Ir ao conteúdo
  • Cadastre-se
waymovie

Dúvida Contador Tempo com Variável

Recommended Posts

Buenas! 

Galera, estou utilizando o CCS no 16Ff628A, tentando efetuar a seguinte situação: quando pressiono um botão, um motor é ligado e uma variável deve ser incrementada (estou utilizando o timer0) para contar o tempo de execução do motor, até que o mesmo botão seja pressionado novamente. Nesse momento a variável está com o valor do tempo armazenado (depois irei tentar guardar esse tempo na eeprom, mas não cheguei lá ainda.... essa será minha próxima pergunta...rsrs). Então, cada vez que um segundo botão for pressionado, o motor deve ligar e ser desligado no tempo armazenado na variável... segue o código que estou tentando, sem sucesso... fiz um pequeno circuitinho no proteus pra testar, mas não ta rolando....Aguardo os especialistas... Abraço.

 

Segue o código... (não riam):

 

int conta=0;  //variavel de incremento de contagem de tempo de abertura
int contador=0;  //0 = motor parado e 1 = motor contando tempo
int abre=0; //variável para decremento de tempo para fechamento/abertura do portão
 
#int_RTCC
void  RTCC_isr(void) 
{
conta++; //incrementa essa variável a cada estouro do timer
}
void main()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_ccp1(CCP_OFF);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   disable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
//Setup_Oscillator parameter not selected from Intr Oscillator Config tab
while(true)
{
   if(!input(grava)) //se apertar o botão de gravar tempo de percurso
      if(contador==0) //se o motor estiver parado
      {
      enable_interrupts(INT_RTCC); //habilita a interrupção
      output_high(led); //liga o motor
      contador=1; //altera o status do motor para "em funcionamento".
      delay_ms(300);
      }
      else if(contador==1) //se o motor tiver em movimento
      {
      disable_interrupts(INT_RTCC); //desabilita a interrupção
      output_low(led); //desliga o motor
      contador=0; //altera status do motor para "parado"
      abre=conta; //transfere o valor da variável "conta" para a variável "abre"
      delay_ms(300);
      }
   if(!input(botao)) //se o controle for pressionado
   {
      if(conta>0) //se a variável "conta" for maior que zero
      {
      output_high(led); //liga o motor
      abre--; //decrementa o tempo gravado na variável "abre"
      delay_ms(100);
         if(abre==0)  //quando a variável "abre" atingir valor = a zero
         {
         output_low(led); //desliga o motor
         abre=conta; //retorna o valor da variável "abre", que deverá ser gravada na eeprom interna, para a variável "abre"
         }
      }
   }
}
 
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vou dar um exemplo: Você pode usar duas ou três variáveis, crie um tempo curto para a interrupção, por exemplo de 10ms no timer0, esta será a resolução do contador, defina como julgar melhor, esta é minha recomendação.

 

Main

*Para o botão principal: Quando pressiona marque uma flag para contagem progressiva, você zera as variáveis e ativa o timer, loop infinito até soltar o botão e aplicar um debounce ao término. 

*Para acionar o motor: Quando pressiona marque a flag para contagem regressiva, ligue o motor, então ativa o timer, aplica um debounce.

 

Interrupção:

*O timer deve gerar uma interrupção a cada 10ms quando ativado.

*Então a cada int. você checa se a contagem é progressiva ou regressiva, dai da um destino para incremento ou decremento.

*Em ambos os casos: terá por exemplo 3 variáveis char, digamos que sejam chamadas de "mS", "S" e "M".

*Por exemplo no modo progressivo (incremento): a cada 100 incrementos em "mS" incremente "S", a cada 60 incrementos em "S" incremente "M", suponhamos que mS=80, S=2, M=0, teremos 800ms + 2segundos + 0minutos = 2,8 Segundos. O mesmo acontece no modo regressivo (de trás para frente), a questão é que quando contadores forem decrementados e iguais a zero, você desliga o motor e o timer.

 

Eeprom:

Se quer salvar os dados na eeprom, salve as chars em sequencia após soltar o botão principal por exemplo, antes do debounce.

Para ler, leia os valores e jogue nas variaveis mS, S, M, antes de ligar o motor e o timer.

 

Como são as funções da eeprom?

 

Para ler:

var_recebe_valor=read_eeprom(endereço);

Ps: Endereço é um número, ou seja, o byte da eeprom que contém o dado.

Ex: Se o pic tem 64bytes de eeprom disponíveis, você pode escolher um número de 0 a 63.

 

Para escrever:

write_eeprom(endereço,variavel);

Ps: Endereço é o mesmo caso anterior, variavel é o registrador que contém o dado a ser gravado.

Ex: write_eeprom(3,mS) // isto fará com que o valor da variável chamada "mS" seja gravado no quarto byte da eeprom.

 

Abraço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Como nosso amigo daniel disse... e complemento:  existem varias formas de fazer isso.. amanha posto alguma coisa de exemplo p ti... ok? abraço

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cesarlg...to no aguardo...obrigado por enquanto.... vou dar uma analisada no que disse o Daniel....Abç

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom, amigo ! desculpe a demora..
Como disse , existe varias formas de fazer a mesmo coisa... preferi seguir a minha linha de raciocinio (talves nao a mais simples).. 
sempre usei o timer1, mas como você fez com o timer0 segui, mas nao usei o oscilador interno, nomeacoes e tal.. veja o codigo....

#include <16f628A.h>    // mcu escolhido#use delay(clock=4000000) //clock#fuses INTRC_IO, NOWDT, PUT, NOBROWNOUT, NOMCLR, NOPROTECT, NOLVP // fusiveis#include <lcd.c>           // biblioteca para utilizar o lcd#define GRAVA pin_a0        // botao p gravar o tempo#define EXECUTA pin_a3      // botao p rodar o programado#define LED pin_a7          // saidasigned int16 x;              // variavel positiva usada p determinar segundosint seg;                      // variavel segundoint tempo_gravado;            // variavel direcionado a gravacao da eepromint passos = 0;              //  variavel q comanda a makina de estados#INT_TIMER0                   void trata_timer0(){ x -= 256;     if (x <= 0)              // metodo utilizado p acertar o tempo de 1 segundo      {        x += 15625;       seg++;                 // cada estouro incremeta 1 seg.      }      }void testa_botoes()                  // janela q testa os botoes qd é chamada{if(input(GRAVA) )      {      passos ++;      }          //   qd aperta botao grava manda ir p proximo bloco   do{}   while(input(grava));                                    // garante q so executa depois q soltar o botao if(input(EXECUTA) )    {      passos = 4;       }        //   qd aperta botao executa manda p bloco 4   do{}   while(input(EXECUTA));                                  // "deboucing"}void main(){   lcd_init();                                     // inicia o modo lcd   setup_timer_0 ( RTCC_INTERNAL | RTCC_DIV_64 ); // seta o timer0   enable_interrupts(global);                    // liga as interupcoes globais   enable_interrupts ( int_timer0);             // liga o timer0while(TRUE){      switch(passos)                             // janela p trabalho{                               // cada bloco executa uma funcao e espera ser man                              //dado para outro bloco pela chamada "passos"   case 1:                                    // bloco 1      {          enable_interrupts ( int_timer0);   // liga timer         output_high(led);                //liga led         printf(lcd_putc,"\fGRAVANDO:     %02u  \nSTOP ?     PIN_A0",seg );          delay_ms(100);                 // mostra tela         testa_botoes();               // manda la p ler os botoes         break;                       // espera ,       }   case 2:                          // bloco 2      {         output_low(led);                                         //desliga led         disable_interrupts ( int_timer0);                      // para o timer0         tempo_gravado=seg;                                     //  torna o valor de tempogravado = seg         write_eeprom (1, tempo_gravado);                        // grava na eeprom                            printf(lcd_putc,"\f  GUARDANDO . \n VALOR NA EEPROM ");         delay_ms(500);         printf(lcd_putc,"\f  GUARDANDO .. \n VALOR NA EEPROM "); // mensagem         delay_ms(500);         printf(lcd_putc,"\f  GUARDANDO ...\n VALOR NA EEPROM ");         delay_ms(500);         passos=3;                                          // manda p bloco 3         break;                                          // espera      }    case 3:                                         // bloco 3      {                  printf(lcd_putc,"\fVALOR DE EEPROM \n       %02u ",tempo_gravado );         delay_ms(2000);                             // tempo          passos=0;                                  // manda p janela default         break;      }   case 4:      {        enable_interrupts ( int_timer0);       // liga timer        seg = 0;                             // mantem o segundo em zero        output_high(led);                  // liga led        passos = 5 ;                     // manda executar bloco 5         break;                       // espera      }case 5:                                 // bloco 5      {       printf(lcd_putc,"\fRODANDO       %02u  \nEEPROM        %02u ",seg , tempo_gravado);       delay_ms(50);       enable_interrupts ( int_timer0);    // permanece o timer ligado      if(seg>=tempo_gravado)             // condicao qd o seg for maior do valor da eeprom       {                                  // se verdadeiro         output_low(led);                 // desliga led         disable_interrupts ( int_timer0); // desliga timer         passos=0;                         // manda p default       }         break;                           // espera      }default :                                    // bloco 0      {           testa_botoes();                     // vai p void onde testa os botoes         seg=0;                             // mantem segundos zerados         tempo_gravado = read_eeprom(1);     // le o valor q esta na eeprom e joga na variavel tempogravado         printf(lcd_putc,"\fGRAVAR ?  PIN_A0  \nRODAR ?   PIN_A3 "); // msg em lcd         delay_ms(50);                        // tempo                                                }      }  }}

em anexo o hardware para funcionamento...

qq duvida estamos ai, espero q ajude o aprendizado!! 

post-396135-0-78433200-1396753809_thumb.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cesar, muito legal mesmo... to dando uma analisada e to entendendo "quase" tudo... pra ti ganhar um 10 (brincadeirinha..ehheh), teria como tu comentar os passos?? só pra entender melhor tua lógica, aprender e começar a implementar... Se não puder, não tem problema, ja me ajudou bastante. Abraço

Compartilhar este post


Link para o post
Compartilhar em outros sites

dei uma comentada no post meu anterior, espero q ajude, apesar de esta bem claro as intrucoes usadas.. estou a disposicao

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

×