Ir ao conteúdo
  • Cadastre-se

Contador de RPM utilizando o PIC18F4520


Posts recomendados

Olá pessoal, boa tarde!

 

Sou iniciante com linguagem C para microcontroladores, por isso preciso da ajuda de vocês.

 

Meu projeto consiste num contador de RPM de um cooler de computador e para isso pretendo usar o PIC18F4520, pois depois tratarei os dados recebidos e preciso de muita memória, o que inviabiliza o uso do 16F877A.

 

Vou utilizar sensores ópticos, os leds infravermelhos til32  e til78 para fazer a contagem de rotações.

O programa que vou utilizar é o CCS.

 

Sei que devo utilizar interrupções nos módulos CCP1 e CCP2, mas como sou leiga no assunto não consegui elaborar o programa, nem entender direito como funciona as interrupções no PIC.

 

 

 

Uma indicação de apostila sobre o assunto e dicas para meu programa seria muito bem vindas.

 

Desde já agradeço a atenção!

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Míga , ccs não vou poder te ajudar.

 

Mas essência é simples. você deve liberar um pino do mc para que atue na entrada do contador (timer) e de tempos em tempos, usando outro timer, (teoricamente a cada minuto) fazer a leitura dos valores que seria direto em rpm. Claro a cada minuto não vai rolar né, então pode ser p.ex. a cada milésimo de minuto (60mS) leia o valor e multiplique por mil. Ah sim, não esqueça de zerar o timer assim que medir pra começar a contar pra próxima captura, capturou?

 

til78 e 32 até que pode dar. O que tem que ver é se eles respondem bem a altas rotações. Mas isso é pra outra hora

 

bjs

Link para o comentário
Compartilhar em outros sites

Olá pessoal, boa tarde!

 

Sou iniciante com linguagem C para microcontroladores, por isso preciso da ajuda de vocês.

 

Meu projeto consiste num contador de RPM de um cooler de computador e para isso pretendo usar o PIC18F4520, pois depois tratarei os dados recebidos e preciso de muita memória, o que inviabiliza o uso do 16F877A.

 

Vou utilizar sensores ópticos, os leds infravermelhos til32  e til78 para fazer a contagem de rotações.

O programa que vou utilizar é o CCS.

 

Sei que devo utilizar interrupções nos módulos CCP1 e CCP2, mas como sou leiga no assunto não consegui elaborar o programa, nem entender direito como funciona as interrupções no PIC.

 

 

 

Uma indicação de apostila sobre o assunto e dicas para meu programa seria muito bem vindas.

 

Desde já agradeço a atenção!

Ola amigo, eu desenvolvi um projeto que contava rotações, porém, eu trabalhei com timer0 como contador de pulsos externo e timer1 como contador interno , entretanto o código foi realizado pelo compilador XC8.

veja como ficou o código base:

 

