Página 1 de 1
Interrupção do TIMER 1

Enviado:
08 Fev 2007 15:33
por Pask
Amigos, como vcs sabem eu tenho pouca experiência com a linguagem C. Preciso desenvolver uma rotina de tratamento da interrupção do timer 1 (16 bits) para ocorrer de 0,5 em 0,5 segundo e usar uma variável auxiliar chamada DIVISOR. Esta variável é inicializada previamente com o valor 120 e é multiplicada pelo 0,5 segundo do timer 1 para gerar uma base de tempo precisa de 60 segundos. Eu escrevi a rotina assim:
#int_timer1 //tratamento da interrupção
void trata_tmr1(){
set_timer1(16384+get_timer1());
divisor--; //tem mais instruções daqui pra baixo...
...}
Na função main tem o seguinte:
main(){
setup_timer_1(t1_external|t1_div_by_1);
set_timer1(16384); //valor inicial da contagem do timer 1
enable_interrupts(int_timer1); //chave da int. de timer 1 ligada
enable_interrupts(global); //chave geral das interrupções ligada
...}
Eu liguei um cristal de 32,768 kHz nos pinos RB6 e RB7 do PIC 16F628A para acionar o oscilador externo.
A minha função está correta? Se está, por que não funciona? Se não estiver, me dêem uma luz.
Obrigado.
Pask.

Enviado:
08 Fev 2007 20:45
por __JEREK__
Pask meu camarada, dá uma olhada nesse tópico, talvez possa lhe ajudar
http://www.asm51.eng.br/phpbb/viewtopic ... er+externo

Enviado:
09 Fev 2007 06:06
por ric_vas
Me parece que você tem que inserir a constante T1_CLK_OUT:
setup_timer_1(t1_external|t1_div_by_1|
T1_CLK_OUT);
Não tenho certeza
Ric

Enviado:
13 Fev 2007 19:34
por Pask
Meus amigos, em relação à interrupção do timer 1 já resolvi o problema. Agora uma nova pergunta para linguagem C:
Caso eu queira utilizar a interrupção por mudança de estado no pino RB0, como seria a forma correta de configurá-la e como seria uma rotina simples de tratamento desta interrupção para, por exemplo, incrementar ou decrementar uma variável qualquer? Obrigado.
Pask.

Enviado:
13 Fev 2007 20:57
por __JEREK__
primeiro, configura a interrupção externa
- Código: Selecionar todos
enable_interrupts(int_ext); // quando receber um sinal no pino B0...
depois cria uma função que atue quando for chama a interrupção (como no timer)...
- Código: Selecionar todos
#int_ext
void trata_ext ()
{
// faz alguma coisa...
}

Enviado:
14 Fev 2007 08:03
por Pask
Caro Jerek, esses comandos que vc passou eu já escrevi e estão ok. Na verdade, o que eu gostaria, é de criar uma base de tempo de 60 segundos a partir da interrupção no pino RB0. Eu estou aplicando um sinal quadrado em RB0 com freq. de 32,768 kHz e quero que haja o incremento de uma variável a cada 60 segundos, mas ainda não consegui fazê-lo. Veja como eu fiz:
Se em 1 segundo a interrupção ocorre 32768 vezes, em 60 segundos, quantas interrupções ocorrerão?
1 seg. 32.768 int.
--------- = ------------ X = 1.966.080 interrupções.
60 seg. X
Assim, eu criei uma variável inteira de 32 bits chamada ACUMULADOR que vai sendo decrementada a partir do valor X até zero sempre que ocorre uma interrupção em RB0. Quando X chegar a zero, terão se passado exatamente 60 segundos!
O que acontece, é que não está funcionando! Por quê? Será que eu errei os cálculos ou estou entendendo mau a coisa...?
Em relação aos ajustes para a interrupção ocorrer, eles já foram feitos:
enable_interrupts(global); //liga chave geral das interrupções
enable_interrupts(int_ext); //habilita interrupção externa
#int_ext //rotina de tratamento desta interrupção
{
......
}
set_tris_b(1); //configura o pino RB0 como uma entrada
------------------------------------------------------------------------------------
Aguardo sua ajuda e obrigado.
Pask.

Enviado:
14 Fev 2007 13:28
por vibrex
Por que vc nao usa o TMR1 ou o TMR0 pra isso? É bem mais pratico e eles possuem divisores(PRESCALER) justamente pra isso!
Exemplo:
setup_timer_1(t1_internal|t1_div_by_4); // interrupções a cada 10ms @4MHz
#int_timer1
void temporizador(){
set_timer1(63060 - get_timer1()); // interrupções a cada 10ms.
if(!--relogio){ // efetua a leitura do timer0 após 1s
relogio = 100; // recarrega contador de 100 => 1s
if(!divisor){
divisor = 60;
## seu evento ## ou flag que sera tratada na função MAIN
}
}
}
Acho que pode ser assim...
Utilizo essa função para temporizar entre 1 e 1200s.
Experimente simular no MPLAB pra ver se bate...

Enviado:
14 Fev 2007 17:47
por Pask
Caro Vibrex, a interrupção do timer1 já está sendo usado para gerar esta base de tempo. Eu gostaria simplesmente de tentar gerá-la também usando a interrupção externa em RB0 para tentar obter mais precisão.
Está acontecendo uma coisa interessante. Eu estou usando um cristal de quartzo de 32,768kHz para gerar os pulsos e liguei entre um de seus pinos e o GND do circuito um trimmer (capacitor variável) de até 30pF. Dependendo do ajuste que eu faço nesse componente, o relógio começa a atrasar e/ou a adiantar após umas 3 horas de funcionamento! Portanto, eu estava querendo usar outro tipo de interrupção para ver se eu resolvia este problemas, mas já me disseram que deve até piorar. Os timers do PIC ainda são a melhor opção. Em tempo: estou usando este cristal ligado a um CI 4060 e retirando o sinal em seu pino 9 que é o pino onde eu obtenho a exata freq. do cristal. A partir do deste ponto, eu acoplo o sinal ao pino RB6 do PIC que é a entrada de incremento externo para o timer1!
Vc teria alguma idéia para eu melhorar a precisão deste circuito? Obrigado.
Pask.