Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 需要计时器的帮助吗_C_Embedded_Avr - Fatal编程技术网

C 需要计时器的帮助吗

C 需要计时器的帮助吗,c,embedded,avr,C,Embedded,Avr,在过去的两周里,我试图学习定时器和中断,并编写了一个程序(据我所知)使ATMEGA2560上的LED闪烁,但无论我做什么,TCNT0从不递增&ISR()函数从未被调用。我哪里出了问题?我该如何解决?这是我的密码: #include<avr/io.h> #include<avr/interrupt.h> #define READ_ATMEGA(ADDR) *((P_CHAR)(BASE_ADDR + ((ADDR) * ADDR_MULTIPLIER))) #define

在过去的两周里,我试图学习定时器和中断,并编写了一个程序(据我所知)使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;
  }
 }
#包括
#包括
#定义READ_ATMEGA(ADDR)*((P_CHAR)(BASE_ADDR+((ADDR)*ADDR_乘数)))
#定义WRITE_ATMEGA(ADDR,DATA)*((P_CHAR)(BASE_ADDR+((ADDR)*ADDR_乘数))=DATA
#定义基本地址0x20
无效初始定时器0\u ovf\u中断(无效);
无效定时器0\u中断\u isr(无效);
无效初始化\u端口(无效);
无效延迟(无符号整数无65毫秒中断);
无效属性(ISR)计时器0中断ISR(无效);
//#pragma中断处理程序计时器0中断isr:24
无符号整数延时定时器;
内部主(空)
{
初始化_端口();
初始化计时器0_ovf_中断();
延误(46);
返回0;
}
无效初始化\u端口(无效)
{
READ_ATMEGA(4)=0xff;
写入_ATMEGA(5,0x00);
}
无效延迟(无符号整数无65毫秒中断)
{
TCNT0=0x00;
延时定时器=0;

while(delay_timer如果延迟函数中的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!!
  } 
 } 
void延迟(无符号整数无65毫秒中断)
{ 
TCNT0=0x00;
延时定时器=0;

而(delay_timer全局变量
delay_timer
在中断和非中断代码之间共享。它应该声明为
volatile
,因为值可以在
delay()之外更改

如果查看为
delay()
生成的代码,您可能会看到,在
while
循环中旋转时,没有重新读取delay\u timer的值

另外,
volatile
是不够的。你有非中断代码和中断代码都在写入同一个变量(延迟计时器)。你需要在非中断代码中保护对变量的写入,那里有竞争条件。简单/懒惰的方法是禁用中断并在非中断代码中恢复它们


(至于设置中断和启动计时器,这些信息应该放在芯片的数据表中。通常这是比较容易正确的部分,而共享数据会让人感到不适。)

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 */
}
#包括
#包括
挥发性uint8_t INTR;
ISR(计时器0 OVF vect){
/*当计时器0溢出时调用此ISR*/
intrs++;
/*选通端口B.5-arduino板上的LED*/
如果(整数>=61){
PORTB=~PORTB;
intrs=0;
}
}
内部主(空){
TCCR0B=0x02;
/*启用计时器溢出中断*/
TIMSK0=0x01;
/*其他设置*/
DDRB=0xff;
TCNT0=0;
intrs=0;
/*启用中断*/
sei();
而(1)
;/*空循环*/
}
如果这是正确的方法,那么我可以开始下一步的工作


谢谢

FYI-要格式化一段代码,请选中它,然后单击
code
按钮;这个看起来像二进制数字的按钮。我真的吓坏了,因为我必须在明天之前提交这个项目&我仍然不能完全理解计时器和中断。(这不是我必须提交的实际项目)。我必须连接LED和开关,循环LED和按下开关时…使用定时器和中断点亮适当的LED,而不使用“avr”头文件。Dan..你在帖子中说的,我仍在考虑。我不熟悉Atmega/Arduino产品,所以我不能确定,但看起来你正在设置定时器频率(TCCROB)、启用定时器中断(TIMSK0)、重置计数器(TCNT0)和启用系统中断(sei)。这应该是让计时器正常工作所必需的一切。就您的原始程序而言,我不确定为什么它不工作,因为您似乎设置了所有相同的寄存器,再加上一些。也许在您的原始程序中,timer0\u中断\u isr与计时器溢出中断没有正确关联?