pic_init();                                                //START PIC

        PORTCbits.RC1 = 0;

        lcd_init();                     //START LCD

        cont();                                                        //START CONT

        TRISC = 0x00;

    OpenTimer2(TIMER_INT_OFF & T2_PS_1_16);             //TIMER2 DESABILITADO E PRESCALER PARA 16

    SetOutputPWM1(SINGLE_OUT, PWM_MODE_1);                   //output PWM in respective modes

    OpenPWM1(255);

        SetDCPWM1(0);

        lcd_cmd(0x80);                                         // Posiciona LCD na primeira linha

    lcd_data('L');                                         // Escreve

    lcd_data('U');

    lcd_data('C');

    lcd_data('A');

    lcd_data('S');

        lcd_data(' ');                                         // Escreve

    lcd_data('L');

    lcd_data('U');

    lcd_data('A');

    lcd_data('N');

    Delay10KTCYx(250);

       

        while(1)

        {

                SetDCPWM1(550);                        // Duty cicle +- 54%

        lcd_cmd(0x80);                         // Posiciona LCD na primeira linha

        lcd_data('R');                         // Escreve

        lcd_data('P');

        lcd_data('M');

        lcd_data(' ');

        lcd_data('C');

        lcd_data('A');

        lcd_data('N');

              

        //obs: amostragem em 0.5 segundos

        TMR0L = 0;                                                //TMR0 PARTE BAIXA

        TMR0H = 0;                                                //TMR0 PARTE ALTA

        TMR1L = 0x24;                                        //TMR1 PARTE BAIXA

        TMR1H = 0x1E;                                        //TMR1 PARTE ALTA

        PIR1bits.TMR1IF = 0;                        //FLAG DE INTERRUPÇÃO

        //start

        T0CONbits.TMR0ON = 1;                          //habilita CONTAGEM DO TIMER0

        T1CONbits.TMR1ON = 1;                                    // habilita TEMPO DO TIMER1

        while(!PIR1bits.TMR1IF);                          //ESPERA 0.5s Para interrupção

        T1CONbits.TMR1ON = 0;                        //DESABILITA TIMER1

        T0CONbits.TMR0ON = 0;                        //DESABILITA TIMER0

       

        rpm = TMR0L;                                         //AMOSTRAGEM DO TIMER0

        rpm = rpm*2;                                        //MULTIPLICADO POR 2 PORQUE É NECESSÁRIO 1 SEGUNDO DE AMOSTRA

        rpm = rpm*60;                                        //TRANSFORMAÇÃO PARA SEGUNDO

        rpm = rpm /9;                                        //UM CICLO EQUIVALE A 9 ou 7 PARTES       

        lcd_cmd(0b00000001);                         // Limpa o display       

        lcd_cmd(0xc0);                          // Posiciona LCD na segunda linha

        lcd_number(rpm);      

        Delay1KTCYx(1);

        }

 

Obs: esse projeto era para contar a rotação de um cooler com 9 hélices ou 7 hélices, sendo assim, para gerar o sinal para o uC eu usei um diodo LED e um foto transistor, quando a hélice passava na frente do led mandava um sinal para o foto transistor e gerava um pulso, a partir desse principio eu mandava os pulsos para o pino do TMR0 para contar.

Link para o comentário
Compartilhar em outros sites

Olá pessoal, boa tarde!

 

Sou iniciante com linguagem C para microcontroladores, por isso preciso da ajuda de vocês.

 

Meu projeto consiste num contador de RPM de um cooler de computador e para isso pretendo usar o PIC18F4520, pois depois tratarei os dados recebidos e preciso de muita memória, o que inviabiliza o uso do 16F877A.

 

Vou utilizar sensores ópticos, os leds infravermelhos til32  e til78 para fazer a contagem de rotações.

O programa que vou utilizar é o CCS.

 

Sei que devo utilizar interrupções nos módulos CCP1 e CCP2, mas como sou leiga no assunto não consegui elaborar o programa, nem entender direito como funciona as interrupções no PIC.

 

 

 

Uma indicação de apostila sobre o assunto e dicas para meu programa seria muito bem vindas.

 

Desde já agradeço a atenção!

 

ola, bom dia.

não trabalho com CCS, mas posso te dar uma ideia como funciona as interrupções.

o pic tem varias formas de ser interrompido (ele para o que estiver fazendo atende a interrupção e volta onde tinha parado), sao algumas:

interrupção externa;

interrupção Timer0, Timer1...;

interrupção da entrada serial;

interrupção da USB;

interrupção do Watch Dog Timer;

 tem outras....

 

Mas o funcionamento é o seguinte: sempre que uma dessas interrupções acontece, uma flag é setada (flag é o bit interno do registrador da interrupção que você esta trabalhando), então você tem que fazer uma sub rotina para este evento:

 

void interrupt() {

if (INTCON.INTF) {            //esta é a flag de interrupção externa

                                          //aqui você coloca o que quer que o mic faca

INTCON.INTF=0;              //zera a flag, ele volta onde estava

}

}                                       //OBS: este pedaço de código é pra mikroc pro

 

a maioria das outras interrupções você trata de forma semelhante.

se você for usar mais que 1 interrupção você tem que configurar a prioridade delas também.

sempre olhe o datasheet do mic e procure os registradores para trabalhar com eles.

 

Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/39631E.pdf

 

