这个程序写了好几次,但每次重写的时候,感觉又无从下手。
在写这个程序时,先把每个寄存器及其功能又全部熟记和理解,这个程序是凭自己的理解写出来的,每个步骤该干嘛,该解决哪些问题。
#include "reg51.h" typedef unsigned int u16; // 数字 0 ~ 9 unsigned char digit[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; /** 实现每隔3秒,数码管数字0~9 **/ /** 要设置中断,需要先解决一下问题: (1) 要设置什么中断? 中断C51有5个: T1 T0 TI/RI INT0 INT1 定时器/计数器中断设置: (1) 要使用哪个中断?T0 ? T1 由TMOD寄存器和TCON寄存器共同决定: GATE=0 && (TR0=1 || TR1=1) GATE=0 && (TR0=1 || TR1=1) && 外部中断(INT0/INT1) (2) 使用哪个工作方式 由TMOD寄存器的M1和M1决定 (共4中方式可选择) (3) 定时或记数多少? 即确定初始值 由时钟频率 和 要计数的值决定. 12个时钟周期为一个机器周期 (4) 打开中断: a) 打开某个定时器中断 b) 打开总中断 (5) 启动定时器工作 (6) 设置中断函数 **/ void init() { // GATE: 0 ==> 哪个定时器有TCON的TRX决定 // C/T : 0 ==> 为定时器模式 // M0M1: 01 ==> 工作方式1 为16位定时器/计数器 TMOD = 0x01; TH0 = 0x3C; // 初始值 定时50ms中断一次 TL0 = 0xB0; ET0 = 1; // 打开t0中断 EA = 1; // 打开总中断 TR0 = 1; // 启动定时器1开始工作 (这个应该放到中断全部设置完毕后,作为一个开关再设置) } u16 index = 0; // 显示数字 void Show() { P0 = digit[index]; } void main() { init(); while(1){ Show(); } } // 中断处理函数 void timer0() interrupt 1 { static u16 num = 0; // 一次中断50ms, 60次中断为3s num++; if(60 == num) { num = 0; index++; if(index == 10) index = 0; } }