找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6150|回复: 2
打印 上一主题 下一主题
收起左侧

51单片机8位数码管秒表程序(按一下 开始计时 再按一下 停止计时 按第三下 清0)

[复制链接]
跳转到指定楼层
楼主
ID:318620 发表于 2018-5-6 15:29 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
K1按键 按一下 开始计时 再按一下 停止计时  按第三下 清0

单片机程序如下
  1. #include <reg51.h>
  2. #include <intrins.h>

  3. unsigned char data dis_digit;
  4. unsigned char key_s, key_v;

  5. unsigned char code dis_code[11]={0xc0,0xf9,0xa4,0xb0,        // 0, 1, 2, 3
  6.                                 0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};// 4, 5, 6, 7, 8, 9, off
  7. unsigned char dis_buf[8];                // 显示缓冲区
  8. unsigned char sec_bcd[8];                 // 秒计数值, BCD码
  9. unsigned char dis_index;                //
  10. unsigned char key_times;                // K1 按下次数                                //

  11. void clr_time();        
  12. void update_disbuf();
  13. bit        scan_key();
  14. void proc_key();
  15. void delayms(unsigned char ms);

  16. sbit        K1 = P3^2;


  17. void main(void)
  18. {
  19.         P0 = 0xff;
  20.         P2 = 0xff;
  21.         TMOD = 0x11;                // 定时器0, 1工作模式1, 16位定时方式
  22.         TH1 = 0xdc;
  23.         TL1 = 0;

  24.         TH0 = 0xFC;
  25.         TL0 = 0x17;
  26.         
  27.         clr_time();                        //
  28.                                           
  29.         dis_digit = 0x7f;                // 初始显示P20口数码管
  30.         dis_index = 0;                        //
  31.         
  32.         key_times = 0;
  33.         key_v = 0x01;
  34.         
  35.         IE = 0x8a;                                // 使能timer0, timer1中断
  36.         
  37.         TR0 = 1;
  38.         TR1 = 0;
  39.         while(1)
  40.         {
  41.                 if(scan_key())
  42.                 {
  43.                         delayms(10);
  44.                         if(scan_key())
  45.                         {
  46.                                 key_v = key_s;
  47.                                 proc_key();
  48.                         }
  49.                 }
  50.                
  51.         }
  52. }

  53. void clr_time()
  54. {
  55.         sec_bcd[0] = 0x0;
  56.         sec_bcd[1] = 0x0;
  57.         sec_bcd[2] = 0x0;
  58.         sec_bcd[3] = 0x0;
  59.         sec_bcd[4] = 0x0;
  60.         sec_bcd[5] = 0x0;
  61.         sec_bcd[6] = 0x0;
  62.         sec_bcd[7] = 0x0;   
  63.         
  64.         update_disbuf();
  65.         
  66. }

  67. bit scan_key()
  68. {
  69.         key_s = 0x00;
  70.         key_s |= K1;
  71.         return(key_s ^ key_v);        
  72. }

  73. void proc_key()
  74. {
  75.         if((key_v & 0x01) == 0)
  76.         {
  77.                 key_times++;
  78.                 if(key_times == 1)
  79.                 {
  80.                         TR1 = 1;
  81.                 }
  82.                 else if(key_times == 2)
  83.                 {        
  84.                         TR1 = 0;
  85.                 }
  86.                 else
  87.                 {
  88.                         clr_time();
  89.                         key_times = 0;
  90.                 }
  91.                
  92.         }
  93. }

  94. void timer0() interrupt 1
  95. // 定时器0中断服务程序, 用于数码管的动态扫描
  96. // dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
  97. // dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
  98. //                                选通P2.0口数码管
  99. // dis_buf   --- 显于缓冲区基地址        
  100. {
  101.         TH0 = 0xFC;
  102.         TL0 = 0x17;
  103.         
  104.         P2 = 0xff;                                                        // 先关闭所有数码管
  105.         P0 = dis_buf[dis_index];                        // 显示代码传送到P0口
  106.         P2 = dis_digit;                                                //

  107.         dis_digit = _cror_(dis_digit,1);        // 位选通值右移(P30<-P37), 下次中断时选通下一位数码管
  108.         dis_index++;                                                //
  109.                                        
  110.         dis_index &= 0x07;                        // 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描
  111. }

  112. void timer1() interrupt 3
  113. //
  114. {        
  115.         unsigned char i;
  116.         TH1 |= 0xdc;
  117.         for(i = 0; i < 8; i++)
  118.         {
  119.                 sec_bcd[i]++;                        // 低位加1
  120.                 if(sec_bcd[i] < 10)                // 如果低位满10则向高位进1
  121.                         break;                        // 低位未满10
  122.                 sec_bcd[i] = 0;                        // 低位满10清0
  123.         }
  124.         update_disbuf();                        // 更新显示缓冲区
  125. }

  126. void update_disbuf()
  127. // 更新显示缓冲区
  128. {
  129.         dis_buf[0] = dis_code[sec_bcd[0]];
  130.         dis_buf[1] = dis_code[sec_bcd[1]];
  131.         dis_buf[2] = dis_code[sec_bcd[2]] & 0x7f;        // 加上小数点
  132.         dis_buf[3] = dis_code[sec_bcd[3]];
  133.         dis_buf[4] = dis_code[sec_bcd[4]];
  134.         dis_buf[5] = dis_code[sec_bcd[5]];
  135.         dis_buf[6] = dis_code[sec_bcd[6]];
  136.         dis_buf[7] = dis_code[sec_bcd[7]];
  137. }

  138. void delayms(unsigned char ms)        
  139. // 延时子程序
  140. {                                                
  141.         unsigned char i;
  142.         while(ms--)
  143.         {
  144.                 for(i = 0; i < 120; i++);
  145.         }
  146. }
复制代码




8位数码管秒表程序.rar

15 KB, 下载次数: 57, 下载积分: 黑币 -5

评分

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

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶1 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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