este livro é muito bom: http://www.editoraerica.com.br/detalhes.asp?cod=2441

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Míga , ccs não vou poder te ajudar.

 

Mas essência é simples. você deve liberar um pino do mc para que atue na entrada do contador (timer) e de tempos em tempos, usando outro timer, (teoricamente a cada minuto) fazer a leitura dos valores que seria direto em rpm. Claro a cada minuto não vai rolar né, então pode ser p.ex. a cada milésimo de minuto (60mS) leia o valor e multiplique por mil. Ah sim, não esqueça de zerar o timer assim que medir pra começar a contar pra próxima captura, capturou?

 

til78 e 32 até que pode dar. O que tem que ver é se eles respondem bem a altas rotações. Mas isso é pra outra hora

 

bjs

 

O CCS foi sugestão do meu orientador de TCC, aí não tive muita escolha.

Meu código de interrupções até o momento tá assim:

 

 

#int_TIMER0

void  conta_rpm(void)

{

   t0_conta++;

   set_timer0(131);

   

   if (t0_conta>=125)

   {

      velocidade_rpm=3600*pulso/7;

      

      if (pulso==0)

      {

         velocidade_rpm=0;

      }

      pulso=0;

   }

}

#int_EXT

void  EXT_isr(void)

{

   pulso++;

}

 

 

Pulso nesse caso seriam os pulsos do fototransistor.

 

Uma coisa que não entendi: por quê vou ter q usar dois timers? Um só não consegue fazer a contagem?

 

ola, bom dia.

não trabalho com CCS, mas posso te dar uma ideia como funciona as interrupções.

o pic tem varias formas de ser interrompido (ele para o que estiver fazendo atende a interrupção e volta onde tinha parado), sao algumas:

interrupção externa;

interrupção Timer0, Timer1...;

interrupção da entrada serial;

interrupção da USB;

interrupção do Watch Dog Timer;

 tem outras....

 

Mas o funcionamento é o seguinte: sempre que uma dessas interrupções acontece, uma flag é setada (flag é o bit interno do registrador da interrupção que você esta trabalhando), então você tem que fazer uma sub rotina para este evento:

 

void interrupt() {

if (INTCON.INTF) {            //esta é a flag de interrupção externa

                                          //aqui você coloca o que quer que o mic faca

INTCON.INTF=0;              //zera a flag, ele volta onde estava

}

}                                       //OBS: este pedaço de código é pra mikroc pro

 

a maioria das outras interrupções você trata de forma semelhante.

se você for usar mais que 1 interrupção você tem que configurar a prioridade delas também.

sempre olhe o datasheet do mic e procure os registradores para trabalhar com eles.

 

Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/39631E.pdf

 

este livro é muito bom: http://www.editoraerica.com.br/detalhes.asp?cod=2441

 

Valeu a dica!

O datasheet eu já tenho, o livro vou ver se consigo baixar ou em alguma biblioteca porque o preço tá salgado pra uma pobre universitária como eu.

Ola amigo, eu desenvolvi um projeto que contava rotações, porém, eu trabalhei com timer0 como contador de pulsos externo e timer1 como contador interno , entretanto o código foi realizado pelo compilador XC8.

veja como ficou o código base:

 

