Página 1 de 1
Utilizar timer/contador para interrupção de +- 1 seg em C

Enviado:
27 Out 2008 17:33
por cristianoisaac
Olá, estou utilizando o microcontrolador AT89S52 e programando na linguagem C. Sou novato e essa é praticamente a primeira vez que programo com microcontroladores.
O timer 0 está sendo utilizado para gerar baudrate, porém, como utilizo um microcontrolador da família 8052, ele ainda possui dois timers/counters. Porém estou tendo dificuldades para programá-lo para realizar a interrupção em valores superiores a 10us, isso porque estou utilizando apenas um timer e não queria que ele realizasse nenhuma interrupção em valores tão pequenos. Gostaria de saber se eu poderia fazer com que o timer 1 e o timer 2 fossem utilizados para realizar uma interrupção com valores aproximados de 1 segundo ou mais, isso sem parar a utilização do microprocessador.
Eu tinha feito um contador para realizar o comando dentro da interrupção apenas quando seu número fosse 11, o que daria aproximadamente 1 segundo pelos calculos realizados, mas nao queria que ele entrasse em nenhuma interrupção antes de 1 segundo para não "roubar" o processamento...
Desculpe se falei alguma bobagem.
Agradeço desde já.

Enviado:
28 Out 2008 12:12
por delenga
timer0() interrupt 1 using 2
{
//declarar no inicio do programa como unsigned char contador0;
TR0=0; //desliga contador
if( ++contador0 == 100 ) {contador0 = 0;//112 MAIS OU MENOS MINUTO
//Escreva aqui seu programa
}//fim do if
TR0=1;//liga contador
}

Enviado:
28 Out 2008 12:17
por delenga
Só alterar para timer 1
timer1 () interrupt 3
{
}

Enviado:
30 Out 2008 19:29
por cristianoisaac
Opa. obrigado pela resposta, mas não era isso que eu queria. Eu pensei em fazer isso, porém, ele continuará executando a interrupção muito rápida. Eu queria é que ele só executasse a interrupção após 1 segundo aproximado. Que ele não ocorresse antes disso, entendeu? Pois desse jeito ela ocorre, incrementa o contador e só entra na interrupção após o contador ser um determinado valor.
Grato

Enviado:
30 Out 2008 22:41
por msamsoniuk
imagino que vc tentou combinacoes de prescaler e divisor e soh conseguiu chegar a valores bem maiores que o 1Hz que vc precisa. uma solucao seria vc nao gerar interrupcao pelo timer, mas apenas fazer a saida do sinal dele em determinada frequencia. por exemplo, se vc fizer a saida em 256 Hz, poderia injetar o sinal como clock de dois 74LS93 cascateados e vai obter um sinal de 1Hz, que pode ser usado para ativar uma interrupcao externa.

Enviado:
31 Out 2008 03:51
por jeanfernandes
Prezado
Voce pode programar o mcu para contador de 16 bits, em modo recarregavel.
O problema é o seguinte.
Imagine que voce quer por exemplo seu mcu trabalhe em 12 Mhz.
Se for um convencional voce pega o clock interno que é esse ae dividido por 12 (lembre-se que tem mcu que eh X2 e divide por 6)....
ai tem um tick de processador vamos dizer de 1 Mhz....que dá 1us....
Entao o que ocorre ?
Digamos que voce esteja por dentro que o tempo de entrada de execucao na rotina da interrupcao depende que instrucao o mcu estava executando no momento, e que há o tempo de empilhar e desempilhar os registradores e tals...vamos supor que isso não seja relevante...pois se for voce vai ter que fazer uns ajustes ae ...
Nao sei se he pra relógio....pois se for...ai complica...vai gerar atraso mesmo...
Bom voltando....
1000 us = 1 ms
50000 us = 50 ms
ou seja em tese....voce pode por por exemplo um timer de 50 ms pra contar 20 vezes pra dar um segundo....
No modo recarregavel...(e que voce desconte o tempo de execucao das suas rotinas e claro estabeleca que esse timer eh prioritario, pois senao uma interrupcao da serial vai por exemplo baguncar a conta se esta for prioritaria)...
ou seja tem que usar THx TLx em modo de 16 bits....recarregavel para brincar com um tempo mais lento....

Enviado:
31 Out 2008 03:58
por jeanfernandes
Uma boa pedida se voce tiver curiosidade eh tentar ver essa literatura aqui
Exploiting C for Microcontrollers
A Hands of Approach
da Springer
Se nao to enganado tem uma rotina em C explicando o que fazer na parada....
Ou o livro do Mauricio de Sá.
Fuiz.

Enviado:
03 Nov 2008 12:58
por Ander_sil
Cristiano voce não consegue fazer isso porque esse uC não possui prescaler no timer, a melhor opção é usar o timer2 como o Jean disse.
Para aumentar o tempo de interrupção voce pode usar um cristal com clock baixo tipo 2Mhz (acho que esse uC suporta 1Mhz) mas isso se não for problema no seu programa.
Segue um trecho de código do timer2 como exemplo:
- Código: Selecionar todos
/*************************************************************************
FUNCAO: programa_timer2()
PARAMETROS: NENHUM
RETORNO: NENHUM
DESCRICAO: Programa o TIMER2 no modo temporizador 16 bits auto-reload
**************************************************************************/
void programa_timer2(void)
{
T2CON = 0x00; // programa TIMER2 no modo temporizador; 16 bits; auto-reload;
// apaga os flags TF2 e TR2; timer desligado
RCAP2 = MAX_COUNT - TEMPO_INT; // carrega os registradores
// RCAP2H e RCAP2L
// com os valores de recarga para interrupção
TH2 = RCAP2H; // copia o valor alto do tempo de interrupção
// para o registrador TH2
TL2 = RCAP2L; // copia o valor baixo do tempo de interrupção
// para o registrador TL2
PT2 = 1; // coloca interrupção de TIMER2 no grupo de alta prioridade;
// TIMER2 será atendido primeiro que TIMER1 e Serial
ET2 = 1; // habilita interrupção de TIMER2
}
- Código: Selecionar todos
/*************************************************************************
FUNCAO: int_timer2() Interrupção
PARAMETROS: NENHUM
RETORNO: NENHUM
DESCRICAO: Interrupção a cada 50ms
**************************************************************************/
void int_timer2(void) interrupt 5
{
if(Cont50ms >= 48) // Se Cont50ms = ou maior de 20
{
Cont50ms = 0; // Zero Cont50ms
seg++; // Incremento seg
FlagTimer = 1; // Seto o flag de 1Seg
}
if(seg >= 60) // Se seg = ou maior que 60
{
seg=0; // Zero o seg e
min++; // Incremento min
}
if(min >= 60) // Se min = ou maior que 60
{
min=0; // Zero o min e
hora++; // Incremento hora
}
if(hora >= 24) // Se hora = ou maior que 24
{
seg=0; // Zero seg
min=0; // Zero min
hora=0; // Zero hora
}
Cont50ms++; // Incremento Cont50ms a cada interrupção (50ms)
TF2 = 0; // libera o flag de overflow para a próxima
// interrupção de TIMER2
}
Falow!!!

Enviado:
03 Nov 2008 20:32
por cristianoisaac
Tá ok. Obrigado, vou testar aqui as soluções apresentadas e pesquisar melhor. ^^