过去2周我正在尝试学习计时器&中断&写了一个程序(据我的理解)在ATMEGA2560上闪烁LED,但无论我做什么,TCNT0都不会增加&永远不会调用ISR()函数。我哪里出错了,我该如何解决?这是我的代码:
#include<avr/io.h>
#include<avr/interrupt.h>
#define READ_ATMEGA(ADDR) *((P_CHAR)(BASE_ADDR + ((ADDR) * ADDR_MULTIPLIER)))
#define WRITE_ATMEGA(ADDR, DATA) *((P_CHAR)(BASE_ADDR + ((ADDR) * ADDR_MULTIPLIER))) = DATA
#define BASE_ADDR 0x20
void init_timer0_ovf_interrupt(void);
void timer0_interrupt_isr(void);
void initialize_ports(void);
void delay(unsigned int no_65_5ms_interrupts);
void __attribute__((ISR)) timer0_interrupt_isr(void);
//#pragma interrupt_handler timer0_interrupt_isr:24
unsigned int delay_timer;
int main(void)
{
initialize_ports();
init_timer0_ovf_interrupt();
delay(46);
return 0;
}
void initialize_ports(void)
{
READ_ATMEGA(4) = 0xff;
WRITE_ATMEGA(5, 0x00);
}
void delay(unsigned int no_65_5ms_interrupts)
{
TCNT0 = 0x00;
delay_timer = 0;
while(delay_timer <= no_65_5ms_interrupts)
{
;
}
}
void init_timer0_ovf_interrupt(void)
{
TCCR0A = 0X00;
TCCR0B = 0x02;
TIMSK0 = 0x01;
TIFR0 = 1<<0;
OCR0A = 25;
sei();
}
void timer0_interrupt_isr(void)
{
delay_timer++;
if(delay_timer >= OCR0A)
{
PORTB = ~(PORTB);
delay_timer = 0;
}
}
答案 0 :(得分:1)
全局变量delay_timer
在中断和非中断代码之间共享。它应声明为volatile
,因为值可以在delay()
之外更改。
如果查看生成的delay()
代码,您可能会看到在while
循环中旋转时不会重新读取delay_timer的值。
另外,volatile
还不够。你有非中断代码和中断代码写入同一个变量(delay_timer)。你需要在非中断代码中保护对变量的写入,那里存在竞争条件。简单/懒惰的方法是禁用中断和在非中断代码中恢复它们。
(至于设置你的中断和启动你的计时器,这些信息应该在芯片的数据表中。通常这是更容易理解的部分,它是咬人的共享数据。)
答案 1 :(得分:1)
3-4天前,我用同样的方式编写了相同的程序。 LED眨眼但仍不确定是否正确使用定时器和放大器。打断。任何人都可以看到这个&amp;告诉我这是否正确?我设法通过读取计时器,中断程序来编写这个程序。
#include <avr/io.h>
#include <avr/interrupt.h>
volatile uint8_t intrs;
ISR(TIMER0_OVF_vect) {
/* this ISR is called when TIMER0 overflows */
intrs++;
/* strobe PORTB.5 - the LED on arduino boards */
if (intrs >= 61){
PORTB = ~PORTB;
intrs = 0;
}
}
int main(void) {
TCCR0B = 0x02;
/* Enable Timer Overflow Interrupts */
TIMSK0 = 0x01;
/* other set up */
DDRB = 0xff;
TCNT0 = 0;
intrs = 0;
/* Enable Interrupts */
sei();
while (1)
; /* empty loop */
}
如果这是正确的方法,那么我可以开始下一步了。
由于
答案 2 :(得分:0)
如果延迟函数中的while循环可能没有做任何事情而且不会增加delay_timer,那么你就会陷入无限循环:
void delay(unsigned int no_65_5ms_interrupts)
{
TCNT0 = 0x00;
delay_timer = 0;
while(delay_timer <= no_65_5ms_interrupts)
{
; //Nothing is happening here!!
}
}