pic_init();                                                //START PIC

        PORTCbits.RC1 = 0;

        lcd_init();                     //START LCD

        cont();                                                        //START CONT

        TRISC = 0x00;

    OpenTimer2(TIMER_INT_OFF & T2_PS_1_16);             //TIMER2 DESABILITADO E PRESCALER PARA 16

    SetOutputPWM1(SINGLE_OUT, PWM_MODE_1);                   //output PWM in respective modes

    OpenPWM1(255);

        SetDCPWM1(0);

        lcd_cmd(0x80);                                         // Posiciona LCD na primeira linha

    lcd_data('L');                                         // Escreve

    lcd_data('U');

    lcd_data('C');

    lcd_data('A');

    lcd_data('S');

        lcd_data(' ');                                         // Escreve

    lcd_data('L');

    lcd_data('U');

    lcd_data('A');

    lcd_data('N');

    Delay10KTCYx(250);

       

        while(1)

        {

                SetDCPWM1(550);                        // Duty cicle +- 54%

        lcd_cmd(0x80);                         // Posiciona LCD na primeira linha

        lcd_data('R');                         // Escreve

        lcd_data('P');

        lcd_data('M');

        lcd_data(' ');

        lcd_data('C');

        lcd_data('A');

        lcd_data('N');

              

        //obs: amostragem em 0.5 segundos

        TMR0L = 0;                                                //TMR0 PARTE BAIXA

        TMR0H = 0;                                                //TMR0 PARTE ALTA

        TMR1L = 0x24;                                        //TMR1 PARTE BAIXA

        TMR1H = 0x1E;                                        //TMR1 PARTE ALTA

        PIR1bits.TMR1IF = 0;                        //FLAG DE INTERRUPÇÃO

        //start

        T0CONbits.TMR0ON = 1;                          //habilita CONTAGEM DO TIMER0

        T1CONbits.TMR1ON = 1;                                    // habilita TEMPO DO TIMER1

        while(!PIR1bits.TMR1IF);                          //ESPERA 0.5s Para interrupção

        T1CONbits.TMR1ON = 0;                        //DESABILITA TIMER1

        T0CONbits.TMR0ON = 0;                        //DESABILITA TIMER0

       

        rpm = TMR0L;                                         //AMOSTRAGEM DO TIMER0

        rpm = rpm*2;                                        //MULTIPLICADO POR 2 PORQUE É NECESSÁRIO 1 SEGUNDO DE AMOSTRA

        rpm = rpm*60;                                        //TRANSFORMAÇÃO PARA SEGUNDO

        rpm = rpm /9;                                        //UM CICLO EQUIVALE A 9 ou 7 PARTES       

        lcd_cmd(0b00000001);                         // Limpa o display       

        lcd_cmd(0xc0);                          // Posiciona LCD na segunda linha

        lcd_number(rpm);      

        Delay1KTCYx(1);

        }

 

Obs: esse projeto era para contar a rotação de um cooler com 9 hélices ou 7 hélices, sendo assim, para gerar o sinal para o uC eu usei um diodo LED e um foto transistor, quando a hélice passava na frente do led mandava um sinal para o foto transistor e gerava um pulso, a partir desse principio eu mandava os pulsos para o pino do TMR0 para contar.

 

Obrigada Lucas, é exatamente como a parte inicial do meu projeto!

 

Só alguma dúvidas: o cristal q vou usar é de 8MHz, qual prescaler devo usar?

Qual PIC você usou?

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Dependendo de qual valor de rpm vai medir, não é necessário pulso++. O circuito interno do pic já faz isso pra você. Mas pra isso, como sempre digo, você vai ter que dar uma olhadela no datashiit do seu mc

PIC16F688_Timer0.png

Note que ao fazer T0SE=1, e entrada vai ser o pino. Aplique nele o sinal advindo do teu opto.

 

Agora sim, uma interrupção pelo timer1...

Timer-1-Block-Diagram.jpg

com intervalo de tempo conhecido, deve capturar o valor de TMR0, colocar numa variável global e zerar TMR0. Percebeste a necessidade de 2 timers? Fazendo assim, o valor rpm vai ser meio que automático e sempre estará na ram (variável)

 

 

Bom .. foi só uma ideota...

 

abç

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

O CCS foi sugestão do meu orientador de TCC, aí não tive muita escolha.

Meu código de interrupções até o momento tá assim:

 

 

#int_TIMER0

void  conta_rpm(void)

{

   t0_conta++;

   set_timer0(131);

   

   if (t0_conta>=125)

   {

      velocidade_rpm=3600*pulso/7;

      

      if (pulso==0)

      {

         velocidade_rpm=0;

      }

      pulso=0;

   }

}

#int_EXT

void  EXT_isr(void)

{

   pulso++;

}

 

 

Pulso nesse caso seriam os pulsos do fototransistor.

 

