Здравствуйте!
Пишу под AT91sam7s64.
Столкнулся с такой проблемой:
Я пользуюсь 2 таймерами TC1 и TC2 в режиме захвата.
Таймера настроены на захват регистра А и рестарт по сравнению с регистром С .
Таймера запущены синхронно и значения регистра С одинаковы.
На таймера есть прерывания по захвату А и сравнению С, по сравнению прерывания возникают одновримено.
Все вроде работает неоприледен время, а потом тупо перестает заходить в обработчик прерываний одного из таймеров (рас 1 рас 2 ..) .
Не заходит, пока не поставлю в дебаге точку останова, непосредственно в том обработчике.
После чего все начинает снова работать не оприделеное время и так по колу.
Код
static void ISR_TC1(void)
{
unsigned int uiSR = AT91C_BASE_TC1->TC_SR;
if( (uiSR & AT91C_TC_CPCS) )
{
uiOverTC1++;
}
if( uiSR & AT91C_TC_LDRAS )
{
unsigned int uiRA = AT91C_BASE_TC1->TC_RA;
if (uiStartT1 <3 )
{
Timer1[uiStartT1].uiRA = uiRA;
Timer1[uiStartT1].uiOver = uiOverTC1;
Timer1[uiStartT1].bZap = true;
uiStartT1++;
}
}
}
void InitTC1ForFreq()
{
//AIC configure.
AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_TC1; // Disable the interrupt first
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC1] = AT91C_AIC_SRCTYPE_POSITIVE_EDGE | AT91C_AIC_PRIOR_HIGHEST;
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC1] = (unsigned int) ISR_TC1;
AT91C_BASE_AIC->AIC_ICCR = 1 << AT91C_ID_TC1; // Clear interrupt
AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_TC1; // Enables interrupts
// Enable PWMC peripheral clock
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TC1;
// Disable TC clock
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
// Disable interrupts
AT91C_BASE_TC1->TC_IDR = 0xFFFFFFFF;
// Clear status register
AT91C_BASE_TC1->TC_SR;
// Set mode
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | // MCK/2
AT91C_TC_BURST_NONE |
AT91C_TC_EEVTEDG_NONE |
AT91C_TC_CPCTRG |
AT91C_TC_ABETRG |
AT91C_TC_LDRA_RISING; // each edge of TIOA
AT91C_BASE_TC1->TC_RC = 0xffff;
// Enable interrpt
AT91C_BASE_TC1->TC_IER = AT91C_TC_CPCS | // Counter compare CR
AT91C_TC_LDRAS; // RA Loading
// Start TC1
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
// Atach to PIO for TIOA1
AT91C_BASE_PIOA->PIO_BSR = AT91C_PA15_TIOA1;
AT91C_BASE_PIOA->PIO_PER = AT91C_PA15_TIOA1;
}
////////////////////////////////////////////////////////////////////////////////
// Timer 2 IntL
////////////////////////////////////////////////////////////////////////////////
unsigned int uiOverTC2 = 0; // ïåðåïîâíåííÿ òàéìåðà
unsigned int uiTC2LastRA = 0;
static void ISR_TC2(void)
{
unsigned int uiSR = AT91C_BASE_TC2->TC_SR;
if( (uiSR & AT91C_TC_CPCS) )
{
uiOverTC2++;
}
if( (uiSR & AT91C_TC_LDRAS) )
{
unsigned int uiRA = AT91C_BASE_TC2->TC_RA;
if (uiStartT2 <3 )
{
Timer2[uiStartT2].uiRA = uiRA;
Timer2[uiStartT2].uiOver = uiOverTC2;
Timer2[uiStartT2].bZap = true;
uiStartT2++;
}
}
}
void InitTC2ForFreq()
{
//AIC configure.
AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_TC2; // Disable the interrupt first
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC2] = AT91C_AIC_SRCTYPE_POSITIVE_EDGE | AT91C_AIC_PRIOR_HIGHEST;
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC2] = (unsigned int) ISR_TC2;
AT91C_BASE_AIC->AIC_ICCR = 1 << AT91C_ID_TC2; // Clear interrupt
AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_TC2; // Enables interrupts
// Enable PWMC peripheral clock
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TC2;
// Disable TC clock
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKDIS;
// Disable interrupts
AT91C_BASE_TC2->TC_IDR = 0xFFFFFFFF;
// Clear status register
AT91C_BASE_TC2->TC_SR;
// Set mode
AT91C_BASE_TC2->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | // MCK/2
AT91C_TC_BURST_NONE |
AT91C_TC_EEVTEDG_NONE |
AT91C_TC_CPCTRG |
AT91C_TC_ABETRG |
AT91C_TC_LDRA_RISING; // each edge of TIOA
AT91C_BASE_TC2->TC_RC = 0xffff;
// Enable interrpt
AT91C_BASE_TC2->TC_IER = AT91C_TC_CPCS | // Counter
AT91C_TC_LDRAS; // RA Loading
// Start TC1
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
//synhron timers
AT91C_BASE_TCB->TCB_BCR = AT91C_TCB_SYNC;
// Atach to PIO for TIOA2
AT91C_BASE_PIOA->PIO_BSR = AT91C_PA26_TIOA2;
AT91C_BASE_PIOA->PIO_PER = AT91C_PA26_TIOA2;
}