需要计时器方面的帮助
在过去的两周里,我试图学习计时器和定时器。中断&编写了一个程序(根据我的理解)来使 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;
}
}
For last 2 weeks am trying to learn timer & interrupt & wrote a program (with my understanding) to blink LEDs on ATMEGA2560 but no matter what I do TCNT0 never increments & ISR() function never gets called. Where am I going wrong and how can I fix it? Here is my code:
#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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
全局变量delay_timer在中断和非中断代码之间共享。它应该被声明为
易失性
,因为该值可以在delay()
之外改变。如果您查看
delay()
生成的代码,您可能会发现在while
循环中旋转时,delay_timer 的值不会被重新读取。此外,
易失性
还不够。您有非中断代码和中断代码都写入同一个变量(delay_timer)。您需要保护对非中断代码中的变量的写入,那里存在竞争条件。简单/懒惰的方法是禁用中断和中断。在非中断代码中恢复它们。(至于设置中断和启动计时器,该信息应该在芯片的数据表中。通常这是更容易正确的部分,这是共享数据的内容。)
The global variable
delay_timer
is shared between interrupt and non-interrupt code. It should be declared asvolatile
as the value can change outside ofdelay()
.If you look at the generated code for
delay()
you'll probably see that the value of delay_timer isn't being re-read while spinning in thewhile
loop.Also,
volatile
isn't enough. You've got non-interrupt code and interrupt code both writing to the same variable (delay_timer). You need to protect writes to the variable in non-interrupt code, there's a race-condition there. The easy/lazy way is to disable interrupts & restore them in the non-interrupt code.(As for setting up your interrupts & starting your timer, that info should be in the chip's datasheet. Usually that's the part that's easier to get right, it's the shared data stuff that bites people.)
3-4 天前,我以稍微不同的方式编写了同一个程序。 LED 闪烁,但仍不确定这是否是使用计时器和计时器的正确方法。打断。任何人都可以看到这个&告诉我这是否正确?我通过阅读定时器、中断程序来编写这个程序。
如果这是正确的方法,那么我可以开始下一步的工作。
谢谢
3-4 days ago, I wrote the same program a little differently & got LEDs blinking but still not sure whether it is the correct way of using timer & interrupt. Could anyone please see this & tell me whether it's the correct or not? I managed to write this program by reading programs of timers, interrupts.
If it's the correct way then I can start working on next step.
Thanks
如果延迟函数中的 while 循环不执行任何操作,并且不会增加delay_timer,那么您将陷入无限循环:
If could be that your while loop in the delay function doesn't do anything and will not increment delay_timer so you are stuck in an endless loop: