我试图让atxmega16e5上的TCC4工作。我的问题是比较通道中断只触发一次。中断标志甚至可以设置,但ISR永远不会被执行。我启用了溢出中断,它一直运行正常。我已经在模拟器和我的实际芯片上测试了它,结果相同。我正在使用Atmel软件框架。我真的感觉到我错过了一些有趣的东西,而我却无法弄明白。
以下是代码:
#define TIMER_TC TCC4
#define TIMER_INT_LVL TC45_INT_LVL_LO
int main (void) {
sysclk_init();
eeprom_enable_mapping();
board_init();
pmic_init();
timer_init();
timer_set_top(100);
cpu_irq_enable();
timer_start();
while(1) {}
}
void timer_cca(void) { //Breakpoint here - reached just once
}
void timer_ccb(void) { //Breakpoint here - reached just once
}
void timer_ccc(void) { //Breakpoint here - reached just once
}
void timer_ccd(void) { //Breakpoint here - reached just once
}
void timer_overflow(void) { //Breakpoint here - reached multiple times
}
void timer_init() {
tc45_enable(&TIMER_TC);
tc45_set_wgm(&TIMER_TC, TC45_WG_NORMAL);
tc45_enable_cc_channels(&TIMER_TC, TC45_CCACOMP | TC45_CCBCOMP | TC45_CCCCOMP | TC45_CCDCOMP);
tc45_set_cca_interrupt_callback(&TIMER_TC, &timer_cca);
tc45_set_cca_interrupt_level(&TIMER_TC, TIMER_INT_LVL);
tc45_set_ccb_interrupt_callback(&TIMER_TC, &timer_ccb);
tc45_set_ccb_interrupt_level(&TIMER_TC, TIMER_INT_LVL);
tc45_set_ccc_interrupt_callback(&TIMER_TC, &timer_ccc);
tc45_set_ccc_interrupt_level(&TIMER_TC, TIMER_INT_LVL);
tc45_set_ccd_interrupt_callback(&TIMER_TC, &timer_ccd);
tc45_set_ccd_interrupt_level(&TIMER_TC, TIMER_INT_LVL);
tc45_write_cc(&TIMER_TC, TC45_CCA, 1);
tc45_write_cc(&TIMER_TC, TC45_CCB, 1);
tc45_write_cc(&TIMER_TC, TC45_CCC, 1);
tc45_write_cc(&TIMER_TC, TC45_CCD, 1);
tc45_set_overflow_interrupt_level(&TIMER_TC, TC45_INT_LVL_LO);
tc45_set_overflow_interrupt_callback(&TIMER_TC, &timer_overflow);
}
void timer_start() {
tc45_write_clock_source(&TIMER_TC, TC45_CLKSEL_DIV64_gc);
}
void timer_set_top(uint16_t top) {
tc45_write_period(&TIMER_TC, top);
}
答案 0 :(得分:2)
这是使用TC45处理通道比较中断的ASF快速入门文档的链接: http://asf.atmel.com/docs/3.11.0/xmegae/html/xmega_tc45_quickstart.html#xmega_tc45_qs_cc
看起来你已经关闭了。我看到的唯一真正的区别是他们将ISR声明为静态void并将它们直接传递给set_callback函数,而不是传递指针:
tc45_set_cca_interrupt_callback(&TIMER_TC, timer_cca);
而不是:
tc45_set_cca_interrupt_callback(&TIMER_TC, &timer_cca);
我还会在cc通道周围添加括号,让您高枕无忧:
tc45_enable_cc_channels(&TIMER_TC, (TC45_CCACOMP | TC45_CCBCOMP | TC45_CCCCOMP | TC45_CCDCOMP));
尝试增加比较值。调试器重置计数器并为溢出中断提供服务后,调试器可能不够快,无法捕获比较值。
如果您仍然遇到问题,请尝试在ISR中手动清除CCxIF。也许它并没有像它应该的那样自动完成。