Uma coisa que não entendi: por quê vou ter q usar dois timers? Um só não consegue fazer a contagem?

 

Valeu a dica!

O datasheet eu já tenho, o livro vou ver se consigo baixar ou em alguma biblioteca porque o preço tá salgado pra uma pobre universitária como eu.

 

Obrigada Lucas, é exatamente como a parte inicial do meu projeto!

 

Só alguma dúvidas: o cristal q vou usar é de 8MHz, qual prescaler devo usar?

Qual PIC você usou?

O prescaler vai depender do seu projeto, no caso do meu projeto eu usei prescaler 8 e para esse projetinho eu usei o PIC18F4520 e um crystal  de 4MHz

 

O pulso é do foto transistor, eu usei dois timers porque um timer 0 conta o pulso de fototransistor e o timer 1 serve para dar um delay 0.5, ou seja, quando eu disparo o timer 0 e o timer 1 eu espero a contagem, sendo assim, depois de 0.5 segundos desligo o timer 0 e 1 e ai eu pego a carga do timer 0 multiplico por 2 para dar uma amostra de 1s, entre tanto, pego o valor do timer 0 multiplico por 60 para virar RPM e divido pelo numero de hélices do cooler.

 

Fica ai uma dica para fazer os calculos para seu timer:

 

Tempo_requerido = (4)*[(1)/(FOSC)]*Prescaler*(8bits_our_16bits - Carga_do_timer)

 

É so você isolar a carga do timer e depois carregar TMRL e TMRH.

 

Obs: Esse é um metodo que usei, mas existe outro  que é o modo  CCP, porém se o seu projeto esta muito em cima faça do jeito que você começou mesmo.

 

Obs: Eu poderia usar uma rotininha de delay comum no lugar do TIMER1 também, porém, eu queria contar pelo timer 1 o tempo para o professor dar uma boa nota e isso foi necessário para eu aprender, muitas das vezes facilitar um projeto demais pode atrapalhar no aprendizado.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Um timer conta os pulsos gerados pelo opto acoplador. ... Mas vai começar quando e terminar de contar quando?

Aí é que entra o segundo timer. Se você deixar os pulsos gerados no opto acoplador passar para o primeiro timer, durante um período, aí você deixa de ter apenas um contador (número de pulsos) e passa a ter uma taxa (número de pulsos por período), que é o que você precisa.

Você TEM que ajustar este período para que não crie incompatibilidade com o segundo timer, que determinará o instante de começar a deixar entrar os pulsos e o instante de bloquear os pulsos.

Como incompatibilidade podemos observar para que a capacidade de contagem do segundo timer não seja ultrapassada.

Você DEVE escolher este período de modo a que não conte poucos pulsos. Aí não terá precisão. Também DEVE impedir que o timer transborde, perdendo informação.

Mesmo que o seu período não seja minuto (caso de rpm), ou segundo (caso de rps). Depois você tem que multiplicar (ou dividir) o valor do número de pulsos capturados pelo primeiro contador (pulsos óticos) para que o seu período seja de um segundo (rps), um minuto (rpm) ou por hora (rph). Você tem que avaliar os limites da taxa de pulsos para que os contadores não caiam nos casos reportados de incompatibilidade.

 

Estude o funcionamento dos timers 0 e 1. Tem montes de tutoriais na net.

Você não vai poder se livrar desta tarefa, a menos que copie algum código, mas aí você terá trabalhado e não aprendido, o que não é um procedimento muito inteligente.

Já que terá que investir um tempo no projeto, pelo menos aprenda para poder usar os conhecimentos adquiridos mais adiante.

 

Investir em conhecimento sempre produz bons resultados.

 

MOR_AL

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Não quero me intrometer, mas também pode ser feito com apenas um timer ( como CONTADOR ), usando uma interrupção em um pino por borda de subida (ou de descida) na entrada. O contador era alimentado pelo clock interno. O tipo de borda pode ser escolhido OU na subida OU na descida.

 

Ví um cara fazer da seguinte maneira, bem engenhosa :

 

Quando ocorria uma borda de subida ( ou de descida ) na entrada, ocorria uma interrupção, e o cara pegava a contagem atual do timer, que fazia a contagem de ciclos de clock dividido pelo prescaler. No caso, para maior precisão, era usado um timer de 16 bits.

 

Na próxima interrupção, ele pegava novamente a contagem, fazia a conta de quantos contagens haviam passado desde a interrupção anterior, e acumulava em um somador e incrementava um contador de subidas na entrada... reparem que ele conseguiu desta maneira o tempo entre duas subidas do sinal, que é a base para calcular a frequência.

 

O contador gerava uma interrupção no estouro da contagem, então nesse momentos era calculada a frequência através da soma no somador e o numero de subidas, e como ele sabia qual a velocidade do contador, ele calculava o tempo médio do sinal, e assim achava a frequência. E nesse momento zerava tanto o somador como o contador de subidas, e inicializava o contador do zero... e fazia tudo de novo .....

 

Era um circuito publicado na antiga Circuit Cellar Magazine, lá pelos idos de 2000 .....

 

Paulo

Link para o comentário
Compartilhar em outros sites

A postagem do Paulo me trouxe à lembrança um projetinho meu.

 

Peço que desculpem e espero que compreendam a colocação da seguinte historinha, mas é que este tópico me trouxe gratas lembranças e que foi o trabalho de muitos meses.

 

Tive o sac,,, ehr a paciência de fazer um frequencímetro, programado em assembler, com apenas um contador usando o TIMER0.

 

O TIMER0 contava os pulsos da frequência na entrada do pino correspondente.

 

Usei o prescaler (div 256).

 

Como período de 1s, eu criei um loop. Ele durava exatamente um segundo.

Como minha frequência máxima poderia ir até 40 ou 50MHz, tive que incluir mais dois registros para conter toda esta contagem.

A cada transbordo do TIMER0 eu incrementava o registro que representava os 8 bits seguintes e verificava se este registro transbordava. Caso afirmativo, eu incrementava o segundo contador. Com isso eu podia contar até o equivalente a um contador com 4 bytes (prescaler TMR0, Reg1 e Reg2). Contagem até 2 elevado a 32 bits = 4.3 bilhões. Com apenas três bytes a máxima contagem seria de 16.8 milhões, menos que o necessário,

O interessante é que qualquer que fosse o caminho por onde o programa seguisse, o número de ciclos era constante. Independentemente se tinha que atualizar ou não o primeiro ou segundo registro extra.

O programa ficava em loop até completar exatas 5.000.000 contagem de clock, que para um cristal de 20MHz, correspondia a um período de 1,000 000 segundo, com as seis casas decimais em zero.

Então o número que constasse nesses 5 registros corresponderia a frequência de entrada.

 

Em tempo. Como sabemos o valor do prescaler do TIMER0 não pode ser lido diretamente. Então, para conhecer o valor do prescaler, tive que incluir falsos pulsos, até que o registro do TIMER0 (TMR0) fosse alterado. Com isso eu conheceria o valor que restava no precaler.

 

Não acreditando que pudesse dar certo, gerei pulsos de clock na entrada do TIMER0, na esperança de ver no LCD o valor de 5.000.000 de pulsos, que mostraria que o período de contagem seria de 1,000000 segundo.

Estou contando isso porque é de uma imensa satisfação verificar quando um trabalho funciona. O erro de contagem era de 200ns (que é o período do clock) em um segundo.

Aí me deu um estalo. De que adianta garantir que a contagem tenha esta precisão, se a frequência do cristal poderia não ter tal precisão?

Incluí um trimmer capacitivo em paralelo com um dos capacitores do cristal. Caso eu tivesse acesso a um frequencímetro com mais precisão, eu poderia calibrar o meu para a mesma precisão.

 

... Já dizia o meu professor do cursinho pré-vestibular, quando mostrava algo que os alunos deveriam saber. "Recordar é viver outra vez", e eu complementava ..."desde que não se tenha Alzheimer". Hehehe!! :)

 

MOR_AL

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

O prescaler vai depender do seu projeto, no caso do meu projeto eu usei prescaler 8 e para esse projetinho eu usei o PIC18F4520 e um crystal  de 4MHz

 

O pulso é do foto transistor, eu usei dois timers porque um timer 0 conta o pulso de fototransistor e o timer 1 serve para dar um delay 0.5, ou seja, quando eu disparo o timer 0 e o timer 1 eu espero a contagem, sendo assim, depois de 0.5 segundos desligo o timer 0 e 1 e ai eu pego a carga do timer 0 multiplico por 2 para dar uma amostra de 1s, entre tanto, pego o valor do timer 0 multiplico por 60 para virar RPM e divido pelo numero de hélices do cooler.

 

Fica ai uma dica para fazer os calculos para seu timer:

 

Tempo_requerido = (4)*[(1)/(FOSC)]*Prescaler*(8bits_our_16bits - Carga_do_timer)

 

É so você isolar a carga do timer e depois carregar TMRL e TMRH.

 

Obs: Esse é um metodo que usei, mas existe outro  que é o modo  CCP, porém se o seu projeto esta muito em cima faça do jeito que você começou mesmo.

 

Obs: Eu poderia usar uma rotininha de delay comum no lugar do TIMER1 também, porém, eu queria contar pelo timer 1 o tempo para o professor dar uma boa nota e isso foi necessário para eu aprender, muitas das vezes facilitar um projeto demais pode atrapalhar no aprendizado.

 

 

Dependendo de qual valor de rpm vai medir, não é necessário pulso++. O circuito interno do pic já faz isso pra você. Mas pra isso, como sempre digo, você vai ter que dar uma olhadela no datashiit do seu mc

PIC16F688_Timer0.png

Note que ao fazer T0SE=1, e entrada vai ser o pino. Aplique nele o sinal advindo do teu opto.

 

Agora sim, uma interrupção pelo timer1...

Timer-1-Block-Diagram.jpg

com intervalo de tempo conhecido, deve capturar o valor de TMR0, colocar numa variável global e zerar TMR0. Percebeste a necessidade de 2 timers? Fazendo assim, o valor rpm vai ser meio que automático e sempre estará na ram (variável)

 

 

Bom .. foi só uma ideota...

 

abç

 

Pessoal, muito obrigada pelas dicas!

 

Ainda não vou marcar como resolvido, mas quando conseguir terminar meu projeito eu marco.

 

Muitíssimo obrigada!

Link para o comentário
Compartilhar em outros sites

@MOR,

Hehehe é sempre bom lembrar das maneiras que resolvemos os problemas !!!

Uma vez eu tive de contar os ciclos de clock que um programa de controle industrial demorava para fazer todo o processamento.... Usava Z80-A rodando a 4 Mhz, e tinha de fazer um registrador de eventos, onde tinha de tratar 256 entradas digitais, com tempo de varredura de 8 milisegundos... O engenheiro responsável, depois de 4 meses fazendo tudo, e tendo consumido todo o valor de customestimado por ele meamo, e sem conseguir concluir, simplesmente pediu as contas e saiu, e me deslocaram de um projeto para terminar esse... Em 5 dias eu percebí que era impossível conseguir a resolução, e como eu era novo na empresa, tomei um esculacho do diretor.... Bom, prá resumir, o presidente da empresa, que era um espanhol, trouxe dois engenheiros espanhóis lá da matriz, porque ele dizia que "um engenheiro espanhol vale mais que 5 engenheiros brasileiros.... " e depois de uma semana a conclusão foi a mesma. Para atender o cliente, trouxeram da matriz espanhola uma nova família , que usava o 8088 a 8 Mhz, e aí conseguiram entregar o projeto com 3 meses de atraso. Me lembro que custou 80% a mais do que o que foi cobrado do cliente, considerando os custos dos "super-engenheiros espanhóis" kkkk

Imagine eu ter de calcular o pior caso de demora em um programa em Assembler, feito por outra pessoa, com pouquíssimos comentários no programa-fonte, com 15k de tamanho do objeto, e que podia mudar muito o tempo de processamento conforme as mudanças nas entradas..... E em um processador que podia demorar de 1 até 6 ciclos de clock ( se não me engano.... ) conforme o resultado de algumas instruções... Foi a pior semana que eu passei até hoje...

