找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2073|回复: 1
收起左侧

带详细注释的51单片机电子秒表程序

[复制链接]
ID:993062 发表于 2021-12-16 10:39 | 显示全部楼层 |阅读模式
基于单片机电子秒表设计的一些程序编程
  1. //包含头文件
  2. #include <reg52.h>
  3. //宏定义
  4. #define uc unsigned char
  5. #define ui unsigned int

  6. void display();        //声明显示函数

  7. //                                0         1    2    3    4    5    6    7    8    9
  8. uc code tab[]={0x5f,0x44,0x9d,0xd5,0xc6,0xd3,0xdb,0x45,0xdf,0xd7,0x00};        //数字对应显示码表
  9. uc code tab1[]={0x7f,0x64,0xbd,0xf5,0xe6,0xf3,0xfb,0x65,0xff,0xf7};                //带小数点的数字码表
  10. uc code index[]={0x7f,0xbf,0xdf,0xef};  //每位数字对应数码管显示位置

  11. uc num[8];                 //num【0】-num【3】是计时用数组,4-7是范围计时用(设置10s,计时到10秒报警)
  12. uc val[10][4];        //存储的记录 [10]为记录序列,[4]为每组记录中的数字
  13. char val_index;        //记录序列标志位  
  14. uc set_index,ok_flag,timing; //set_index:设置的位。ok_flag:设置状态标志,=0时是正常状态,=1是设置状态。timing:显示状态标志:=0正常显示,=1闪烁设置位
  15. bit mode=1;                //运行模式,1为正向计数,0为反向计数。
  16. bit fin_flag=0;        //完成标志位,当反向计数结束时,此位为高电平,触发蜂鸣器     
  17. bit set_shan;
  18. uc count,beep_stop;

  19. sbit beep=P3^2;         //蜂鸣器

  20. sbit key1=P3^3;         //功能1:开始&停止计时;//功能2:倒计时数值设置位加1(倒计时数值设置模式下操作闪烁位);
  21. sbit key2=P3^4;         //功能1:记录时间点(计时进行中按下记录,停止计时后按下回看);//功能2:倒计时数值设置位切换(倒计时数值设置模式下操作);
  22. sbit key3=P3^5;         //功能:计时值归零(随时操作)
  23. sbit key4=P3^6;         //功能:正/倒计时模式切换(计时停止状态下操作)
  24. sbit key5=P3^7;         //功能:倒计时数值设置模式(计时停止状态下操作)

  25. void delay(ui z) //延时函数,大约延时z ms
  26. {
  27.         ui i,j;
  28.         for(i=0;i<z;i++)
  29.         for(j=0;j<121;j++);
  30. }

  31. void init()                                //初始化
  32. {
  33.         TMOD=0x11;                        //工作方式
  34.         TH0=0x3c;
  35.         TL0=0xb0;                   //定时器0赋初值
  36.         TH1=0x3c;
  37.         TL1=0xb0;                   //定时器1赋初值
  38.         ET1=1;                           //允许中断
  39.         TR1=1;                           //定时开关
  40.         ET0=1;
  41.         TR0=0;
  42.         EA=1;                           //中断总开关

  43.         val_index=0;           //清零
  44. }

  45. void clr()                                //清除函数
  46. {
  47.         uc i;
  48.         for(i=0;i<8;i++)        //将存储的数据清零        for循环8次
  49.         num[i]=0;
  50. }

  51. void setup()                        //设置函数
  52. {
  53.         ok_flag=0xff;                //ok_flag赋值1
  54.         set_index=0;                //设置位置0
  55.         while (ok_flag)                //进入设置后,循环,直到ok_flag为0
  56.         {
  57.                  display();                //调用显示函数
  58.                 if(key1==0)          //按动KEY1设置值加1   
  59.                 {
  60.                         delay(5); //延时去抖
  61.                         if(key1==0)//再次判断按键是否按下
  62.                         {
  63.                                 if ((set_index==0)|(set_index==2)|(set_index==4)|(set_index==6))//设置个位数据时
  64.                                 {
  65.                                         num[set_index]++;                                                                                        //数据加
  66.                                         if(num[set_index]==10)                                                                                //加到10
  67.                                         num[set_index]=0;                                                                                         //清零
  68.                                 }
  69.                                 else if((set_index==1)|(set_index==3)|(set_index==5)|(set_index==7))//设置十位数据时
  70.                                 {
  71.                                         num[set_index]++;                                                                                        //数据加
  72.                                         if(num[set_index]==6)                                                                                //加到6时
  73.                                         num[set_index]=0;                                                                                        //清零
  74.                                 }
  75.                                 while(!key1) display();                                                                                        //按键释放
  76.                         }
  77.                 }

  78.                 if(key2==0)         //按动KEY2设置位置加1  
  79.                 {
  80.                         delay(5);//延时去抖
  81.                         if(key2==0)//再次按下按键
  82.                         {
  83.                                 set_index++; //设置位置加
  84.                                 if(set_index==8)//设置位置加到最后一位时
  85.                                 {
  86.                                         set_index=0;//设置位置到0
  87.                                 }
  88.                                 while(!key2) display();//按键释放
  89.                         }
  90.                 }
  91.                 if(key5==0)         //按动KEY5设置结束  
  92.                 {
  93.                         delay(5);//延时去抖
  94.                         if(key5==0)//再次判断按键是否按下
  95.                         {
  96.                                 ok_flag=0x00;//ok_flag清零
  97.                                 if((num[4]!=0)||(num[5]!=0)||(num[6]!=0)||(num[7]!=0)) //如果计时时间上限设置数据不都为0时
  98.                                 {
  99.                                         num[0]=0;num[1]=0;num[2]=0;num[3]=0;mode=1;//将正计时时间清零,Mode置1,正计时
  100.                                 }
  101.                                 else if((num[4]==0)&&(num[5]==0)&&(num[6]==0)&&(num[7]==0))//如果计时时间上限设置数据都为0时
  102.                                 {
  103.                                         if((num[0]==0)&&(num[1]==0)&&(num[2]==0)&&(num[3]==0))//判断计时时间都为0
  104.                                         mode=1;                                                                                                  //正计时模式
  105.                                         else if((num[0]!=0)||(num[1]!=0)||(num[2]!=0)||(num[3]!=0))//判断计时时间有不为0
  106.                                         mode=0;                                                                                                           //倒计时模式
  107.                                 }
  108.                                 while(!key5) display();         //按键去抖
  109.                         }  
  110.                 }
  111.         }
  112. }

  113. void display()
  114. {
  115.         uc i;
  116.         if(ok_flag!=0xff)                   //不是设置状态时
  117.         {
  118.                 if(timing==0)                  
  119.                 {
  120.                         for(i=0;i<4;i++)
  121.                         {
  122.                                 P0=0xff;                //清显示
  123.                                 P2=index[i];        //选中位
  124.                                 if(i==2)                //如果是第二位时
  125.                                 P0=tab1[num[i]];//显示有小数点的数据
  126.                                 else                        //不是第二位时
  127.                                 P0=tab[num[i]];        //正常显示数据
  128.                                  delay(2);                //修改此参数可修改刷新频率  
  129.                         }
  130.                 }
  131.                 else                                         //设置时 闪烁相应位
  132.                 {
  133.                         if(set_shan==0)
  134.                         {
  135.                                 for(i=0;i<4;i++)
  136.                                 {
  137.                                         P0=0xff;
  138.                                         P2=index[i];
  139.                                         P0=tab[10];                 //熄灭
  140.                                          delay(2);                //修改此参数可修改刷新频率  
  141.                                 }
  142.                         }
  143.                         else if(set_shan==1)
  144.                         {                                                           //点亮显示
  145.                                 for(i=0;i<4;i++)
  146.                                 {
  147.                                         P0=0xff;
  148.                                         P2=index[i];
  149.                                         if(i==2)
  150.                                         P0=tab1[num[i]];
  151.                                         else
  152.                                         P0=tab[num[i]];
  153.                                          delay(2);                //修改此参数可修改刷新频率  
  154.                                 }
  155.                         }
  156.                 }
  157.         }
  158.         else        //设置时
  159.         {
  160.                 if(set_shan==0)
  161.                 {
  162.                         if(set_index==0)                                //设置不同位时,闪烁相应位
  163.                         {
  164.                                 for(i=0;i<4;i++)
  165.                                 {
  166.                                         if(i==0)
  167.                                         {
  168.                                                 P2=index[0];
  169.                                                 P0=tab[10];
  170.                                                  delay(2);                //修改此参数可修改刷新频率  
  171.                                                 P0=0xff;
  172.                                         }
  173.                                         else
  174.                                         {
  175.                                                 P2=index[i];
  176.                                                 if(i==2)
  177.                                                 P0=tab1[num[i]];
  178.                                                 else
  179.                                                 P0=tab[num[i]];
  180.                                                  delay(2);                //修改此参数可修改刷新频率  
  181.                                                 P0=0xff;
  182.                                         }
  183.                                 }
  184.                         }
  185.                         else if(set_index==1)
  186.                         {
  187.                                 for (i=0;i<4;i++)
  188.                                 {
  189.                                         if(i==1)
  190.                                         {
  191.                                                 P2=index[1];
  192.                                                 P0=tab[10];
  193.                                                  delay(2);                //修改此参数可修改刷新频率  
  194.                                                 P0=0xff;
  195.                                         }
  196.                                         else
  197.                                         {
  198.                                                 P2=index[i];
  199.                                                 P0=tab[num[i]];
  200.                                                  delay(2);                //修改此参数可修改刷新频率  
  201.                                                 P0=0xff;
  202.                                         }
  203.                                 }
  204.                         }
  205.                         else if(set_index==2)
  206.                         {
  207.                                 for (i=0;i<4;i++)
  208.                                 {
  209.                                         if(i==2)
  210.                                         {
  211.                                                 P2=index[2];
  212.                                                 P0=tab[10];
  213.                                                  delay(2);                //修改此参数可修改刷新频率  
  214.                                                 P0=0xff;
  215.                                         }
  216.                                         else
  217.                                         {
  218.                                                 P2=index[i];
  219.                                                 if(i==2)
  220.                                                 P0=tab1[num[i]];
  221.                                                 else
  222.                                                 P0=tab[num[i]];
  223.                                                  delay(2);                //修改此参数可修改刷新频率  
  224.                                                 P0=0xff;
  225.                                         }
  226.                                 }
  227.                         }
  228.                         else if(set_index==3)
  229.                         {
  230.                                 for (i=0;i<4;i++)
  231.                                 {
  232.                                         if(i==3)
  233.                                         {
  234.                                                 P2=index[3];
  235.                                                 P0=tab[10];
  236.                                                  delay(2);                //修改此参数可修改刷新频率  
  237.                                                 P0=0xff;
  238.                                         }
  239.                                         else
  240.                                         {
  241.                                                 P2=index[i];
  242.                                                 if(i==2)
  243.                                                 P0=tab1[num[i]];
  244.                                                 else
  245.                                                 P0=tab[num[i]];
  246.                                                  delay(2);                //修改此参数可修改刷新频率  
  247.                                                 P0=0xff;
  248.                                         }
  249.                                 }
  250.                         }
  251.                         else if(set_index==4)
  252.                         {
  253.                                 for (i=4;i<8;i++)
  254.                                 {
  255.                                         if(i==4)
  256.                                         {
  257.                                                 P2=index[0];
  258.                                                 P0=tab[10];
  259.                                                  delay(2);                //修改此参数可修改刷新频率  
  260.                                                 P0=0xff;
  261.                                         }
  262.                                         else
  263.                                         {
  264.                                                 P2=index[i-4];
  265.                                                 if(i==6)
  266.                                                 P0=tab1[num[i]];
  267.                                                 else
  268.                                                 P0=tab[num[i]];
  269.                                                  delay(2);                //修改此参数可修改刷新频率  
  270.                                                 P0=0xff;
  271.                                         }
  272.                                 }
  273.                         }
  274.                         else if(set_index==5)
  275.                         {
  276.                                 for (i=4;i<8;i++)
  277.                                 {
  278.                                         if(i==5)
  279.                                         {
  280.                                                 P2=index[1];
  281.                                                 P0=tab[10];
  282.                                                  delay(2);                //修改此参数可修改刷新频率  
  283.                                                 P0=0xff;
  284.                                         }
  285.                                         else
  286.                                         {
  287.                                                 P2=index[i-4];
  288.                                                 if(i==6)
  289.                                                 P0=tab1[num[i]];
  290.                                                 else
  291.                                                 P0=tab[num[i]];
  292.                                                  delay(2);                //修改此参数可修改刷新频率  
  293.                                                 P0=0xff;
  294.                                         }
  295.                                 }
  296.                         }
  297.                         else if(set_index==6)
  298.                         {
  299.                                 for (i=4;i<8;i++)
  300.                                 {
  301.                                         if(i==6)
  302.                                         {
  303.                                                 P2=index[2];
  304.                                                 P0=tab[10];
  305.                                                  delay(2);                //修改此参数可修改刷新频率  
  306.                                                 P0=0xff;
  307.                                         }
  308.                                         else
  309.                                         {
  310.                                                 P2=index[i-4];
  311.                                                 if(i==6)
  312.                                                 P0=tab1[num[i]];
  313.                                                 else
  314.                                                 P0=tab[num[i]];
  315.                                                  delay(2);                //修改此参数可修改刷新频率  
  316.                                                 P0=0xff;
  317.                                         }
  318.                                 }
  319.                         }
  320.                         else if(set_index==7)
  321.                         {
  322.                                 for (i=4;i<8;i++)
  323.                                 {
  324.                                         if(i==7)
  325.                                         {
  326.                                                 P2=index[3];
  327.                                                 P0=tab[10];
  328.                                                  delay(2);                //修改此参数可修改刷新频率  
  329.                                                 P0=0xff;
  330.                                         }
  331.                                         else
  332.                                         {
  333.                                                 P2=index[i-4];
  334.                                                 if(i==6)
  335.                                                 P0=tab1[num[i]];
  336.                                                 else
  337.                                                 P0=tab[num[i]];
  338.                                                  delay(2);                //修改此参数可修改刷新频率  
  339.                                                 P0=0xff;
  340.                                         }
  341.                                 }
  342.                         }
  343.                 }
  344.                 else
  345.                 {
  346.                         if(set_index<4)
  347.                         {
  348.                                 for (i=0;i<4;i++)
  349.                                 {
  350.                                         P2=index[i];
  351.                                         if(i==2)
  352.                                         P0=tab1[num[i]];
  353.                                         else
  354.                                         P0=tab[num[i]];
  355.                                          delay(2);                //修改此参数可修改刷新频率  
  356.                                         P0=0xff;
  357.                                 }
  358.                         }
  359.                         else
  360.                         {
  361.                                 for (i=4;i<8;i++)
  362.                                 {
  363.                                         P2=index[i-4];
  364.                                         if(i==6)
  365.                                         P0=tab1[num[i]];
  366.                                         else
  367.                                         P0=tab[num[i]];
  368.                                          delay(2);                //修改此参数可修改刷新频率  
  369.                                         P0=0xff;
  370.                                 }
  371.                         }
  372.                 }
  373.         }
  374. }

  375. void alarm()
  376. {
  377.         if((num[4]==0)&&(num[5]==0)&&(num[6]==0)&&(num[7]==0)) //计时时间到0时
  378.         {
  379.                 timing=0;
  380.         }                                                                                                         
  381.         else
  382.         {
  383.                 if((num[4]==num[0])&&(num[6]==num[2])&&(num[5]==num[1])&&(num[7]==num[3])) //设置上限模式时,计时时间到
  384.                 {
  385.                         timing=1;
  386.                         TR0=0;                  //停止计时,并闪烁显示
  387.                 }                                                                                                                  
  388.         }
  389. }

  390. void main()
  391. {
  392.         uc h,g,k;
  393.         init();
  394.         clr();

  395.         while(1)
  396.         {
  397.                 display();                 //刷屏显示数码管  
  398.                 alarm();
  399.                 if(key1==0)          //开始/暂停按钮
  400.                 {
  401.                         delay(5);
  402.                         if(key1==0)
  403.                         {
  404.                                 TR0=~TR0;
  405.                                 while(!key1) display();
  406.                         }
  407.                 }
  408.                 if(key2==0)         //记录按钮
  409.                 {
  410.                         delay(5);
  411.                         if(key2==0)
  412.                         {
  413.                                 if(TR0==1)//当在运行中按下记录键则存储记录   
  414.                                 {
  415.                                         for(g=1;g<10;g++)
  416.                                         {
  417.                                                 for(k=0;k<4;k++)
  418.                                                 {
  419.                                                         val[g-1][k]=val[g][k];           //低位存储的数据向高位移一位
  420.                                                 }
  421.                                         }
  422.                                         for(h=0;h<4;h++)
  423.                                         {
  424.                                                 val[9][h]=num[h];//将当前时间存储
  425.                                         }
  426.                                 }
  427.                                 else//在停止状态下按下记录键查看记录,按动一次序列递减一次,即查看上一次记录   
  428.                                 {
  429.                                         for(h=0;h<4;h++)
  430.                                         num[h]=val[val_index][h];//将当前时间存储
  431.                                         val_index--;
  432.                                         if(val_index<0)
  433.                                         val_index=9;
  434.                                 }
  435.                                 while(!key2) display();                //按键释放
  436.                         }
  437.                 }
  438.                 if(key3==0)          //复位按钮
  439.                 {
  440.                         delay(5);
  441.                         if(key3==0)
  442.                         {
  443.                                 clr();                                         //将数据清零
  444.                                 while(!key3) display();         //按键释放
  445.                         }  
  446.                 }
  447.                 if((key4==0)&&(TR0==0))          //模式选择按钮,仅在停止状态下有效   
  448.                 {
  449.                         delay(5);
  450.                         if(key4==0)
  451.                         {
  452.                                 mode=~mode;                                 //正计时倒计时切换
  453.                                 while(!key4) display();
  454.                         }  
  455.                 }
  456.                 if((key5==0)&&(TR0==0))          //时间设置,仅在停止状态下有效
  457.                 {
  458.                         delay(5);
  459.                         if(key5==0)
  460.                         {
  461.                                 while(!key5)
  462.                                 display();
  463.                                 setup();                   //调用设置函数
  464.                         }
  465.                 }
  466.         }
  467. }  


  468. void T0_time() interrupt 1
  469. {
  470.         uc m;
  471.         TH0=0x3c;          //12M晶振定时器定时时间为50ms
  472.         TL0=0xb0;
  473.         m++;
  474.         if(m==20)
  475.         {
  476.                 m=0;
  477.                 if(mode==1)          //正向计数
  478.                 {
  479.                         num[0]++;                                  //秒个位加
  480.                         if(num[0]==10)                          //秒个位加到10时
  481.                         {
  482.                                 num[0]=0;                          //个位清零
  483.                                 num[1]++;                          //秒十位加
  484.                                 if(num[1]==6)                  //秒十位加到6时
  485.                                 {
  486.                                         num[1]=0;                  //秒十位清零
  487.                                         num[2]++;                  //分个位加
  488.                                         if(num[2]==10)          //分个位加到10时
  489.                                         {
  490.                                                  num[2]=0;          //分个位清零
  491.                                                 num[3]++;          //分十位加
  492.                                                 if(num[3]==10)//分十位加到10时
  493.                                                 num[3]=0;          //分十位清零
  494.                                         }
  495.                                 }
  496.                         }
  497.                 }
  498.                 else
  499.                 {
  500.                         num[0]--;                                         //秒个位减
  501.                         if(num[0]>9)                                 //小于0时,该数字的最高位会变1,所以判断是否大于9        下同
  502.                         {
  503.                                 num[0]=9;
  504.                                 num[1]--;
  505.                                 if(num[1]>5)
  506.                                 {
  507.                                         num[1]=5;
  508.                                         num[2]--;
  509.                                         if(num[2]>9)
  510.                                         {
  511.                                                  num[2]=9;
  512.                                                 num[3]--;
  513.                                                 if(num[3]>9)
  514.                                                 {
  515.                                                         num[3]=0;
  516.                                                         TR0=0;
  517.                                                         fin_flag=1;
  518.                                                         clr();
  519.                                                 }
  520.                                         }
  521.                                 }
  522.                         }
  523.                 }
  524.         }
  525. }

  526. void T1_time() interrupt 3                        //定时器1的工作函数
  527. {
  528.         uc shan,beep_stop;
  529.         TH1=0x3c;
  530.         TL1=0xb0;                                                          //重新赋初值
  531.         shan++;                                                                  //闪烁变量加
  532.         if(shan==10)                                                  //加到10时(500ms)
  533.         {
  534.                 shan=0;                                                          //清零
  535.                 set_shan=~set_shan;                                  //设置的闪烁变量取反
  536.                 if((fin_flag)||(timing))         //当反向计数完成时  或计时时间到时   
  537.                 {
  538.                         beep_stop++;                        
  539.                         beep=~beep;                                 //蜂鸣器闪烁响
  540.                         if(beep_stop==10)                 //蜂鸣器响五声停止
  541.                         {
  542.                                 fin_flag=0;
  543.                                 timing=0;
  544.                                 num[4]=0;num[5]=0;num[6]=0;num[7]=0;
  545.                                 beep_stop=0;
  546.                                 beep=1;
  547.                         }
  548.                 }
  549.         }
  550. }
复制代码

评分

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

查看全部评分

回复

使用道具 举报

ID:1016637 发表于 2022-4-13 15:33 | 显示全部楼层
有没有仿真图片可以图文来讲解一下吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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