需要计时器方面的帮助

发布于 2024-09-30 19:44:52 字数 1315 浏览 4 评论 0原文

在过去的两周里,我试图学习计时器和定时器。中断&编写了一个程序(根据我的理解)来使 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

So要识趣 2024-10-07 19:44:52

全局变量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 as volatile as the value can change outside of delay().

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 the while 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.)

赠佳期 2024-10-07 19:44:52

3-4 天前,我以稍微不同的方式编写了同一个程序。 LED 闪烁,但仍不确定这是否是使用计时器和计时器的正确方法。打断。任何人都可以看到这个&告诉我这是否正确?我通过阅读定时器、中断程序来编写这个程序。

#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 */
}

如果这是正确的方法,那么我可以开始下一步的工作。

谢谢

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.

#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 */
}

If it's the correct way then I can start working on next step.

Thanks

九命猫 2024-10-07 19:44:52

如果延迟函数中的 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!!
  } 
 } 

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:

void delay(unsigned int no_65_5ms_interrupts) 
 { 
  TCNT0 = 0x00; 
  delay_timer = 0; 
  while(delay_timer <= no_65_5ms_interrupts) 
  { 
   ; //Nothing is happening here!!
  } 
 } 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文