Форумчане, подскажите что я упустил в настройках таймера TCC0 на прерывания.
Суть такова, хотел настроить таймер на совпадение с регистром CCA. Поставил регистр периода на полный счет, т.е. 0xFFFF, а в CCA записываем, например 1000. Так вот прерывания по сравнению происходит как и для переполнения в 0xFFFF -> 0x0000. Для наглядности добавил прерывания по переполнению и убедился что так оно и есть. Если регистр периода изменять, то опять таки происходят оба прерывания по числу из этого регистра. Проверить в студии не могу, там почему-то флаги устанавливаются, а на обработчик программа не переходит (и в 4 и в 6). Проверяю в железе.
Вот кодик.
CODE
void tcc0_init(void)
{
unsigned char s;
unsigned char n;
s=SREG;
asm("cli");
tc0_disable(&TCC0); // эту не вставляю, но она есть
TCC0.CTRLA=(TCC0.CTRLA & (~TC0_CLKSEL_gm)) | TC_CLKSEL_DIV64_gc; // делитель на 64
TCC0.CTRLB=(TCC0.CTRLB & (~(TC0_CCAEN_bm | TC0_CCBEN_bm | TC0_CCCEN_bm | TC0_CCDEN_bm | TC0_WGMODE_gm))) | TC_WGMODE_NORMAL_gc | TC0_CCAEN_bm; // тут ССAEN включаю, хотя не обязательно
TCC0.CTRLD=(TCC0.CTRLD & (~(TC0_EVACT_gm | TC0_EVSEL_gm))) | TC_EVACT_OFF_gc | TC_EVSEL_OFF_gc;
// Включаем переполнение по высокому приоритету
TCC0.INTCTRLA=(TCC0.INTCTRLA & (~(TC0_ERRINTLVL_gm | TC0_OVFINTLVL_gm | TC_ERRINTLVL_OFF_gc))) | TC_OVFINTLVL_HI_gc;
// Включаем сравнение тоже по высокому приоритету
TCC0.INTCTRLB=(TCC0.INTCTRLB & (~(TC0_CCDINTLVL_gm | TC0_CCCINTLVL_gm | TC0_CCBINTLVL_gm | TC0_CCAINTLVL_gm))) | TC_CCDINTLVL_OFF_gc | TC_CCCINTLVL_OFF_gc | TC_CCBINTLVL_OFF_gc | TC_CCAINTLVL_HI_gc;
// Clear the interrupt flags
TCC0.INTFLAGS=TCC0.INTFLAGS;
// Set counter register
TCC0.CNT=0x0000;
// Период на 65535
TCC0.PER=0xFFFF;
// Компаратор на 1000
TCC0.CCA=1000;
// Restore interrupts enabled/disabled state
SREG=s;
}
void main (void)
{
unsigned char n;
// Включаем прерывания для высокого и низкого приоритетов.
n=(PMIC.CTRL & (~(PMIC_RREN_bm | PMIC_IVSEL_bm | PMIC_HILVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm))) |
PMIC_HILVLEN_bm | PMIC_LOLVLEN_bm;
CCP=CCP_IOREG_gc;
PMIC.CTRL=n;
// Set the default priority for round-robin scheduling
PMIC.INTPRI=0x00;
Config32MHzClock();
tcc0_init();
asm("sei");
for(;;){}
}
и оба обработчика.
unsigned int tt, ttt;
#pragma vector = TCC0_CCA_vect
__interrupt void TCC0_CCA_v(void)
{
tt++;
}
#pragma vector = TCC0_OVF_vect
__interrupt void TCC0_OVF_v(void)
{
ttt++;
}
Что упущенно? Спасибо, если подскажите.
UPD. Всё, ложная тревога. Всё правильно выполняется. Если сбрасывать CNT в сравнении, то оно таки вызывается на 1000. Просто при 32мгц это кажется одновременным вызовом. ))
Всем спасибо.
Сообщение отредактировал IgorKossak - May 13 2014, 13:19
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!