路过的avr单片机高手进来救命啊

来源:百度知道 编辑:UC知道 时间:2024/09/21 01:31:09
我写的一个关于avr单片机定时器0中断的程序,如下
#include <avr/io.h>
#include <avr/interrupt.h>
const unsigned char LedNum[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x80,0xf8,0x80,0x90,0xff,0xbf};
#define uchar unsigned char
static uchar g_bCount=0; //中断计数器
static uchar timer=0;
//T/C0 中断例程
SIGNAL(SIG_OVERFLOW0)
{
// 产生中断周期 T = 256 * 1024 / 4MHz
if(++g_bCount >14) //中断15 次约一秒
{
timer++;
g_bCount=0;
}
}

int main(void)
{
DDRD=0X10;
DDRC=0xff;
PORTD=0X01;
TCNT0=0; // T/C0 开始值
TCCR0=5; // 预分频 ck/1024 ,计数允许
TIMSK=_BV(TOIE0);
sei();
while(1)
{
PORTC=LedNum[timer];
}
}
不知道为什么执行中断时,就回不到while循环里去了,用单步调试看到中断执行后,就没执行了,过一段时间在继续执行中断,也就是中断正常,但执行后,回不到while里面了,怎么回事?

//代码修改如下

#include <avr/io.h>
#include <avr/interrupt.h>
const unsigned char LedNum[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x80,0xf8,0x80,0x90,0xff,0xbf};
#define uchar unsigned char
volatile uchar g_bCount=0; //中断计数器
volatile uchar timer=0;

//T/C0 中断
SIGNAL(SIG_OVERFLOW0)
{
// 产生中断周期 T = 256 * 1024 / 4MHz
if(++g_bCount >14) //中断15 次约一秒
{
timer++;
g_bCount=0;
}

TCNT0=0; // T/C0 重载计数初值0

}

int main(void)
{
DDRD=0X10;
DDRC=0xff;
PORTD=0X01;
TCNT0=0; // T/C0 开始值
TCCR0=5; // 预分频 ck/1024 ,计数允许
TIMSK=_BV(TOIE0);
sei();
while(1)
{
PORTC=LedNum[timer];
asm("nop");//空等待操作,可加也可以去掉
}
}

补充:对中断需要修改的全局变量,推荐用volatile修饰,用static有时候也会被优化掉,另外计数初值要重新加载,即使已经计数溢出
推荐你用计数器1定时计数,这样可直接定时1秒钟
定时器1初始化代码如下:
TCCR1B = 0x00; //停止timer1
TCNT1 = 0