这个程序是参照《手把手教你学51单片机》里的练习程序修改写的:
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- /*数码管计时和LED流水灯*/
-
- #include <reg52.h>
- sbit WE1 = P2^0; // 数码管位定义
- sbit WE2 = P2^1;
- sbit WE3 = P2^2;
- sbit WE4 = P2^3;
- sbit BEEP = P2^4;
-
- unsigned char code LedChar[]={ //数码管显示字符转换表
- 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
- 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
- };
- unsigned char LedBuff[]={ // 数码管显示缓冲区,初值0xFF确保启动时都不亮
- 0XFF,0XFF,0XFF,0XFF,0XFF
- };
- unsigned char cnt200 = 0; // 200ms计数
- unsigned int cnt1000 = 0; // 1000ms计数
-
- void ShowCount(); // 秒计数显示函数
- void FlowingLight(); // 流水灯实现函数
-
- void main ()
- {
-
- EA = 1 ; //使能总中断
- TMOD = 0X01 ; //设置T0为模式1
- TH0 = 0XFC ; //为T0赋初值0xFC67,定时1ms
- TL0 = 0X67 ;
- ET0 = 1 ; //使能T0中断
- TR0 = 1 ; //启动T0
-
- while (1)
- {
-
- if (cnt200 >= 200 ) // 200ms刷新一次流水灯
- {
- cnt200 = 0 ;
- FlowingLight();
-
- }
- if (cnt1000 >= 1000) //1s刷新一次计数值
- {
- cnt1000 = 0 ;
- ShowCount();
- }
- }
- }
-
-
- /* 流水灯实现函数 */
-
- void FlowingLight()
- {
- static unsigned char dir = 0; //移位方向变量dir,用于控制移位的方向
- static unsigned char shift = 0X01 ; //循环移位变量shift,并赋初值0x01
-
- P1 = ~shift ; //循环移位变量取反,控制8个LED
- if(dir == 0) //移位方向变量为0时,左移
- {
- shift = shift << 1; //循环移位变量左移1位
- if (shift == 0X80) //左移到最左端后,改变移位方向
- {
- dir = 1 ;
- }
- }
- else //移位方向变量不为0时,右移
- {
- shift = shift >>1; //循环移位变量右移1位
- if (shift == 0X01) //右移到最右端后,改变移位方向
- {
- dir = 0 ;
- }
- }
- }
-
-
- /* 秒计数显示函数 */
-
- void ShowCount()
- {
- char i ; //循环变量
- unsigned char buf[4]; //中间转换缓冲区
- static unsigned long sec = 1; //记录经过的秒数
-
- sec++ ; //秒计数自加1
- buf[0] = sec%10 ; //将sec按十进制位从低到高依次提取到buf数组中
- buf[1] = sec/10%10 ;
- buf[2] = sec/100%10 ;
- buf[3] = sec/1000%10 ;
- //buf[4] =sec/10000%10 ;
- //buf[5] = sec/100000%10;
-
- for(i=3; i>=1; i--) //从最高为开始,遇到0不显示,遇到非0退出循环
- {
- if(buf[i] == 0)
- LedBuff[i] = 0XFF ;
- else
- break;
- }
- for (;i>=0; i--) //将剩余的有效数字位如实转换
- {
- LedBuff[i] = LedChar[buf[i]] ;
- }
- }
-
-
- /* 定时器0中断服务函数 */
- void InterruptTimer0() interrupt 1
- {
- static unsigned char i = 0 ; //动态扫描的索引
- TH0 = 0XFC ; //重新加载初值
- TL0 = 0X67 ;
- cnt200++ ;
- cnt1000++ ;
- //以下代码完成数码管动态扫描刷新
- P0 = 0xFF; //显示消隐
-
- switch(i)
- {
- case 0: WE1 = 0;WE2 = 0;WE3 = 0;WE4 = 1; P0=LedBuff[0];i++;break;
- case 1: WE1 = 0;WE2 = 0;WE3 = 1;WE4 = 0; P0=LedBuff[1];i++; break;
- case 2: WE1 = 0;WE2 = 1;WE3 = 0;WE4 = 0; P0=LedBuff[2];i++;break;
- case 3: WE1 = 1;WE2 = 0;WE3 = 0;WE4 = 0; P0=LedBuff[3];i=0;break;
- default: break;
- }
- }
复制代码
所有资料51hei提供下载:
LED SMG - 1.rar
(77.37 KB, 下载次数: 31)
|