找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机做简易电子表程序及Proteus仿真

[复制链接]
ID:760565 发表于 2020-5-25 12:53 | 显示全部楼层 |阅读模式
这周我做了一个用51单片机的时钟,下面介绍一下具体实用功能 。仿真一开始,时间显示的是20:30:00    mmexport1590381120338.jpg
当按下第二个开关时  即可调节"分"如图,按一下便调整为31分。
mmexport1590381122557.jpg
再按一下第二个键,此时可调节"时"如图。
mmexport1590381125521.jpg
按一下以后,时间为21时。
mmexport1590381127960.jpg
代码放在附件,有需要可以下载。

单片机源程序如下:
  1. #include <reg51.h>

  2. sbit key1 = P1^0;
  3. bit flag1s = 0;
  4. bit KeySta = 1;
  5. unsigned char hour = 20;
  6. unsigned char minute = 30;
  7. unsigned char second = 00;
  8. unsigned char mode = 0;
  9. void FreshTime();
  10. void TimeInit();
  11. void IntInit();
  12. void InitLedBuff();
  13. void keyscan();
  14.   
  15. unsigned char code LedChar[] = {  //共阴数码管显示字符转换表
  16.     0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  17.     0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00};
  18. unsigned char LedBuff[6] = {  //数码管显示缓冲区
  19.     0xff,0xff,0xff,0xff,0xff,0xff};

  20. void main()
  21. {
  22.   TimeInit();
  23.   IntInit();
  24.   InitLedBuff();
  25.   while(1)//显示内容处理
  26.   {
  27.     if(flag1s&&!mode) //时间显示模式
  28.     {
  29.       flag1s = 0;
  30.       FreshTime();
  31.     }
  32.     else if(mode == 1)  //校准分钟
  33.     {
  34.       LedBuff[0] = 17;
  35.       LedBuff[1] = 17;
  36.       LedBuff[4] = 17;
  37.       LedBuff[5] = 17;//不显示
  38.       LedBuff[2] = minute/10;
  39.       LedBuff[3] = minute%10;
  40.     }
  41.     else if(mode == 2)  //校准小时
  42.     {
  43.       LedBuff[2] = 17;
  44.       LedBuff[3] = 17;
  45.       LedBuff[4] = 17;
  46.       LedBuff[5] = 17;//不显示
  47.       LedBuff[0] = hour/10;
  48.       LedBuff[1] = hour%10;
  49.     }
  50.     else if(mode == 3)  //校准完成重新显示
  51.     {
  52.       InitLedBuff();
  53.       mode = 0;
  54.     }
  55.     keyscan();
  56.   }
  57. }

  58. void InitLedBuff()//初始化时间到显示缓冲区
  59. {
  60.   LedBuff[0] = hour/10;
  61.   LedBuff[1] = hour%10;
  62.   LedBuff[2] = minute/10;
  63.   LedBuff[3] = minute%10;
  64.   LedBuff[4] = second/10;
  65.   LedBuff[5] = second%10;
  66. }
  67. void FreshTime()//刷新时间到显示缓冲区
  68. {
  69.   second++;
  70.   if(second == 60)//进位
  71.   {
  72.     second = 0;
  73.     minute++;
  74.     LedBuff[2] = minute/10;
  75.     LedBuff[3] = minute%10;
  76.     if(minute == 60)//进位
  77.     {
  78.       minute = 0;
  79.       hour++;
  80.       if(hour == 24)
  81.         hour = 0;
  82.       LedBuff[0] = hour/10;
  83.       LedBuff[1] = hour%10;
  84.     }  
  85.   }
  86.   LedBuff[4] = second/10;
  87.   LedBuff[5] = second%10;
  88. }

  89. void TimeInit()//定时器初始化
  90. {
  91.   TMOD = 0X11;    //设置定时器为模式1
  92.   TL0 = 0xB0;
  93.   TH0 = 0x3C;     //定时初值 50ms
  94.   TL1 = 0x18;                //
  95.         TH1 = 0xFC;                //定时初值 1ms
  96.   TR0 = 1;    //定时器0开始计时
  97.   TR1 = 1;    //定时器1开始计时
  98.   ET1 = 1;    //使能定时器1
  99.   ET0 = 1;    //使能定时器0
  100.   PT0 = 1;    //提高计时准确性,提高定时器0中断优先级
  101.   EA = 1;     //打开总中断
  102. }
  103. void IntInit()//外部中断初始化
  104. {
  105.   IT0 = 1;     //下降沿触发
  106.   EX0 = 1;    //使能外部中断0
  107. }

  108. void keyscan() //按键扫描及处理
  109. {
  110.   static bit backup = 1;
  111.   if (KeySta != backup)  //当前值与前次值不相等说明此时按键有动作
  112.   {
  113.     if (backup == 0)   //如果前次值为0,则说明当前是弹起动作
  114.     {
  115.       if(mode == 1)   //校准分钟时,分钟加一
  116.       {
  117.         minute++;
  118.         if(minute==60)
  119.           minute = 0;
  120.       }
  121.       else if(mode == 2)    //校准小时,小时加一
  122.       {
  123.         hour++;
  124.         if(hour==24)
  125.           hour = 0;
  126.       }
  127.     }
  128.     backup = KeySta;   //更新备份为当前值,以备进行下次比较
  129.   }
  130. }
  131. void Int0() interrupt 0
  132. {
  133.   mode++;
  134.   if(mode == 4)
  135.   {
  136.     mode = 0;
  137.   }
  138. }
  139. void Ledfresh() //数码管显示刷新
  140. {
  141.   static unsigned char i = 0;
  142.   switch(i)
  143.   {
  144.     case 0 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[i]];i++;break;
  145.     case 1 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[i]];i++;break;
  146.     case 2 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[i]];i++;break;
  147.     case 3 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[i]];i++;break;
  148.     case 4 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[i]];i++;break;
  149.     case 5 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[i]];i=0;break;
  150.   }
  151. }
  152. void Time0() interrupt 1 //12MHz 50ms
  153. {
  154.   static unsigned char n = 0;
  155.   TL0 = 0xB0;
  156.   TH0 = 0x3C;
  157.   n++;
  158.   if(n==20)
  159.   {
  160.     n=0;
  161.     flag1s = 1;//1s标志位
  162.   }
  163. }

  164. void Time1() interrupt 3  //12MHz 1ms
  165. {
  166.   static unsigned char keybuff = 0xff;
  167.   TL1 = 0x18;                //
  168.         TH1 = 0xFC;                //定时初值 1ms
  169.   Ledfresh();
  170.   keybuff = (keybuff<<1)|key1;
  171.   if (keybuff == 0x00)
  172.   {   //连续8次扫描值都为0,即16ms内都只检测到按下状态时,可认为按键已按下
  173.       KeySta = 0;
  174.   }
  175.   else if (keybuff == 0xFF)
  176.   {   //连续8次扫描值都为1,即16ms内都只检测到弹起状态时,可认为按键已弹起
  177.       KeySta = 1;
  178.   }
  179.   else
  180.   {}  //其它情况则说明按键状态尚未稳定,则不对KeySta变量值进行更新
  181. }
复制代码
请自行画图

评分

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

查看全部评分

回复

使用道具 举报

ID:762381 发表于 2020-5-27 12:41 | 显示全部楼层
请问有没有Proteus的工程文件啊
回复

使用道具 举报

ID:1033811 发表于 2022-6-13 18:16 来自手机 | 显示全部楼层
你这个图不全啊
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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