Interrupção do TIMER 1

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Interrupção do TIMER 1

Mensagempor Pask » 08 Fev 2007 15:33

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.
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19

Mensagempor __JEREK__ » 08 Fev 2007 20:45

Pask meu camarada, dá uma olhada nesse tópico, talvez possa lhe ajudar

http://www.asm51.eng.br/phpbb/viewtopic ... er+externo
__JEREK__
Byte
 
Mensagens: 216
Registrado em: 11 Out 2006 17:53
Localização: BA

Mensagempor ric_vas » 09 Fev 2007 06:06

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
ric_vas
Nibble
 
Mensagens: 93
Registrado em: 11 Out 2006 22:22
Localização: RS

Mensagempor Pask » 13 Fev 2007 19:34

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.
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19

Mensagempor __JEREK__ » 13 Fev 2007 20:57

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...

}
__JEREK__
Byte
 
Mensagens: 216
Registrado em: 11 Out 2006 17:53
Localização: BA

Mensagempor Pask » 14 Fev 2007 08:03

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.
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19

Mensagempor vibrex » 14 Fev 2007 13:28

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...
vibrex
Nibble
 
Mensagens: 74
Registrado em: 08 Nov 2006 18:49

Mensagempor Pask » 14 Fev 2007 17:47

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.
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19


Voltar para PIC

Quem está online

Usuários navegando neste fórum: Bing [Bot] e 1 visitante

x