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 , 0x4f , 0x66 , 0x6d ,0
2、x7d , 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 display(uint);/显示数void main()in
3、it();/初始化定时器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;j-);void init()EA=1;/开总中断允许ET0=1;/开定时器
4、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=d_tablebai;duan=1;duan=0;delay(5);/软件延时/十位数P0=w
5、_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的时候就产生定时器0的中断,进入定时器中断1。就是重/装初值 ,count+,还有执行一次diaplay
6、.count+;/定时时间计数display(num);/在数码管上显示当前num值/把函数放在这里可以会出现数字不稳定的现象,因为在50ms内执行一次中断处理程序,所以每个数码管只是亮5ms,count0123456789 10(count=0,num+)123456789 10(count=0,num+)123456789display函数 执行的间隔时间是50ms,这个十分精确。可以用数轴来帮助理解。(在初始化函数中设定好定时器的初始值) 定时器中断就是当计数值满65536的时候就进入定时器中断处理函数。个位十位百位;消影;先把要送的数据送到门口,然后再开门,接着关门.定时器中断的应用,以及理解.动态显示的理解 24hz