Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AT91SAM7A3 Прерывание таймера 0
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
KSN
Таймер 0 тактируется внешними тактовым сигналом.
Устанавливаю регистры таймера RA,RB,RC. Разрешаю прерывания по сравнению для всех трех регистров. Фактически срабатывает только прерывания RA и RC, а RB - нет. Никак не могу понять - почему?
Ниже привожу код запуска таймера:
PORT_COUNTER->PIO_PDR = BIT_COUNTER; // config PB10 - input timer0
PORT_COUNTER->PIO_ASR = BIT_COUNTER;
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); /* Enable periph clock for the PIO controller */
/* Disable the clock and the interrupts */
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC0->TC_IDR = 0xFFFFFFFF;
/* Clear status bit */
temp = AT91C_BASE_TC0->TC_SR;
/* Set the Mode of the Timer Counter */
//AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_XC1|AT91C_TC_WAVESEL_UP|AT91C_TC_WAVE;
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKI|AT91C_TC_CLKS_XC1|AT91C_TC_WAVESEL_UP|AT91C_TC_WAVE;
AT91C_BASE_TC0->TC_RA = 50;
AT91C_BASE_TC0->TC_RB = 150;
AT91C_BASE_TC0->TC_RC = 200;
/* Enable interrupts */
/* Disable the interrupt on the interrupt controller */
AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_TC0);
/* Save the interrupt handler routine pointer and the interrupt priority */
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (unsigned long) timer_handler;
/* Store the Source Mode Register */
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | (AT91C_AIC_PRIOR&PRIORITY_TCO);
/* Clear the interrupt on the interrupt controller */
AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_TC0);
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPAS;
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPBS;
AT91C_BASE_TC0->TC_IER = AT91C_TC_COVFS;
/* Enable the interrupt on the interrupt controller */
AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_TC0);
/* Clock is started */
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
/* Counter is reset and the clock is started */
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;

ОБработчик прерывания от таймера:

void timer_handler(void)
{ volatile unsigned long dummy;
dummy = AT91C_BASE_TC0->TC_SR; /* Clear status bit */
if( (dummy&AT91C_TC_CPAS) && (AT91C_BASE_TC0->TC_IMR&AT91C_TC_CPAS) ) {
#ifndef NDEBUG
Set_Led(4);
#endif
AT91C_BASE_TC0->TC_IDR = AT91C_TC_CPAS; /* Disable interrupt CPAS*/
pSD->Speed = pSD->Speed_max;
pSD->CPRD = (AT91B_MCK>>1)/pSD->Speed;
pSD->State = RUN;
AT91C_BASE_PWMC->PWMC_IER = AT91C_PWMC_CHID2;
}
if( (dummy&AT91C_TC_CPBS) && (AT91C_BASE_TC0->TC_IMR&AT91C_TC_CPBS) ) {
AT91C_BASE_TC0->TC_IDR = AT91C_TC_CPBS;
pSD->Accel_factor = 0x00000000-pSD->Accel_factor;
pSD->State = DECEL;
#ifndef NDEBUG
Set_Led(5);
#endif
}
if( (dummy&AT91C_TC_CPCS) && (AT91C_BASE_TC0->TC_IMR&AT91C_TC_CPCS) ) {// End of DECELERATION. STOP.
Stop();
}
if( dummy&AT91C_TC_COVFS ) {// increment high_timer counters
pSD->Counter += 0x00010000;
TESTCNT(pSD->Accel_cnt, AT91C_TC_CPAS);
TESTCNT(pSD->Decel_cnt, AT91C_TC_CPBS);
TESTCNT(pSD->End_cnt, AT91C_TC_CPCS);
}
}
aaarrr
Обертка какая-нибудь (и какая именно) для вектора IRQ у Вас присутствует?

P.S. пользуйтесь тегами [сode][/сode].
KSN
Шапка для прерываний:
Код
__irq __nested __arm void IRQ_Handler(void)
{
void (*interrupt_function)(void);
unsigned int vector;
vector=AT91C_BASE_AIC->AIC_IVR;
interrupt_function=(void(*)())vector;
(*interrupt_function)();
AT91C_BASE_AIC->AIC_EOICR=0;
}

При детальном изучении даташита в описании значение битов EEVT мелким шрифтом
if TIOB is chosen as the external event signal, it is configured as an input and no longer generates waveforms and subsequently no IRQs.
Изменил значение по умолчанию 00b на 01b. Прерывание по сравнению регистра B стало срабатывать.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.