Сам таймер работает, + при бесконечном опросе флага AT91C_TC_CPCS в TC_SR (произошло накопление счетчика до значения RC) все робит как нуно. Но мне нужны прерывания по такому поводу.
Как правельно настроить, чтобы появились прерывания от таймера T0 по достижению счетчика значения RC ?
Код
#include "AT91SAM7S128.h"
void timer_tick10ms(void) __attribute__ ((interrupt)); // забыл вставить, но в моей проге это было и есть
void timer_tick10ms(void)
{
unsigned int temp;
AT91C_BASE_AIC->AIC_IDCR = (1<<AT91C_ID_TC0);
temp=AT91C_BASE_TC0->TC_SR;
led_tgl();
AT91C_BASE_AIC->AIC_ICCR = (1<<AT91C_ID_TC0);
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;//перезапуск таймера
AT91C_BASE_AIC->AIC_IECR = (1<<AT91C_ID_TC0);
AT91C_BASE_AIC->AIC_EOICR = 0;//(1<<AT91C_ID_TC0);
}
void init_timer( void )
{
AT91C_BASE_TCB->TCB_BCR = 1;
AT91C_BASE_TCB->TCB_BMR = 0x15;
AT91C_BASE_TC0->TC_CMR = (1 << 15) | (2<<13) | 1;//4
AT91C_BASE_TC0->TC_RC = 0x1;
//AT91C_BASE_TC0->TC_IDR = 0xFFFFFFFF;
AT91C_BASE_TC0->TC_IDR &= ~((long)AT91C_TC_CPCS);
AT91C_BASE_TC0->TC_IER |= AT91C_TC_CPCS;
*AT91C_AIC_ICCR = (1<<AT91C_ID_TC0);
AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF;
AT91C_BASE_AIC->AIC_EOICR = 0;//*/
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (unsigned long)timer_tick10ms;
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = (1 << 5) | 0x7;
AT91C_BASE_AIC->AIC_IDCR &= ~(1<<AT91C_ID_TC0);
AT91C_BASE_AIC->AIC_IECR |= (1<<AT91C_ID_TC0);
//AT91C_BASE_AIC->AIC_ISCR = (1<<AT91C_ID_TC0);
ctl_global_interrupts_enable();
//*/
AT91C_BASE_PMC->PMC_PCER |= (1<<AT91C_ID_TC0);
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;//запуск таймера
}
int init( void )
{
int i;
AT91PS_PMC pPMC = AT91C_BASE_PMC;
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
pPMC->PMC_MOR = 1;//(( AT91C_CKGR_OSCOUNT & (0x06 <<8) | AT91C_CKGR_MOSCEN ));
// Wait the startup time
while(!(pPMC->PMC_SR & AT91C_PMC_MOSCS));
pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 14) | (AT91C_CKGR_PLLCOUNT & (10<<8)) | (AT91C_CKGR_MUL & (72<<16)));
// Wait the startup time (until PMC Status register LOCK bit is set)
while(!(pPMC->PMC_SR & AT91C_PMC_LOCK));
pPMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 | 1;
while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));
pPMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;
while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));
//*******************
i=AT91C_PMC_PCK0 | AT91C_PMC_PCK;
*AT91C_PMC_SCER = i;
*AT91C_PMC_SCDR = ~i;
pPMC->PMC_PCKR[0]=0x00000015;
while( !(pPMC->PMC_SR & AT91C_PMC_PCK0RDY) );
//**************************************************
pPMC->PMC_IER=0xffffffff;
pPMC->PMC_SCER=0xffffffff;
i=(1 << AT91C_ID_PIOB) | (1 << AT91C_ID_US1);
pPMC->PMC_PCER = i;
pPMC->PMC_PCDR = ~i;
//**************************************************
volatile AT91PS_PIO pPIO = AT91C_BASE_PIOB; // pointer to PIO data structure
pPIO->PIO_OWER = LED_MASK | PB20_PIN_MASK;
pPIO->PIO_PER = LED_MASK | PB20_PIN_MASK;
pPIO->PIO_PPUDR = LED_MASK | PB20_PIN_MASK; //disabele pull-up on PB19
pPIO->PIO_OER = LED_MASK | PB20_PIN_MASK; //enable output on PB19
pPIO->PIO_CODR = LED_MASK | PB20_PIN_MASK;
pPIO->PIO_ASR=0;
pPIO->PIO_BSR=0;
init_timer();
return 0;
}
int main( void ) //************************* M A I N ******************************
{
init();
led_off();
while(1) //********************** W H I L E ******************************
{
//;
/*if( (AT91C_BASE_TC0->TC_SR & AT91C_TC_CPCS) )
//если постоянно читать флаг , все работает как нуно( переключение сигнала с нужным переудом)
{
led_tgl();
*AT91C_AIC_ICCR = 0;//AT91C_TC_CPCS;
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;//перезапуск таймера
}//*/
}//while 1
return -1;
}
void timer_tick10ms(void) __attribute__ ((interrupt)); // забыл вставить, но в моей проге это было и есть
void timer_tick10ms(void)
{
unsigned int temp;
AT91C_BASE_AIC->AIC_IDCR = (1<<AT91C_ID_TC0);
temp=AT91C_BASE_TC0->TC_SR;
led_tgl();
AT91C_BASE_AIC->AIC_ICCR = (1<<AT91C_ID_TC0);
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;//перезапуск таймера
AT91C_BASE_AIC->AIC_IECR = (1<<AT91C_ID_TC0);
AT91C_BASE_AIC->AIC_EOICR = 0;//(1<<AT91C_ID_TC0);
}
void init_timer( void )
{
AT91C_BASE_TCB->TCB_BCR = 1;
AT91C_BASE_TCB->TCB_BMR = 0x15;
AT91C_BASE_TC0->TC_CMR = (1 << 15) | (2<<13) | 1;//4
AT91C_BASE_TC0->TC_RC = 0x1;
//AT91C_BASE_TC0->TC_IDR = 0xFFFFFFFF;
AT91C_BASE_TC0->TC_IDR &= ~((long)AT91C_TC_CPCS);
AT91C_BASE_TC0->TC_IER |= AT91C_TC_CPCS;
*AT91C_AIC_ICCR = (1<<AT91C_ID_TC0);
AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF;
AT91C_BASE_AIC->AIC_EOICR = 0;//*/
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (unsigned long)timer_tick10ms;
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = (1 << 5) | 0x7;
AT91C_BASE_AIC->AIC_IDCR &= ~(1<<AT91C_ID_TC0);
AT91C_BASE_AIC->AIC_IECR |= (1<<AT91C_ID_TC0);
//AT91C_BASE_AIC->AIC_ISCR = (1<<AT91C_ID_TC0);
ctl_global_interrupts_enable();
//*/
AT91C_BASE_PMC->PMC_PCER |= (1<<AT91C_ID_TC0);
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;//запуск таймера
}
int init( void )
{
int i;
AT91PS_PMC pPMC = AT91C_BASE_PMC;
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
pPMC->PMC_MOR = 1;//(( AT91C_CKGR_OSCOUNT & (0x06 <<8) | AT91C_CKGR_MOSCEN ));
// Wait the startup time
while(!(pPMC->PMC_SR & AT91C_PMC_MOSCS));
pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 14) | (AT91C_CKGR_PLLCOUNT & (10<<8)) | (AT91C_CKGR_MUL & (72<<16)));
// Wait the startup time (until PMC Status register LOCK bit is set)
while(!(pPMC->PMC_SR & AT91C_PMC_LOCK));
pPMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 | 1;
while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));
pPMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;
while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));
//*******************
i=AT91C_PMC_PCK0 | AT91C_PMC_PCK;
*AT91C_PMC_SCER = i;
*AT91C_PMC_SCDR = ~i;
pPMC->PMC_PCKR[0]=0x00000015;
while( !(pPMC->PMC_SR & AT91C_PMC_PCK0RDY) );
//**************************************************
pPMC->PMC_IER=0xffffffff;
pPMC->PMC_SCER=0xffffffff;
i=(1 << AT91C_ID_PIOB) | (1 << AT91C_ID_US1);
pPMC->PMC_PCER = i;
pPMC->PMC_PCDR = ~i;
//**************************************************
volatile AT91PS_PIO pPIO = AT91C_BASE_PIOB; // pointer to PIO data structure
pPIO->PIO_OWER = LED_MASK | PB20_PIN_MASK;
pPIO->PIO_PER = LED_MASK | PB20_PIN_MASK;
pPIO->PIO_PPUDR = LED_MASK | PB20_PIN_MASK; //disabele pull-up on PB19
pPIO->PIO_OER = LED_MASK | PB20_PIN_MASK; //enable output on PB19
pPIO->PIO_CODR = LED_MASK | PB20_PIN_MASK;
pPIO->PIO_ASR=0;
pPIO->PIO_BSR=0;
init_timer();
return 0;
}
int main( void ) //************************* M A I N ******************************
{
init();
led_off();
while(1) //********************** W H I L E ******************************
{
//;
/*if( (AT91C_BASE_TC0->TC_SR & AT91C_TC_CPCS) )
//если постоянно читать флаг , все работает как нуно( переключение сигнала с нужным переудом)
{
led_tgl();
*AT91C_AIC_ICCR = 0;//AT91C_TC_CPCS;
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;//перезапуск таймера
}//*/
}//while 1
return -1;
}
код приведен не полностью , только самое важное.