Página 1 de 1
TIMER0 INTERRUPT

Enviado:
16 Jun 2008 08:42
por wrodrigo
Olá pessoal, estou com um problema com a interrupção de timer 0.
Ela ocorre a primeira vez e depois simplesmente não ocorre mais, se alguém puder ajudar eu agradeceria muito.
As minhas rotinas são :
- Código: Selecionar todos
int main (void)
{
/*================================
** INICIALIZAÇÃO DOS PERIFÉRICOS
**===============================*/
PCONP |= (1 << 1); //Timer0 Power Enabled
INIT_TIMER(10); //Timer p/ 10 segundos
for(;;);
}
void INIT_TIMER(int seconds)
{
int counter_timer;
counter_timer=seconds*20000000;
/* Setup Timer Counter 0: Periodic Timer with nterrupt */
PCONP |= (1 << 1); //Timer0 Power Enabled
T0MR0 = counter_timer;
T0MCR =3; // Gera interrupção quanto MR0 se igualar ao TC (T0MCR =3 => 0x03)
/*resetar timer antes de iniciar contagem*/
T0TCR = 2; // Reseta o TC
T0TCR = 0; // Release o Reset
T0TCR = 1; // START TIMER
/* Setup Timer Counter 0 Interrupt */
VICVectAddr4 = (unsigned long)timer0_irq;
VICVectCntl4 = 0x02;
VICIntEnable |= 1 << 4;
}
/*===================================================================*/
/* TRATAMENTO DA INTERRUPÇÃO DO TIMER 0 */
/*===================================================================*/
__irq void timer0_irq (void)
{
LED_DEBUG_NEGVAL(); //
T0IR = 1; // Clear interrupt flag
VICVectAddr = 0; // Acknowledge Interrupt
}

Enviado:
16 Jun 2008 12:59
por tcpipchip
Amigo
Este exemplo eu fiz em basic e funcionou...mas eh para o TIMER1...talvez ajude voce.
TCPIPCHIP
'ARM GNU BASIC FOR ARM
Dim TIMER1_counter as integer
Dim Stat_Init_Timer1 as boolean
sub main()
Stat_Init_Timer1 = init_TIMER1()
Do
loop while 1 = 1
end sub
function init_TIMER1() as boolean
TIMER1_counter = 0
T1MR0 = &H0001FFFF
T1MCR = 3
init_TIMER1 = __hbbr_install_irq(TIMER1_INT, AddressOf irq_TIMER1)
VICIntEnable = VICIntEnable Or &b00100000
Call __hbbr_enable_irq()
T1TCR = 1
End function
Irq irq_TIMER1()
Print #0,"Ocorreu interrupcao..."
T1IR = 1
TIMER1_counter = TIMER1_counter + 1
VICVectAddr = 0
End Irq
Ocorreu interrupcao...
Ocorreu interrupcao...
Ocorreu interrupcao...
Ocorreu interrupcao...
Ocorreu interrupcao...

Enviado:
16 Jun 2008 13:19
por leoabubauru
Rodrigo:
Não sei que compilador você está usando, mas sei que não é o CCS o qual estou mais familiarizado. Mesmo assim, de cara reparei que você faz uma conta que da maneira que está declarada com certeza trará algum efeito indesejado:
int counter_timer;
counter_timer=seconds*20000000;
Para qualquer valor de "seconds" maior que zero, "counter_timer" terá um valor errado uma vez que está declarado com um tipo de 16 bits que suporta só até 65535!
A última linha da INT eu não sei o que o compilador faz, mas geralmente nos PICs basta limpar o flag da int, o que você faz na primeira linha.
Espero ter contribuido...
Laercio

Enviado:
16 Jun 2008 14:36
por tcpipchip
Nao eh CCS.
O meu INT é de 32 bits...

