Ir ao conteúdo
  • Cadastre-se
Carlos Eduardo Rosa

Como fazer start Stop no meu cronometro

Recommended Posts

Bom dia pessoal, estou começando a programar em c e estou com um problemão, montei um cronometro com varredura e 4 displays de 7 segmentos, que conta centesimos, e esta contando normal, mas o stop funciona as vezes geralmente quando coloco a mão na placa, acredito que seja alguma falha na programação,Será que alguém pode me ajudar  ?? segue a programação logo abaixo. 

 

#include   <16F877A.h>            //microcontrolador utilizado

#use delay (clock = 20000000)      // clock de 4 MHz

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                         Configurações para gravação                   *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#fuses hs,nolvp,wdt,nolvp,nobrownout,put,nodebug,noprotect,nowrt,nocpd

                            // Configurações da Máquina
                                   // Oscilador: XT
                                   // LVP: Off
                                   // WDT: On
                                   // Brown-out: Off
                                   // Power-up: Off
                                   // Debug: Off
                                   // CP: Off
                                   // CPD: Off


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                 Definição e inicialização das variáveis               *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Aqui iremos definir as variáveis globais do sistema

int unidade=0,centena=0,dezena=0,milhar=0,indice=0;
int vezes_tmr1=1;
boolean pisca=0;
boolean bcontagem = 0 ;    // 0 não efetua a contagem 1 efetua a contagem

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                           Constantes internas                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Aqui iremos definir as constantes utilizadas pelo sistema

#define CHR_0     0b00111111
#define CHR_1     0b00000110
#define CHR_2     0b01011011
#define CHR_3     0b01001111
#define CHR_4     0b01100110
#define CHR_5     0b01101101
#define CHR_6     0b01111101
#define CHR_7     0b00000111
#define CHR_8     0b01111111
#define CHR_9     0b01101111


const int converte_to_7seg[]={CHR_0,CHR_1,CHR_2,CHR_3,CHR_4,CHR_5,CHR_6,
                              CHR_7,CHR_8,CHR_9};
                                    //Caracteres para o displayt de 7 segmentos

#define BASE_TEMPO  (100000)   //   Base de tempo para timer

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                                Saídas                               *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Aqui iremos definir as saídas do sistema

#define SEL_UNIDADE   PIN_B4        // Define pino para seleção de display
#define SEL_DEZENA    PIN_B3        // Define pino para seleção de display
#define SEL_CENTENA   PIN_B2        // Define pino para seleção de display
#define SEL_MILHAR    PIN_B1        // Define pino para seleção de display
#define PINO_PISCA    PIN_D7        // Define pino para piscar o ponto
#bit START    =     5.0       // Define pino para começar a contar
#bit STOP     =     5.1        // Define pino para parar o contador


#use fast_io  ( a )      // Porta A defiinida como rapida

#byte portA = 5          // Definição de valor referente a porta A
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                       Prototipagem das funções                      *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Aqui iremos declarar todas as funções definidas pelo usuário

void Inicializa(void);

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                           Rotina Principal                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Nessa parte ficará o loop principal do sistema

void main()
{
  set_tris_A (0b000111);      // portas 0,1 e dois como entra e o restante como saida
 // portA = 0x00 ;
    while (true){

           Inicializa();                    // Chama rotina para inicializar a máquina
           while(1)
      {
       restart_wdt();               // Entra em loop infinito e limpa o wdt
      }
   }

}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                       Inicialização do Sistema                       *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

