如果是用C去写的话,像汇编一样,开中断就行了。位置一般就在MAIN 之前的。
//晶振频率22.1184MHz
#include<at89x52.h>
#define TIMER0H 0x4c
#define TIMER0L 0x00
#define TIMER0_RUN TR0=1
#define SECOND_OVERFLOW 40
#define SEG_PORT P0
#define DISPLAY_DIG1 P1&=0xf0;P1|=0x01
unsigned char g_CurrentDigit=0; //当前显示的数字
void timer() interrupt 1
{
static unsigned char s_Count = 0;
TH0 = TIMER0H; //重置定时器初值
TL0 = TIMER0L;
//每次进入中断服务程序,TH0和 TL0 的值都
TIMER0_RUN; //定时器运行,开始下一
if(s_Count != SECOND_OVERFLOW)
{ //未到整秒,把 sCount 值加1
s_Count++;
}
else
{ //到整秒,s_Count归 0,更新把当前显示
s_Count = 0;
if(g_CurrentDigit != 9)
{
g_CurrentDigit++;
}
else
{
g_CurrentDigit = 0;
}
}
return;
}
void Initial(void) //初始化
{
IE = 0x82; //仅允许Timer0 中断
TMOD = 0x01; //Timer0 使用工作方式 1(16位) ,定时器
TH0 = TIMER0H; //设置定时器初值
TL0 = TIMER0L;
TIMER0_RUN; //定时器开始运行
DISPLAY_DIG1;
}
void main()
{
unsigned char code SEG_CODE[]
= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
Initial();
while(1)
{
SEG_PORT = SEG_CODE[g_CurrentDigit]; //显示当前的数字
//当timer0溢出时,单片机响应 timer0 中断,调用 timer 函数,
//每40 次调用当前显示的数字加 1
}
}
程序分析:
程序中主程序做的事只是在死循环中反复显示当前的数字,每产生一次中断,程序就跳
转到中断服务函数 timer()中进行相应的更新。
这里中断服务函数 timer()有别于普通 C函数的地方是在声明中多了“interrupt 1” ,说明
这个函数是中断号为 1的中断服务函数。各个中断对应的中断号如表 3.8所示。
这个程序需要初始化的东西比较多, 我们把这些初始化语句都放在了初始化函数 Initial()
中,这也是程序初始化很常见的做法。我们还第一次用到了静态变量和全局变量。全局变量
是中断处理函数与外界程序进行参数传递的唯一途径,因此在单片机程序中全局变量的使
用频率要比普通的 C 语言程序高。尽管如此,由于全局变量的使用会影响程序的结构化,
所以在可以不使用全局变量的地方,还是要避免使用全局变量。在程序中,为了把全局变
量与静态变量跟普通变量区别开来,我们在变量前分别加了小写 g_和小写 s_以示区别。
IE 寄存器中的使能位和C中的中断号 中断源
0 外部中断0
1 定时器0溢出
2 外部中断1
3 定时器1溢出
4 串行口中断
5
定时器2溢出(仅在S52、
C52中有此中断源)
好了,以上是我找的一个实例,希望对你有帮助!
温馨提示:内容为网友见解,仅供参考