Paulo

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Não quero me intrometer, mas também pode ser feito com apenas um timer ( como CONTADOR ), usando uma interrupção em um pino por borda de subida (ou de descida) na entrada. O contador era alimentado pelo clock interno. O tipo de borda pode ser escolhido OU na subida OU na descida.

 

Ví um cara fazer da seguinte maneira, bem engenhosa :

 

Quando ocorria uma borda de subida ( ou de descida ) na entrada, ocorria uma interrupção, e o cara pegava a contagem atual do timer, que fazia a contagem de ciclos de clock dividido pelo prescaler. No caso, para maior precisão, era usado um timer de 16 bits.

 

Na próxima interrupção, ele pegava novamente a contagem, fazia a conta de quantos contagens haviam passado desde a interrupção anterior, e acumulava em um somador e incrementava um contador de subidas na entrada... reparem que ele conseguiu desta maneira o tempo entre duas subidas do sinal, que é a base para calcular a frequência.

 

O contador gerava uma interrupção no estouro da contagem, então nesse momentos era calculada a frequência através da soma no somador e o numero de subidas, e como ele sabia qual a velocidade do contador, ele calculava o tempo médio do sinal, e assim achava a frequência. E nesse momento zerava tanto o somador como o contador de subidas, e inicializava o contador do zero... e fazia tudo de novo .....

 

Era um circuito publicado na antiga Circuit Cellar Magazine, lá pelos idos de 2000 .....

 

Paulo

 

 

Um timer conta os pulsos gerados pelo opto acoplador. ... Mas vai começar quando e terminar de contar quando?

Aí é que entra o segundo timer. Se você deixar os pulsos gerados no opto acoplador passar para o primeiro timer, durante um período, aí você deixa de ter apenas um contador (número de pulsos) e passa a ter uma taxa (número de pulsos por período), que é o que você precisa.

Você TEM que ajustar este período para que não crie incompatibilidade com o segundo timer, que determinará o instante de começar a deixar entrar os pulsos e o instante de bloquear os pulsos.

Como incompatibilidade podemos observar para que a capacidade de contagem do segundo timer não seja ultrapassada.

Você DEVE escolher este período de modo a que não conte poucos pulsos. Aí não terá precisão. Também DEVE impedir que o timer transborde, perdendo informação.

Mesmo que o seu período não seja minuto (caso de rpm), ou segundo (caso de rps). Depois você tem que multiplicar (ou dividir) o valor do número de pulsos capturados pelo primeiro contador (pulsos óticos) para que o seu período seja de um segundo (rps), um minuto (rpm) ou por hora (rph). Você tem que avaliar os limites da taxa de pulsos para que os contadores não caiam nos casos reportados de incompatibilidade.

 

Estude o funcionamento dos timers 0 e 1. Tem montes de tutoriais na net.

Você não vai poder se livrar desta tarefa, a menos que copie algum código, mas aí você terá trabalhado e não aprendido, o que não é um procedimento muito inteligente.

Já que terá que investir um tempo no projeto, pelo menos aprenda para poder usar os conhecimentos adquiridos mais adiante.

 

Investir em conhecimento sempre produz bons resultados.

 

MOR_AL

 

Muito obrigada pelas dicas!

 

Tô estudando as interrupções do TIMER0 e do TIMER1, aos poucos vou pegando as coisas.

Já procurei códigos prontos também, mas como o colega disse é melhor aprender do q apenas trabalhar.

Em breve espero poder marcar esse tópico como concluído.

Link para o comentário
Compartilhar em outros sites

@Janaína Ribeiro,

 

A maneira mais simples realmente é utilizando os dois Timers, como o Mor citou, e é o que eu chamos de maneira clássica.

 

Procure por códigos para frequencímetro simples com Pic, o pricípio é o mesmo, e acho que são mais simples de se encontrar.

 

Boa sorte !

 

Paulo

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades 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

×
×
  • Criar novo...