void Inicializa(void)
{

   setup_wdt(WDT_144MS);            // Configura WDT para 2,304 s

   set_timer0(0);                    // Inicializa timer 0 com 0
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1);
                                    // Timer configurado para clock
                                    // Interno com prescaler de 1:4

   set_timer1(BASE_TEMPO);           // Inicializa timer 1
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
                                    // Timer configurado para clock
                                    // Interno com prescaler de 1:8

   enable_interrupts(INT_TIMER0);   // Habilita interrupção de timer 0
   enable_interrupts(INT_TIMER1);   // Habilita interrupção de timer 1

   enable_interrupts(GLOBAL);       // Habilita todas as interrupções
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                  Tratamento da Interrupção de Timer 1               *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#int_timer1
void Isr_Timer1(void)
{

   set_timer1(15536);        // Recarrega timer 1
    pisca=!pisca;    // Recarrega variável
    vezes_tmr1--;
    if (vezes_tmr1) return;
    vezes_tmr1=1;
// Inicio da funcao que define o Stop, Start e Reset da contagem
    if (!START) {
     bcontagem = 1 ;
  //   ++unidade ;
    }
    else if ( bcontagem & !STOP){
    bcontagem = 0 ;
    }

      if ( bcontagem ){
      ++unidade ;
      }
//fim da funcao
      if (unidade!=10) return;     
   unidade=0;                       // Zera a variável

   dezena++;                        // Incrementa dezena
      if (dezena!=10) return;       
   dezena=0;                        // Zera a variável

   centena++;                       // Incrementa a variável

   if (milhar==10)                 // Verifica se milhar vale 2
    {
      if (centena==10)              
         {
            milhar=0;               // Zera variável
            centena=0;              // Zera variável
            return;                 // Zera variável
         }
    }

      if (centena!=10)return;      // Verifica se variável chegou a 10
   centena=0;                       // Limpa a variável
   milhar++;

}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                  Tratamento da Interrupção de Timer 0               *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#int_timer0
void Isr_Timer0(void)
{

    set_timer0(62000);
   indice++;                        // Incrementa indice

   switch(indice)                   // Seleção de casos com indice
      {

         case 1:                    // Caso seja 1...
            output_low(SEL_UNIDADE);// Retira a seleção do display anterior
            output_d(converte_to_7seg[milhar]);
            output_high(SEL_MILHAR);// Mostra o dado no barramento
            break;                  // Liga display selecionado

         case 2:                     // Caso seja 2...
            output_low(SEL_MILHAR);  // Retira a seleção do display anterior
            output_d(Converte_to_7seg[centena]);
            output_high(SEL_CENTENA);// Mostra o dado no barramento
                                       // Liga display selecionado
          if (pisca) output_high(PINO_PISCA);
            break;

         case 3:                     // Caso seja 3...
            output_low(SEL_CENTENA); // Retira a seleção do display anterior
            output_d(Converte_to_7seg[dezena]);
            output_high(SEL_DEZENA); // Mostra o dado no barramento
            break;                // Liga display selecionado

         case 4:                     // Caso seja 4...
            indice=0;                // Reinicia indice
            output_low(SEL_DEZENA);  // Retira a seleção do display anterior
            output_d(Converte_to_7seg[unidade]);
            output_high(SEL_UNIDADE);// Mostra o dado no barramento
            break;                   // Liga display selecionado
      }
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                        Fim do Programa                          *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 

post-724021-0-98031100-1400582095_thumb.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Amigo qual compilador? Posta o circuito, pois pelo q descreveu sobre tocar na plca pode ser algo relacionado a pull up ou down.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Estarei no celular alguns dias então nao da p analisar direito. O código muda um pouco pois escrevo no ccs. Os botões entram no A0 A1 A2 ? Se sim add botões de pulldown ou pullup se for o caso para forçar a estabilidade e ruidos indesejáveis.

Compartilhar este post


Link para o post
Compartilhar em outros sites

olá amigo . você não é o 1° (e nem será o último) que usa aquele método digamos ... infantil - sem ofensas - pra colocar uma variável no display. De fato já passei por isso no início de carreira. sério.

Isso não vai te ajudar diretamente no entanto permita-me oferecer uma alternativa pra decompor uma variável contagem em milhar, dentena, dezena, unidade o que pode dar mais elegância ao seu código. talvez até mesmo mais segurança

unsigned char milhar,centena, dezena, unidade;//globaisvoid decompoe(unsigned int valor){milhar=valor/1000;centena=(valor-(milhar*1000))/100;dezena=(valor-milhar*1000-centena*100)/10unidade=valor-milhar*1000-centena*100-dezena*10;}

Mas.. pra que isso? neste caso uma variável apenas contagem p.ex. pode ser mais facilmente controlada

unsigned int contagem=1234;//p.ex.decompoe(contagem);//depois disso as variáveis globais estarão compondo a contagem podendo ser colocadas no display

Note que só uso resto. Tem uma maneira ainda mais bacana com resto (%) e mais simples para decompor variáveis de 32bits (que pode ser aplicada pra 16) mas fica pra próxima

No caso da dúvida original, realmente está faltando pullup: um resistor de 10K da entrada pro vcc. Também tem a questão do debounce. Por hora, um capacitor xute 100nF em paralelo com o botão pode ajudar
( ͡° ͜ʖ ͡°)

Sucessos!

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Um palpite!

Esses pinos que ficaram sobrando foram declarados com entradas ou saídas?

Só corri os olhos pelo código, mas se foram declarados como entrada talvez esteja ai seu problema, declare todos esses pinos com saídas, assim o µcontrolador não terá como detectar pulsos parasitas por eles.

 

Agricio

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×