找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机精确到0.1秒可回看记录的秒表程序

[复制链接]
跳转到指定楼层
楼主
基于51单片机精确到0.1秒可回看记录的秒表程序
可回看计时记录

下载:
miaobiao5.rar (20.28 KB, 下载次数: 21)

  1. #include <reg51.h>
  2. unsigned char code leddata[]= {  0x3F,  0x06,  0x5B,  0x4F, //0 1 2 3
  3.                                  0x66,  0x6D,  0x7D,  0x07,  //4 5 6 7
  4.                                  0x7F,  0x6F,  0x77,  0x7C,  //8 9 A b
  5.                                  0x39,  0x5E,  0x79,  0x71,  //c d E F
  6.                                  0x76,  0x38,  0x37,  0x3E,  //H L n u
  7.                                  0x73,  0x5C,  0x40,  0x00,  //P o - 清屏
  8.                               };
  9. #define digitData P0          //数码管数据
  10. #define startBtn    0       //按键值
  11. #define resetBtn    1
  12. #define counterBtn  2
  13. sbit DX = P2^6;//段选
  14. sbit WX = P2^7;//位选
  15. sbit kaiShi = P3^4;//开始、暂停按键
  16. sbit chongZhi = P3^5;//重置按键
  17. sbit jiCi = P3^6;//计次、记录查看按键
  18. unsigned int recode[8] = {0};//记录数据
  19. unsigned char recodeNum = 0;//记录数据值位置
  20. unsigned char showRe = 0; //查看哪项记录值
  21. unsigned int times = 0; //当前计时时间
  22. unsigned int saveTimes = 0;//暂停查看记录时保存时间数据
  23. unsigned char counter = 0;//定时器次数,构成100ms
  24. unsigned char shuanXi = 0,sXW = 1;//刷新数码管
  25. unsigned char runState = 0;//0表示停止,1表示运行
  26. unsigned char keyTemp[3]= {0}; //按键按下状态持续时间

  27. //六位数码管显示 dat:显示内容下标 wei:哪一个数码管
  28. void display(unsigned char dat,unsigned char wei)//wei 1-6
  29. {
  30.     digitData = 0xff; //关掉显示 消除重影
  31.     WX = 1;
  32.     WX = 0;
  33.     //如果不先关闭显示,不论先段选还位选(位选前关闭都不行),而且必须先送段选,再送位选,
  34.     //先位选则当前位置会显示上次残留段选数据 导致重影
  35.     digitData = leddata[dat];//段选
  36.     DX = 1;
  37.     DX = 0;
  38.     digitData = ~(1<<(wei-1));//位选
  39.     WX = 1;
  40.     WX = 0;
  41. }
  42. //判断当前按键
  43. unsigned char scanKey()
  44. {
  45.     P3 = 0x70;//k1 k2 k3给高

  46.     if(kaiShi==0)//开始键按下
  47.     {
  48.         if(keyTemp[0] == 0) keyTemp[0]=1 ;//按键按下 开始记延时
  49.     }
  50.     else
  51.     {
  52.         keyTemp[0] = 0; //有抖动重新延时
  53.     }

  54.     if(chongZhi==0)
  55.     {
  56.         if(keyTemp[1] == 0) keyTemp[1]=1 ;
  57.     }
  58.     else
  59.     {
  60.         keyTemp[1] = 0;
  61.     }

  62.     if(jiCi==0)
  63.     {
  64.         if(keyTemp[2] == 0) keyTemp[2]=1 ;
  65.     }
  66.     else
  67.     {
  68.         keyTemp[2] = 0;
  69.     }
  70.     if(keyTemp[0]>5) return startBtn;  //5次 5*2ms 超过10ms 消抖
  71.     if(keyTemp[1]>5) return resetBtn;
  72.     if(keyTemp[2]>5) return counterBtn;
  73.     return 0xFF; //没有按键
  74. }
  75. void Timer0Init(void)        //2毫秒@11.0592MHz
  76. {
  77.     //AUXR &= 0x7F;        //定时器时钟12T模式
  78.     TMOD &= 0xF0;        //设置定时器模式
  79.     TMOD |= 0x01;        //设置定时器模式
  80.     TL0 = 0xCF;        //设置定时初值
  81.     TH0 = 0xF8;        //设置定时初值
  82.     TF0 = 0;        //清除TF0标志
  83.     TR0 = 1;        //定时器0开始计时
  84.     ET0 = 1;         //运行定时器0中断
  85.     EA = 1;         //开全局中断
  86. }

  87. void main()
  88. {
  89.     unsigned char keyValue = 0xFF,keyT = 0xFF;//按键值
  90.     unsigned char weiXian[6] = {0,22,0,0,22,0};
  91.     Timer0Init();
  92.     while(1)
  93.     {
  94.         if(shuanXi)//刷新sXW位置的数码管中
  95.         {
  96.             if(times>=6000) //十分钟
  97.             {
  98.                 times = 0;
  99.             }
  100.             weiXian[0] = times/600;//分钟
  101.             weiXian[2] = times/10%60/10;
  102.             weiXian[3] = times/10%60%10;
  103.             weiXian[5] = times%10;
  104.             display(weiXian[sXW-1],sXW);
  105.             shuanXi = 0;
  106.         }
  107.         keyT = scanKey();//当前按键值
  108.         if(keyT!=keyValue)//当前按键值与上次按键值不同,则表示按键状态改变。需要做按键处理
  109.         {
  110.             keyValue = keyT;
  111.             //P1 = keyValue;
  112.             switch(keyValue)//按键处理
  113.             {
  114.             case startBtn://开始暂停按下
  115.                 //if(runState) TR0 = 0; else TR0 = 1;
  116.                 //runState ? (TR0 = 0) : (TR0 = 1);
  117.                 runState = !runState;//改变状态
  118.                 if(runState)//恢复时间
  119.                 {
  120.                     times = saveTimes;
  121.                 }
  122.                 else//保存时间
  123.                 {
  124.                     saveTimes = times;
  125.                 }

  126.                 break;
  127.             case resetBtn:  //重置
  128.                 if(!runState)
  129.                 {
  130.                     times = 0;
  131.                     saveTimes = 0;
  132.                     recodeNum = 0;
  133.                     P1 = 0xFF;
  134.                 }
  135.                 break;
  136.             case counterBtn:  //记录或查看记录
  137.                 if(runState)//运行时,记录
  138.                 {
  139.                     if(recodeNum<8)
  140.                     {
  141.                         recode[recodeNum++] = times;
  142.                         P1 = (0xFF<<recodeNum);//点亮recodeNum个灯
  143.                     }
  144.                 }
  145.                 else//暂停查看记录
  146.                 {
  147.                     P1 = (0xFF ^(1 << showRe));//点亮showRe位置的灯
  148.                     times = recode[showRe++];
  149.                     if(showRe >= recodeNum)
  150.                     {
  151.                         showRe = 0;//循环查看记录
  152.                     }
  153.                 }
  154.                 break;
  155.             }
  156.         }
  157.     }

  158. }
  159. void T0_2ms() interrupt 1
  160. {
  161.     //定时器重新赋初值 放在终端服务程序最开始有利于降低定时中断误差
  162.     TL0 = 0xCF;        //设置定时初值
  163.     TH0 = 0xF8;        //设置定时初值
  164.     if(++counter>=50 && runState)//运行状态下100ms 加0.1秒
  165.     {
  166.         times++;
  167.         counter = 0;
  168.     }
  169.     shuanXi = 1;//数码管周期刷新
  170.     if(++sXW>6) //六位循环刷新
  171.     {
  172.         sXW = 1;
  173.     }
  174.     if(keyTemp[0]) keyTemp[0]++;//按键持续
  175.     if(keyTemp[1]) keyTemp[1]++;//按键持续
  176.     if(keyTemp[2]) keyTemp[2]++;//按键持续

  177. }
复制代码


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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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