找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3185|回復(fù): 2
收起左側(cè)

單片機(jī)74HC595數(shù)碼管菜單系統(tǒng)程序Proteus仿真(高位為0不顯示)

[復(fù)制鏈接]
ID:448556 發(fā)表于 2021-11-8 10:18 | 顯示全部樓層 |閱讀模式
基于吳堅鴻與祁緒電子程序修改
51hei.gif 51hei截圖_20211108101636.png 51hei截圖_20211108101752.png

單片機(jī)源程序如下:
  1. #include "REG52.H"
  2. #define const_voice_short 40 //蜂鳴器短叫的持續(xù)時間
  3. #define const_key_time1 20 //按鍵去抖動延時的時間
  4. #define const_key_time2 20 //按鍵去抖動延時的時間
  5. #define const_key_time3 20 //按鍵去抖動延時的時間
  6. void initial_myself();
  7. void initial_peripheral();
  8. void delay_short(unsigned int uiDelayshort);
  9. void delay_long(unsigned int uiDelaylong);
  10. void dig_hc595_drive(unsigned char ucDigStatusTemp16_09,unsigned char ucDigStatusTemp08_01);
  11. void display_drive();//顯示數(shù)碼管字模的驅(qū)動函數(shù)
  12. void display_service();//顯示的窗口菜單服務(wù)程序

  13. void T0_time();//定時中斷函數(shù)
  14. void key_service();//按鍵服務(wù)的應(yīng)用程序
  15. void key_scan();//按鍵掃描函數(shù) 放在定時中斷里
  16. sbit key_sr1=P1^0;
  17. sbit key_sr2=P1^1;
  18. sbit key_sr3=P1^2;
  19. sbit beep_dr=P2^7;//蜂鳴器的驅(qū)動 IO 口
  20. sbit led_dr=P3^5;//作為中途暫停指示燈 亮的時候表示中途暫停
  21. sbit dig_hc595_sh_dr=P2^3; //數(shù)碼管的 74HC595 程序
  22. sbit dig_hc595_st_dr=P2^4;
  23. sbit dig_hc595_ds_dr=P2^5;
  24. sbit hc595_sh_dr=P2^0;//LED 燈的 74HC595 程序
  25. sbit hc595_st_dr=P2^1;
  26. sbit hc595_ds_dr=P2^2;
  27. unsigned char ucKeySec=0;//被觸發(fā)的按鍵編號
  28. unsigned int uiKeyTimeCnt1=0;//按鍵去抖動延時計數(shù)器
  29. unsigned char ucKeyLock1=0;//按鍵觸發(fā)后自鎖的變量標(biāo)志
  30. unsigned int uiKeyTimeCnt2=0;//按鍵去抖動延時計數(shù)器
  31. unsigned char ucKeyLock2=0;//按鍵觸發(fā)后自鎖的變量標(biāo)志
  32. unsigned int uiKeyTimeCnt3=0;//按鍵去抖動延時計數(shù)器
  33. unsigned char ucKeyLock3=0;//按鍵觸發(fā)后自鎖的變量標(biāo)志
  34. unsigned int uiVoiceCnt=0;//蜂鳴器鳴叫的持續(xù)時間計數(shù)器

  35. unsigned char ucDigShowTemp=0;//臨時中間變量
  36. unsigned char ucDisplayDriveStep=1;//動態(tài)掃描數(shù)碼管的步驟變量
  37. unsigned char ucWd1Update=1;//窗口 1 更新顯示標(biāo)志
  38. unsigned char ucWd2Update=0;//窗口 2 更新顯示標(biāo)志
  39. unsigned char ucWd3Update=0;//窗口 3 更新顯示標(biāo)志
  40. unsigned char ucWd4Update=0;//窗口 4 更新顯示標(biāo)志
  41. unsigned char ucWd=1;//本程序的核心變量,窗口顯示變量。類似于一級菜單的變量。代表顯示不同的窗口。

  42. unsigned int uiSetData1=999;//本程序中需要被設(shè)置的參數(shù) 1
  43. unsigned int uiSetData2=99;//本程序中需要被設(shè)置的參數(shù) 2
  44. unsigned int uiSetData3=9;//本程序中需要被設(shè)置的參數(shù) 3
  45. unsigned int uiSetData4=1;//本程序中需要被設(shè)置的參數(shù) 4

  46. //根據(jù)原理圖得出的共陰數(shù)碼管字模表
  47. code unsigned char dig_table[]=
  48. {
  49. 0x3f, //0 序號 0
  50. 0x06, //1 序號 1
  51. 0x5b, //2 序號 2
  52. 0x4f, //3 序號 3
  53. 0x66, //4 序號 4
  54. 0x6d, //5 序號 5
  55. 0x7d, //6 序號 6
  56. 0x07, //7 序號 7
  57. 0x7f, //8 序號 8
  58. 0x6f, //9 序號 9
  59. 0x00, //無 序號 10
  60. 0x40, //- 序號 11
  61. 0x73, //P 序號 12
  62. };
  63. code unsigned char dig[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,};
  64. unsigned char ucDigDot[8];//要顯示的8個小數(shù)點(diǎn)
  65. unsigned char ucDigShow[8];//要顯示的8個數(shù)字
  66. void main()
  67. {
  68.         initial_myself();
  69.         delay_long(100);
  70.         initial_peripheral();
  71.         while(1)
  72.         {
  73.                 key_service();//按鍵服務(wù)的應(yīng)用程序               
  74.                 display_service();//顯示的窗口菜單服務(wù)程序               
  75.         }
  76. }
  77. void display_service() //顯示的窗口菜單服務(wù)程序
  78. {        unsigned char i;
  79.         unsigned int temp;
  80.         switch(ucWd) //本程序的核心變量,窗口顯示變量。類似于一級菜單的變量。代表顯示不同的窗口。
  81.         {
  82.         case 1: //顯示 P--1 窗口的數(shù)據(jù)
  83.                 if(ucWd1Update==1) //窗口 1 要全部更新顯示
  84.                 {
  85.                         ucWd1Update=0;//及時清零標(biāo)志,避免一直進(jìn)來掃描                       
  86.                   ucDigShow[7]=12;//第 8 位數(shù)碼管顯示 P                       
  87.                         ucDigShow[6]=11;//第 7 位數(shù)碼管顯示-                       
  88.                         ucDigShow[5]=1;//第 6 位數(shù)碼管顯示 1                       
  89.                         ucDigShow[4]=10;//第 5 位數(shù)碼管顯示無               
  90.                         temp=uiSetData1;
  91.                         for(i=0;i<4;i++)//分解數(shù)字
  92.                         {
  93.                         ucDigShow[i]=temp%10;
  94.                   temp=temp/10;
  95.                         }               
  96.                                 for(i=3;i>=1;i--)                //高位為0不顯示
  97.                         {
  98.                                 if( ucDigShow[i]==0)
  99.        ucDigShow[i]=10;
  100.                                 else break;
  101.                         }               
  102.                 } break;
  103.         case 2: //顯示 P--2 窗口的數(shù)據(jù)
  104.                 if(ucWd2Update==1) //窗口 2 要全部更新顯示
  105.                 {
  106.                         ucWd2Update=0;//及時清零標(biāo)志,避免一直進(jìn)來掃描               
  107.                 ucDigShow[7]=12;//第 8 位數(shù)碼管顯示 P                       
  108.                         ucDigShow[6]=11;//第 7 位數(shù)碼管顯示-                       
  109.                         ucDigShow[5]=2;//第 6 位數(shù)碼管顯示 1                       
  110.                         ucDigShow[4]=10;//第 5 位數(shù)碼管顯示無                               
  111.                                 temp=uiSetData2;
  112.                         for(i=0;i<4;i++)//分解數(shù)字
  113.                         {
  114.                         ucDigShow[i]=temp%10;
  115.                   temp=temp/10;
  116.                         }       
  117.                         for(i=3;i>=1;i--)                        //高位為0不顯示
  118.                         {
  119.                                 if( ucDigShow[i]==0)
  120.        ucDigShow[i]=10;
  121.                                 else
  122.             break;
  123.                         }               
  124.                                        
  125.                 }break;
  126.         case 3: //顯示 P--3 窗口的數(shù)據(jù)
  127.                 if(ucWd3Update==1) //窗口 3 要全部更新顯示
  128.                 {
  129.                         ucWd3Update=0;//及時清零標(biāo)志,避免一直進(jìn)來掃描                       
  130.                         ucDigShow[7]=12;//第 8 位數(shù)碼管顯示 P                       
  131.                         ucDigShow[6]=11;//第 7 位數(shù)碼管顯示-                       
  132.                         ucDigShow[5]=3;//第 6 位數(shù)碼管顯示 1                       
  133.                         ucDigShow[4]=10;//第 5 位數(shù)碼管顯示無                               
  134.                         temp=uiSetData3;
  135.                         for(i=0;i<4;i++)
  136.                         {
  137.                         ucDigShow[i]=temp%10;
  138.                   temp=temp/10;
  139.                         }       
  140.                 if(uiSetData3<1000)       
  141.                         {
  142.                           ucDigShow[3]=10;
  143.                           if(uiSetData3<100)       
  144.                           {
  145.                             ucDigShow[2]=10;
  146.                                   if(uiSetData3<10)       
  147.                             {
  148.                             ucDigShow[1]=10;
  149.                             }
  150.                           }
  151.                         }                               
  152.                 }break;
  153.         case 4: //顯示 P--4 窗口的數(shù)據(jù)
  154.                 if(ucWd4Update==1) //窗口 4 要全部更新顯示
  155.                 {
  156.                         ucWd4Update=0;//及時清零標(biāo)志,避免一直進(jìn)來掃描                       
  157.                   ucDigShow[7]=12;//第 8 位數(shù)碼管顯示 P                       
  158.                         ucDigShow[6]=11;//第 7 位數(shù)碼管顯示-                       
  159.                         ucDigShow[5]=4;//第 6 位數(shù)碼管顯示 1                       
  160.                         ucDigShow[4]=10;//第 5 位數(shù)碼管顯示無                               
  161.                         temp=uiSetData4;
  162.                         for(i=0;i<4;i++)
  163.                         {
  164.                         ucDigShow[i]=temp%10;
  165.                   temp=temp/10;
  166.                         }       
  167.                 if(uiSetData4<1000)       
  168.                         {
  169.                           ucDigShow[3]=10;
  170.                           if(uiSetData4<100)       
  171.                         {
  172.                           ucDigShow[2]=10;
  173.                                   if(uiSetData4<10)       
  174.                         {
  175.                           ucDigShow[1]=10;
  176.                         }}}       
  177.                                        
  178.                 }break;
  179.         }
  180. }
  181. void key_scan()//按鍵掃描函數(shù) 放在定時中斷里
  182. {
  183.         if(key_sr1==1)//IO 是高電平,說明按鍵沒有被按下,這時要及時清零一些標(biāo)志位
  184.         {
  185.                 ucKeyLock1=0;//按鍵自鎖標(biāo)志清零               
  186.                 uiKeyTimeCnt1=0;//按鍵去抖動延時計數(shù)器清零,此行非常巧妙,是我實(shí)戰(zhàn)中摸索出來的。               
  187.         } else if(ucKeyLock1==0)//有按鍵按下,且是第一次被按下
  188.         {
  189.                 uiKeyTimeCnt1++;//累加定時中斷次數(shù)               
  190.                 if(uiKeyTimeCnt1>const_key_time1)
  191.                 {
  192.                         uiKeyTimeCnt1=0;
  193.                         ucKeyLock1=1;//自鎖按鍵置位,避免一直觸發(fā)                       
  194.                         ucKeySec=1;//觸發(fā) 1 號鍵                       
  195.                 }
  196.         }
  197.         if(key_sr2==1)//IO 是高電平,說明按鍵沒有被按下,這時要及時清零一些標(biāo)志位
  198.         {
  199.                 ucKeyLock2=0;//按鍵自鎖標(biāo)志清零               
  200.                 uiKeyTimeCnt2=0;//按鍵去抖動延時計數(shù)器清零,此行非常巧妙,是我實(shí)戰(zhàn)中摸索出來的。               
  201.         } else if(ucKeyLock2==0)//有按鍵按下,且是第一次被按下
  202.         {
  203.                 uiKeyTimeCnt2++;//累加定時中斷次數(shù)               
  204.                 if(uiKeyTimeCnt2>const_key_time2)
  205.                 {
  206.                         uiKeyTimeCnt2=0;
  207.                         ucKeyLock2=1;//自鎖按鍵置位,避免一直觸發(fā)                       
  208.                         ucKeySec=2;//觸發(fā) 2 號鍵                       
  209.                 }
  210.         }
  211.         if(key_sr3==1)//IO 是高電平,說明按鍵沒有被按下,這時要及時清零一些標(biāo)志位
  212.         {
  213.                 ucKeyLock3=0;//按鍵自鎖標(biāo)志清零               
  214.                 uiKeyTimeCnt3=0;//按鍵去抖動延時計數(shù)器清零,此行非常巧妙,是我實(shí)戰(zhàn)中摸索出來的。               
  215.         } else if(ucKeyLock3==0)//有按鍵按下,且是第一次被按下
  216.         {
  217.                 uiKeyTimeCnt3++;//累加定時中斷次數(shù)               
  218.                 if(uiKeyTimeCnt3>const_key_time3)
  219.                 {
  220.                         uiKeyTimeCnt3=0;
  221.                         ucKeyLock3=1;//自鎖按鍵置位,避免一直觸發(fā)                       
  222.                         ucKeySec=3;//觸發(fā) 3 號鍵                       
  223.                 }
  224.         }
  225. }
  226. void key_service() //按鍵服務(wù)的應(yīng)用程序
  227. {
  228.         switch(ucKeySec) //按鍵服務(wù)狀態(tài)切換
  229.         {
  230.                 case 1:// 加按鍵 對應(yīng)朱兆祺學(xué)習(xí)板的 S1 鍵
  231.                 switch(ucWd) //在不同的窗口下,設(shè)置不同的參數(shù)
  232.                 {
  233.                         case 1:
  234.                                uiSetData1++;
  235.                         if(uiSetData1>9999) //最大值是 9999
  236.                         {
  237.                                 uiSetData1=9999;
  238.                         }
  239.                         ucWd1Update=1;//窗口 1 更新顯示                       
  240.                         break;
  241.                         case 2:
  242.                                         uiSetData2++;
  243.                         if(uiSetData2>9999) //最大值是 9999
  244.                         {
  245.                                 uiSetData2=9999;
  246.                         }
  247.                         ucWd2Update=1;//窗口 2 更新顯示                       
  248.                         break;
  249.                         case 3:
  250.                                         uiSetData3++;
  251.                         if(uiSetData3>9999) //最大值是 9999
  252.                         {
  253.                                 uiSetData3=9999;
  254.                         }
  255.                         ucWd3Update=1;//窗口 3 更新顯示                       
  256.                         break;
  257.                         case 4:
  258.                                         uiSetData4++;
  259.                         if(uiSetData4>9999) //最大值是 9999
  260.                         {
  261.                                 uiSetData4=9999;
  262.                         }
  263.                         ucWd4Update=1;//窗口 4 更新顯示                       
  264.                         break;
  265.                 }
  266.                 uiVoiceCnt=const_voice_short;//按鍵聲音觸發(fā),滴一聲就停。               
  267.                 ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)               
  268.                 break;
  269.                 case 2:// 減按鍵 對應(yīng)朱兆祺學(xué)習(xí)板的 S5 鍵
  270.                 switch(ucWd) //在不同的窗口下,設(shè)置不同的參數(shù)
  271.                 {
  272.                         case 1:
  273.                         uiSetData1--;
  274.                         if(uiSetData1>9999)
  275.                         {
  276.                                 uiSetData1=0;//最小值是 0                               
  277.                         }
  278.                         ucWd1Update=1;//窗口 1 更新顯示                       
  279.                         break;
  280.                         case 2:
  281.                         uiSetData2--;
  282.                         if(uiSetData2>9999)
  283.                         {
  284.                                 uiSetData2=0;//最小值是 0                               
  285.                         }
  286.                         ucWd2Update=1;//窗口 2 更新顯示                       
  287.                         break;
  288.                         case 3:
  289.                         uiSetData3--;
  290.                         if(uiSetData3>9999)
  291.                         {
  292.                                 uiSetData3=0;//最小值是 0                               
  293.                         }
  294.                         ucWd3Update=1;//窗口 3 更新顯示                       
  295.                         break;
  296.                         case 4:
  297.                         uiSetData4--;
  298.                         if(uiSetData4>9999)
  299.                         {
  300.                                 uiSetData4=0;//最小值是 0                               
  301.                         }
  302.                         ucWd4Update=1;//窗口 4 更新顯示                       
  303.                         break;
  304.                 }
  305.                 uiVoiceCnt=const_voice_short;//按鍵聲音觸發(fā),滴一聲就停
  306.                 ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)               
  307.                 break;
  308.                 case 3:// 切換窗口按鍵
  309.                 ucWd++;//切換窗口               
  310.                 if(ucWd>4)
  311.                 {
  312.                         ucWd=1;
  313.                 }
  314.                 switch(ucWd) //在不同的窗口下,在不同的窗口下,更新顯示不同的窗口
  315.                 {
  316.                         case 1:
  317.                                 ucWd1Update=1;//窗口 1 更新顯示
  318.                        
  319.                         break;
  320.                         case 2:
  321.                                 ucWd2Update=1; //窗口 2 更新顯示               
  322.                         break;
  323.                         case 3:
  324.                                 ucWd3Update=1;//窗口 3 更新顯示                       
  325.                         break;
  326.                         case 4:
  327.                                 ucWd4Update=1;//窗口 4 更新顯示                       
  328.                         break;
  329.                 }
  330.                 uiVoiceCnt=const_voice_short;//按鍵聲音觸發(fā),滴一聲就停。               
  331.                 ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)               
  332.                 break;
  333.         }
  334. }
  335. void display_drive() //顯示驅(qū)動
  336. {
  337. static unsigned char i=0;

  338.         switch(i)
  339.         {
  340. case 0:
  341. case 1:
  342. case 2:
  343. case 3:
  344. case 4:
  345. case 5:
  346. case 6:
  347. case 7:        
  348.                 ucDigShowTemp=dig_table[ucDigShow[i]];
  349.                 if(ucDigDot[i]==1)
  350.                 {
  351.                         ucDigShowTemp=ucDigShowTemp|0x80;//顯示小數(shù)點(diǎn)                       
  352.                 }
  353.                 dig_hc595_drive(ucDigShowTemp,dig[i]);
  354.                 break;               
  355.         }       
  356.         i++;
  357.         i=i%8;                       
  358. }
  359. //數(shù)碼管的 74HC595 驅(qū)動函數(shù)
  360. void dig_hc595_drive(unsigned char ucDigStatusTemp16_09,unsigned char ucDigStatusTemp08_01)
  361. {
  362.         unsigned char i;
  363.         unsigned char ucTempData;
  364.         dig_hc595_sh_dr=0;
  365.         dig_hc595_st_dr=0;
  366.         ucTempData=ucDigStatusTemp16_09;//先送高 8 位       
  367.         for (i=0;i<8;i++)
  368.         {
  369.                 if(ucTempData>=0x80)dig_hc595_ds_dr=1; else dig_hc595_ds_dr=0;
  370.                 dig_hc595_sh_dr=0;//SH 引腳的上升沿把數(shù)據(jù)送入寄存器               
  371.                 delay_short(1);
  372.                 dig_hc595_sh_dr=1;
  373.                 delay_short(1);
  374.                 ucTempData=ucTempData<<1;
  375.         }
  376.         ucTempData=ucDigStatusTemp08_01;//再先送低 8 位       
  377.         for (i=0;i<8;i++)
  378.         {
  379.                 if(ucTempData>=0x80)dig_hc595_ds_dr=1; else dig_hc595_ds_dr=0;
  380.                 dig_hc595_sh_dr=0;//SH 引腳的上升沿把數(shù)據(jù)送入寄存器               
  381.                 delay_short(1);
  382.                 dig_hc595_sh_dr=1;
  383.                 delay_short(1);
  384.                 ucTempData=ucTempData<<1;
  385.         }
  386.         dig_hc595_st_dr=0;//ST 引腳把兩個寄存器的數(shù)據(jù)更新輸出到 74HC595 的輸出引腳上并且鎖存起來       
  387.         delay_short(1);
  388.         dig_hc595_st_dr=1;
  389.         delay_short(1);
  390.         dig_hc595_sh_dr=0;//拉低,抗干擾就增強(qiáng)       
  391.         dig_hc595_st_dr=0;
  392.         dig_hc595_ds_dr=0;
  393. }

  394.        
  395. void T0_time() interrupt 1
  396. {
  397.         TF0=0;//清除中斷標(biāo)志       
  398.         TR0=0;//關(guān)中斷       
  399.         key_scan();//按鍵掃描函數(shù)       
  400.         if(uiVoiceCnt!=0)
  401.         {
  402.                 uiVoiceCnt--;//每次進(jìn)入定時中斷都自減 1,直到等于零為止。才停止鳴叫               
  403.                 beep_dr=0;//蜂鳴器是 PNP 三極管控制,低電平就開始鳴叫

  404.         } else
  405.         {       
  406.                 beep_dr=1;               
  407.         }
  408.         display_drive();//數(shù)碼管字模的驅(qū)動函數(shù)       
  409.         TH0=0xfe;//重裝初始值(65535-500)=65035=0xfe0b       
  410.         TL0=0x0b;
  411.         TR0=1;//開中斷       
  412. }
  413. void delay_short(unsigned int uiDelayshort)
  414. {
  415. ……………………

  416. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
51hei.png

所有資料51hei附件下載:
029-74HC595菜單顯示高位為零.zip (435.29 KB, 下載次數(shù): 72)
029-595菜單系統(tǒng)高位為0不顯示.pdf (275.59 KB, 下載次數(shù): 35)

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復(fù)

使用道具 舉報

ID:246744 發(fā)表于 2022-3-15 10:37 | 顯示全部樓層
贊美一下!謝謝分享
回復(fù)

使用道具 舉報

ID:492633 發(fā)表于 2024-8-14 19:51 | 顯示全部樓層
case 1:
                               uiSetData1++;
                        if(uiSetData1>9999) //如果最大值是大于 9999
                        {
                                uiSetData1=0; //那么清零重新開始
改一下,不然到達(dá)9999就累計不了了
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表