Enviado:
16 Jun 2008 14:57
por wrodrigo
Olá pessoal,
Bom eu estou utilizando Keil com MDK-ARM.
Conforme o leoabubauro mencionou, corrigi o código, agora o timer é fixo em 60 segundos, testado ok.
Com o exemplo do tcpipchip consegui adaptar meu código e agora a interrupção é executada sempre.
Porém agora surgiu uma outra dúvida, dentro do handler da minha interrupção eu precisaria chamar uma outra função, e isso está fazendo com que o software se "perca" e ele simplesmente não faz mais nada.
Dúvida: Após limpar a flag de interrupção e zerar o VIC, pra onde o software retorna ?
No pic tinhamos o vetor de reset onde eu limpava variaveis e registradores, e no ARM ?
Muito obrigado pela ajuda

Enviado:
17 Jun 2008 21:42
por jeanfernandes
Rodrigo
Volta para onde o PC (cuidado com o pre-fetch) estava....
Sobre chamar uma funcao dentro de uma interrupcao ehehehehe bom nao eh uma boa pratica....na verdade voce tem que alterar variaveis setar flags etc...dentro de uma interrupcao....
Mas eu ja fiz um teste aqui e funciona perfeito....see code
- Código: Selecionar todos
void app_timer0_setup(void)
{
/*
Configuracao dos tempos
MSEL = 5
PSEL = 2
PCLK = 12*MSEL/f(VPBDIV) = 60 MHZ
Tick do Timer Requerido = 100 us
*/
// T0MR0 = 59999; // 1 mSec = 60000 - 1 contagens
T0MR0 = 29999; // .1 mSec = 6000 - 1 contagens
T0MCR = 3; // Interrupt and Reset on MR0
T0TCR = 1; // Habilita o Timer 0
/* Configura a interrupcao no vetor 0 */
VICVectAddr1 = (unsigned long) app_timer0_int;
VICVectCntl1 = 0x20 | 4; // use it for Timer 0 Interrupt
VICIntEnable |= 0x00000010; // Habilita a interrupcao do Timer 0
}
void app_timer0_int (void) __irq
{
/* if (!destino_timeout--) {
destino_timeout = DESTINO_VARREDURA_TIMEOUT;
destino_varredura();
} */
if (!--destino_timeout) {
destino_timeout = DESTINO_VARREDURA_TIMEOUT;
// destino_varredura();
destino_dvarredura();
}
if (muda_valor_timeout) {
muda_valor_timeout--;
}
T0IR = 1; // Limpa o flag de interrupção
VICVectAddr = 0; // Reconhece a interrupção
}
Num chame uma funcao que baixe a internet pro seu pen drive...ela pode demorar um céu ....pra terminar ai froide ne bixo....
outra coisa....cuidado com a pilha de usuario e interrupcao.... (la no startup.ps) ehehehhehe isso as vezes froide com o bagulho
Fuiz.

Enviado:
17 Jun 2008 21:45
por jeanfernandes
Outro bagulho que gosto de usar ...que atende gregos troianos bibas e cabras da pexte sao os typedefs..... pra ter noção das coisas do tamanho das variáveis....
- Código: Selecionar todos
/*************************************************************************
Definições de Tipos
**************************************************************************/
/* Inteiros sem sinal */
typedef unsigned char byte; // 1 byte
typedef unsigned char uchar;
typedef unsigned char u08;
typedef unsigned short word; // 2 bytes
typedef unsigned short uint;
typedef unsigned short u16;
typedef unsigned int dword; // 4 bytes
typedef unsigned int ulong;
typedef unsigned int u32;
/* Inteiros com sinal */
typedef char schar; // 1 byte
typedef signed char s08;
typedef short sint; // 2 bytes
typedef signed short s16;
typedef signed long s32; // 4 bytes
/* Ponto fixo */
typedef double ddouble;
typedef unsigned char tU8;
typedef unsigned short tU16;
typedef unsigned int tU32;
typedef char tS8;
typedef short tS16;
typedef int tS32;
typedef unsigned char tBool;

Enviado:
19 Jun 2008 08:04
por wrodrigo
Muito obrigado jean,
Realmente revi meus conceitos e ajustei minhas interrupções. Agora está tudo funcionando direitinho !!!
Valeu a força de todos
Abraços
