单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 644|回复: 2
收起左侧

单片机数码管计时和LED流水灯点亮 仿真和C语言程序

[复制链接]
紫色的云 发表于 2019-1-27 11:14 | 显示全部楼层 |阅读模式
这个程序是参照《手把手教你学51单片机》里的练习程序修改写的:

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png

单片机源程序如下:

  1.         /*数码管计时和LED流水灯*/
  2.         
  3.         #include <reg52.h>
  4.         sbit  WE1 = P2^0;          //        数码管位定义
  5.         sbit  WE2 = P2^1;
  6.         sbit  WE3 = P2^2;
  7.         sbit  WE4 = P2^3;
  8.         sbit  BEEP = P2^4;

  9.         
  10.         unsigned char  code LedChar[]={                        //数码管显示字符转换表
  11.                 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
  12.                 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
  13.         };
  14.         unsigned char LedBuff[]={       //                数码管显示缓冲区,初值0xFF确保启动时都不亮
  15.                 0XFF,0XFF,0XFF,0XFF,0XFF
  16.         };
  17.         unsigned char cnt200 = 0;         // 200ms计数
  18.         unsigned int cnt1000 = 0;                // 1000ms计数
  19.         
  20.         void ShowCount();                 // 秒计数显示函数
  21.         void FlowingLight();     // 流水灯实现函数
  22.          
  23.         void main ()
  24.         {
  25.                
  26.                 EA = 1 ;  //使能总中断
  27.                 TMOD = 0X01 ;  //设置T0为模式1
  28.                 TH0 = 0XFC ;   //为T0赋初值0xFC67,定时1ms
  29.                 TL0 = 0X67 ;         
  30.                 ET0 = 1 ;                 //使能T0中断
  31.                 TR0 = 1 ;                 //启动T0
  32.                
  33.                 while (1)
  34.                 {
  35.                              
  36.                                 if (cnt200 >= 200 )         // 200ms刷新一次流水灯
  37.                                 {
  38.                                         cnt200 = 0 ;
  39.                                         FlowingLight();
  40.                                        
  41.                                 }
  42.                                 if (cnt1000 >= 1000)                //1s刷新一次计数值
  43.                                 {
  44.                                         cnt1000 = 0 ;
  45.                                         ShowCount();
  46.                                 }
  47.                 }
  48.         }
  49.         
  50.         
  51.         /* 流水灯实现函数 */
  52.         
  53.         void FlowingLight()
  54.         {
  55.                 static unsigned char dir = 0;  //移位方向变量dir,用于控制移位的方向
  56.                 static unsigned char shift = 0X01 ;        //循环移位变量shift,并赋初值0x01
  57.                
  58.                 P1  = ~shift ;                //循环移位变量取反,控制8个LED
  59.                 if(dir == 0)                //移位方向变量为0时,左移
  60.                 {
  61.                         shift = shift << 1;                //循环移位变量左移1位
  62.                         if (shift == 0X80)                //左移到最左端后,改变移位方向
  63.                         {
  64.                           dir = 1 ;
  65.                         }
  66.                 }
  67.                 else                                                  //移位方向变量不为0时,右移
  68.                 {
  69.                         shift = shift >>1;        //循环移位变量右移1位
  70.                         if  (shift == 0X01)                //右移到最右端后,改变移位方向
  71.                         {
  72.                                 dir = 0 ;
  73.                         }
  74.                 }
  75.         }
  76.         
  77.         
  78.         /* 秒计数显示函数 */
  79.         
  80.                 void ShowCount()
  81.                 {
  82.                     char i ;          //循环变量
  83.                         unsigned char buf[4];         //中间转换缓冲区
  84.                         static unsigned long sec = 1;        //记录经过的秒数
  85.                         
  86.                         sec++ ;         //秒计数自加1
  87.                         buf[0] = sec%10 ;                 //将sec按十进制位从低到高依次提取到buf数组中
  88.                         buf[1] = sec/10%10 ;
  89.                         buf[2] = sec/100%10 ;
  90.                         buf[3] = sec/1000%10 ;
  91.                          //buf[4] =sec/10000%10 ;
  92.                         //buf[5] = sec/100000%10;
  93.                         
  94.                         for(i=3; i>=1; i--)   //从最高为开始,遇到0不显示,遇到非0退出循环
  95.                         {
  96.                                 if(buf[i] == 0)
  97.                                         LedBuff[i] = 0XFF ;
  98.                                 else
  99.                                         break;
  100.                         }
  101.                         for (;i>=0; i--)                 //将剩余的有效数字位如实转换
  102.                         {
  103.                           LedBuff[i] = LedChar[buf[i]] ;
  104.                         }
  105.                 }
  106.                         
  107.                
  108.         /* 定时器0中断服务函数 */
  109.                 void InterruptTimer0() interrupt 1
  110.                 {
  111.                         static unsigned char i =  0 ;                 //动态扫描的索引

  112.                         TH0 = 0XFC ;        //重新加载初值
  113.                         TL0 = 0X67 ;   
  114.                         cnt200++ ;
  115.                         cnt1000++ ;
  116.                         //以下代码完成数码管动态扫描刷新
  117.                         P0 = 0xFF;                           //显示消隐
  118.                         
  119.                         switch(i)
  120.                         {
  121.                                 case 0: WE1 = 0;WE2 = 0;WE3 = 0;WE4 = 1; P0=LedBuff[0];i++;break;
  122.                                 case 1: WE1 = 0;WE2 = 0;WE3 = 1;WE4 = 0; P0=LedBuff[1];i++; break;
  123.                                 case 2: WE1 = 0;WE2 = 1;WE3 = 0;WE4 = 0; P0=LedBuff[2];i++;break;
  124.                                 case 3: WE1 = 1;WE2 = 0;WE3 = 0;WE4 = 0; P0=LedBuff[3];i=0;break;
  125.                                 default: break;
  126.                         }
  127.                 }
复制代码

所有资料51hei提供下载:
LED SMG - 1.rar (77.37 KB, 下载次数: 9)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

站着说话不腰疼 发表于 2019-2-8 12:46 | 显示全部楼层
很不错,用定时器执行了两种功能同时运行的效果而不冲突

评分

参与人数 4黑币 +47 收起 理由
春风十里吹死你 + 10 很给力!
zhengchong60 + 15
shuisheng60 + 10
钻牛尖滴刘尖尖 + 12

查看全部评分

回复

使用道具 举报

喜乐 发表于 2019-4-7 22:55 来自手机 | 显示全部楼层
站着说话不腰疼 发表于 2019-2-8 12:46
很不错,用定时器执行了两种功能同时运行的效果而不冲突

运行了吗,怎么样
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51Hei单片机16群 联系QQ:125739409;技术交流QQ群7344883

Powered by 单片机教程网

快速回复 返回顶部 返回列表