標(biāo)題: 帶詳細(xì)注釋的51單片機(jī)電子秒表程序 [打印本頁(yè)]

作者: 帥氣的小哥哥    時(shí)間: 2021-12-16 10:39
標(biāo)題: 帶詳細(xì)注釋的51單片機(jī)電子秒表程序
基于單片機(jī)電子秒表設(shè)計(jì)的一些程序編程
  1. //包含頭文件
  2. #include <reg52.h>
  3. //宏定義
  4. #define uc unsigned char
  5. #define ui unsigned int

  6. void display();        //聲明顯示函數(shù)

  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};        //數(shù)字對(duì)應(yīng)顯示碼表
  9. uc code tab1[]={0x7f,0x64,0xbd,0xf5,0xe6,0xf3,0xfb,0x65,0xff,0xf7};                //帶小數(shù)點(diǎn)的數(shù)字碼表
  10. uc code index[]={0x7f,0xbf,0xdf,0xef};  //每位數(shù)字對(duì)應(yīng)數(shù)碼管顯示位置

  11. uc num[8];                 //num【0】-num【3】是計(jì)時(shí)用數(shù)組,4-7是范圍計(jì)時(shí)用(設(shè)置10s,計(jì)時(shí)到10秒報(bào)警)
  12. uc val[10][4];        //存儲(chǔ)的記錄 [10]為記錄序列,[4]為每組記錄中的數(shù)字
  13. char val_index;        //記錄序列標(biāo)志位  
  14. uc set_index,ok_flag,timing; //set_index:設(shè)置的位。ok_flag:設(shè)置狀態(tài)標(biāo)志,=0時(shí)是正常狀態(tài),=1是設(shè)置狀態(tài)。timing:顯示狀態(tài)標(biāo)志:=0正常顯示,=1閃爍設(shè)置位
  15. bit mode=1;                //運(yùn)行模式,1為正向計(jì)數(shù),0為反向計(jì)數(shù)。
  16. bit fin_flag=0;        //完成標(biāo)志位,當(dāng)反向計(jì)數(shù)結(jié)束時(shí),此位為高電平,觸發(fā)蜂鳴器     
  17. bit set_shan;
  18. uc count,beep_stop;

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

  20. sbit key1=P3^3;         //功能1:開(kāi)始&停止計(jì)時(shí);//功能2:倒計(jì)時(shí)數(shù)值設(shè)置位加1(倒計(jì)時(shí)數(shù)值設(shè)置模式下操作閃爍位);
  21. sbit key2=P3^4;         //功能1:記錄時(shí)間點(diǎn)(計(jì)時(shí)進(jìn)行中按下記錄,停止計(jì)時(shí)后按下回看);//功能2:倒計(jì)時(shí)數(shù)值設(shè)置位切換(倒計(jì)時(shí)數(shù)值設(shè)置模式下操作);
  22. sbit key3=P3^5;         //功能:計(jì)時(shí)值歸零(隨時(shí)操作)
  23. sbit key4=P3^6;         //功能:正/倒計(jì)時(shí)模式切換(計(jì)時(shí)停止?fàn)顟B(tài)下操作)
  24. sbit key5=P3^7;         //功能:倒計(jì)時(shí)數(shù)值設(shè)置模式(計(jì)時(shí)停止?fàn)顟B(tài)下操作)

  25. void delay(ui z) //延時(shí)函數(shù),大約延時(shí)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;                   //定時(shí)器0賦初值
  36.         TH1=0x3c;
  37.         TL1=0xb0;                   //定時(shí)器1賦初值
  38.         ET1=1;                           //允許中斷
  39.         TR1=1;                           //定時(shí)開(kāi)關(guān)
  40.         ET0=1;
  41.         TR0=0;
  42.         EA=1;                           //中斷總開(kāi)關(guān)

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

  45. void clr()                                //清除函數(shù)
  46. {
  47.         uc i;
  48.         for(i=0;i<8;i++)        //將存儲(chǔ)的數(shù)據(jù)清零        for循環(huán)8次
  49.         num[i]=0;
  50. }

  51. void setup()                        //設(shè)置函數(shù)
  52. {
  53.         ok_flag=0xff;                //ok_flag賦值1
  54.         set_index=0;                //設(shè)置位置0
  55.         while (ok_flag)                //進(jìn)入設(shè)置后,循環(huán),直到ok_flag為0
  56.         {
  57.                  display();                //調(diào)用顯示函數(shù)
  58.                 if(key1==0)          //按動(dòng)KEY1設(shè)置值加1   
  59.                 {
  60.                         delay(5); //延時(shí)去抖
  61.                         if(key1==0)//再次判斷按鍵是否按下
  62.                         {
  63.                                 if ((set_index==0)|(set_index==2)|(set_index==4)|(set_index==6))//設(shè)置個(gè)位數(shù)據(jù)時(shí)
  64.                                 {
  65.                                         num[set_index]++;                                                                                        //數(shù)據(jù)加
  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))//設(shè)置十位數(shù)據(jù)時(shí)
  70.                                 {
  71.                                         num[set_index]++;                                                                                        //數(shù)據(jù)加
  72.                                         if(num[set_index]==6)                                                                                //加到6時(shí)
  73.                                         num[set_index]=0;                                                                                        //清零
  74.                                 }
  75.                                 while(!key1) display();                                                                                        //按鍵釋放
  76.                         }
  77.                 }

  78.                 if(key2==0)         //按動(dòng)KEY2設(shè)置位置加1  
  79.                 {
  80.                         delay(5);//延時(shí)去抖
  81.                         if(key2==0)//再次按下按鍵
  82.                         {
  83.                                 set_index++; //設(shè)置位置加
  84.                                 if(set_index==8)//設(shè)置位置加到最后一位時(shí)
  85.                                 {
  86.                                         set_index=0;//設(shè)置位置到0
  87.                                 }
  88.                                 while(!key2) display();//按鍵釋放
  89.                         }
  90.                 }
  91.                 if(key5==0)         //按動(dòng)KEY5設(shè)置結(jié)束  
  92.                 {
  93.                         delay(5);//延時(shí)去抖
  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)) //如果計(jì)時(shí)時(shí)間上限設(shè)置數(shù)據(jù)不都為0時(shí)
  98.                                 {
  99.                                         num[0]=0;num[1]=0;num[2]=0;num[3]=0;mode=1;//將正計(jì)時(shí)時(shí)間清零,Mode置1,正計(jì)時(shí)
  100.                                 }
  101.                                 else if((num[4]==0)&&(num[5]==0)&&(num[6]==0)&&(num[7]==0))//如果計(jì)時(shí)時(shí)間上限設(shè)置數(shù)據(jù)都為0時(shí)
  102.                                 {
  103.                                         if((num[0]==0)&&(num[1]==0)&&(num[2]==0)&&(num[3]==0))//判斷計(jì)時(shí)時(shí)間都為0
  104.                                         mode=1;                                                                                                  //正計(jì)時(shí)模式
  105.                                         else if((num[0]!=0)||(num[1]!=0)||(num[2]!=0)||(num[3]!=0))//判斷計(jì)時(shí)時(shí)間有不為0
  106.                                         mode=0;                                                                                                           //倒計(jì)時(shí)模式
  107.                                 }
  108.                                 while(!key5) display();         //按鍵去抖
  109.                         }  
  110.                 }
  111.         }
  112. }

  113. void display()
  114. {
  115.         uc i;
  116.         if(ok_flag!=0xff)                   //不是設(shè)置狀態(tài)時(shí)
  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)                //如果是第二位時(shí)
  125.                                 P0=tab1[num[i]];//顯示有小數(shù)點(diǎn)的數(shù)據(jù)
  126.                                 else                        //不是第二位時(shí)
  127.                                 P0=tab[num[i]];        //正常顯示數(shù)據(jù)
  128.                                  delay(2);                //修改此參數(shù)可修改刷新頻率  
  129.                         }
  130.                 }
  131.                 else                                         //設(shè)置時(shí) 閃爍相應(yīng)位
  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);                //修改此參數(shù)可修改刷新頻率  
  141.                                 }
  142.                         }
  143.                         else if(set_shan==1)
  144.                         {                                                           //點(diǎn)亮顯示
  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);                //修改此參數(shù)可修改刷新頻率  
  154.                                 }
  155.                         }
  156.                 }
  157.         }
  158.         else        //設(shè)置時(shí)
  159.         {
  160.                 if(set_shan==0)
  161.                 {
  162.                         if(set_index==0)                                //設(shè)置不同位時(shí),閃爍相應(yīng)位
  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);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  194.                                                 P0=0xff;
  195.                                         }
  196.                                         else
  197.                                         {
  198.                                                 P2=index[i];
  199.                                                 P0=tab[num[i]];
  200.                                                  delay(2);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  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);                //修改此參數(shù)可修改刷新頻率  
  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)) //計(jì)時(shí)時(shí)間到0時(shí)
  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])) //設(shè)置上限模式時(shí),計(jì)時(shí)時(shí)間到
  384.                 {
  385.                         timing=1;
  386.                         TR0=0;                  //停止計(jì)時(shí),并閃爍顯示
  387.                 }                                                                                                                  
  388.         }
  389. }

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

  395.         while(1)
  396.         {
  397.                 display();                 //刷屏顯示數(shù)碼管  
  398.                 alarm();
  399.                 if(key1==0)          //開(kāi)始/暫停按鈕
  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)//當(dāng)在運(yùn)行中按下記錄鍵則存儲(chǔ)記錄   
  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];           //低位存儲(chǔ)的數(shù)據(jù)向高位移一位
  420.                                                 }
  421.                                         }
  422.                                         for(h=0;h<4;h++)
  423.                                         {
  424.                                                 val[9][h]=num[h];//將當(dāng)前時(shí)間存儲(chǔ)
  425.                                         }
  426.                                 }
  427.                                 else//在停止?fàn)顟B(tài)下按下記錄鍵查看記錄,按動(dòng)一次序列遞減一次,即查看上一次記錄   
  428.                                 {
  429.                                         for(h=0;h<4;h++)
  430.                                         num[h]=val[val_index][h];//將當(dāng)前時(shí)間存儲(chǔ)
  431.                                         val_index--;
  432.                                         if(val_index<0)
  433.                                         val_index=9;
  434.                                 }
  435.                                 while(!key2) display();                //按鍵釋放
  436.                         }
  437.                 }
  438.                 if(key3==0)          //復(fù)位按鈕
  439.                 {
  440.                         delay(5);
  441.                         if(key3==0)
  442.                         {
  443.                                 clr();                                         //將數(shù)據(jù)清零
  444.                                 while(!key3) display();         //按鍵釋放
  445.                         }  
  446.                 }
  447.                 if((key4==0)&&(TR0==0))          //模式選擇按鈕,僅在停止?fàn)顟B(tài)下有效   
  448.                 {
  449.                         delay(5);
  450.                         if(key4==0)
  451.                         {
  452.                                 mode=~mode;                                 //正計(jì)時(shí)倒計(jì)時(shí)切換
  453.                                 while(!key4) display();
  454.                         }  
  455.                 }
  456.                 if((key5==0)&&(TR0==0))          //時(shí)間設(shè)置,僅在停止?fàn)顟B(tài)下有效
  457.                 {
  458.                         delay(5);
  459.                         if(key5==0)
  460.                         {
  461.                                 while(!key5)
  462.                                 display();
  463.                                 setup();                   //調(diào)用設(shè)置函數(shù)
  464.                         }
  465.                 }
  466.         }
  467. }  


  468. void T0_time() interrupt 1
  469. {
  470.         uc m;
  471.         TH0=0x3c;          //12M晶振定時(shí)器定時(shí)時(shí)間為50ms
  472.         TL0=0xb0;
  473.         m++;
  474.         if(m==20)
  475.         {
  476.                 m=0;
  477.                 if(mode==1)          //正向計(jì)數(shù)
  478.                 {
  479.                         num[0]++;                                  //秒個(gè)位加
  480.                         if(num[0]==10)                          //秒個(gè)位加到10時(shí)
  481.                         {
  482.                                 num[0]=0;                          //個(gè)位清零
  483.                                 num[1]++;                          //秒十位加
  484.                                 if(num[1]==6)                  //秒十位加到6時(shí)
  485.                                 {
  486.                                         num[1]=0;                  //秒十位清零
  487.                                         num[2]++;                  //分個(gè)位加
  488.                                         if(num[2]==10)          //分個(gè)位加到10時(shí)
  489.                                         {
  490.                                                  num[2]=0;          //分個(gè)位清零
  491.                                                 num[3]++;          //分十位加
  492.                                                 if(num[3]==10)//分十位加到10時(shí)
  493.                                                 num[3]=0;          //分十位清零
  494.                                         }
  495.                                 }
  496.                         }
  497.                 }
  498.                 else
  499.                 {
  500.                         num[0]--;                                         //秒個(gè)位減
  501.                         if(num[0]>9)                                 //小于0時(shí),該數(shù)字的最高位會(huì)變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                        //定時(shí)器1的工作函數(shù)
  527. {
  528.         uc shan,beep_stop;
  529.         TH1=0x3c;
  530.         TL1=0xb0;                                                          //重新賦初值
  531.         shan++;                                                                  //閃爍變量加
  532.         if(shan==10)                                                  //加到10時(shí)(500ms)
  533.         {
  534.                 shan=0;                                                          //清零
  535.                 set_shan=~set_shan;                                  //設(shè)置的閃爍變量取反
  536.                 if((fin_flag)||(timing))         //當(dāng)反向計(jì)數(shù)完成時(shí)  或計(jì)時(shí)時(shí)間到時(shí)   
  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. }
復(fù)制代碼


作者: sanye涼風(fēng)    時(shí)間: 2022-4-13 15:33
有沒(méi)有仿真圖片可以圖文來(lái)講解一下嗎?




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1