1、/*作者:夏国清,时间 2009/10/18 晚电路图说明:使用段锁存器和位锁存器分别控制数码管(共阴极) 的段选端和位选端,两个锁存器都使用 P0 口送数;并分别使用 P2.0 和 P2.1 来控制两锁存器的 LE 锁存控制端,LE1 时选通,LE=0 时锁存。程序功能:对数码管动态扫描来显示数 0 到 999,使用定时器 0 计时,使其半秒钟加数一次,到 999 加满自动清零重新计数。*/#include#define uint unsigned int#define uchar unsigned charuchar code d_table=0x3f , 0x06 , 0x5b , 0x
2、4f , 0x66 , 0x6d ,0x7d , 0x07 , 0x7f , 0x6f , 0x77 , 0x7c ,0x39 , 0x5e , 0x79 , 0x71 , 0x00;/共阴 0F 段码uchar code w_table=0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf;/1-6 位选码sbit duan=P20;sbit wei=P21;uchar count;/定时器产生中断时加 1uint num;/存放数码管显示的数void delay(uint);void init();/对定时器 0 初始化,并对 ge,shi,bai 初始化void disp
3、lay(uint);/显示数void main()init();/初始化定时器while(1)if(count=10)/半秒钟到加数一次count=0;num+;if(num=1000)/数满清零num=0;/display(num);如果把函数放在这里的话,那么不会出现数字显示不稳地功能的现象 ,因为这里有一个 while(1)循环,数码管是亮 5ms,灭 10ms 而已.而如果放在定时器中断处理函数中则是亮 5 ms,而灭 45ms.void delay(uint z)/晶振频率 12MHz 时,z=1 时延迟 1msuint i,j;for(i=z;i0;i-)for(j=110;j0;
4、j-);void init()EA=1;/开总中断允许ET0=1;/开定时器 0 允许TMOD=0x01;/定时器选择软件启动,工作方式为 1TH0=(65536-50000)/256;TL0=(65536-50000)%256;/给定时器赋初值,定时 50msTR0=1;/启动定时器 0 /当定时器计数值满 65536 的时候就触发/定时器 0 断 1. void display(uint m_num)/动态显示uchar ge,shi,bai;ge=m_num%10;shi=(m_num/10)%10;bai=m_num/100;/百位数P0=w_table1;wei=1;wei=0;P0
5、=d_tablebai;duan=1;duan=0;delay(5);/软件延时/十位数P0=w_table2;wei=1;wei=0;P0=d_tableshi;duan=1;duan=0;delay(5);/个位数P0=w_table3;wei=1;wei=0;P0=d_tablege;duan=1;duan=0;delay(5);void timer0_50ms() interrupt 1 / 每 50ms 执行一次定时器中断处理函数( 因为定时器中断处理函数中重新装初值了) TH0=(65536-50000)/256;TL0=(65536-50000)%256;/当计数值满 65536
6、 的时候就产生定时器 0 的中断,进入定时器中断 1。就是重/装初值 ,count+,还有执行一次 diaplay.count+;/定时时间计数display(num);/在数码管上显示当前 num 值 /把函数放在这里可以会出现数字不稳定的现象,因为在 50ms 内执行一次中断处理程序,所以每个数码管只是亮 5ms,count0123456789 10(count=0,num+ )123456789 10(count=0,num+)123456789display 函数 执行的间隔时间是 50ms,这个十分精确。可以用数轴来帮助理解。(在初始化函数中设定好定时器的初始值) 定时器中断就是当计数值满 65536 的时候就进入定时器中断处理函数。个位十位百位;消影;先把要送的数据送到门口,然后再开门,接着关门.定时器中断的应用,以及理解.动态显示的理解 24hz