找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3107|回复: 2
收起左侧

单片机74HC595数码管菜单系统程序Proteus仿真(高位为0不显示)

[复制链接]
ID:448556 发表于 2021-11-8 10:18 | 显示全部楼层 |阅读模式
基于吴坚鸿与祁绪电子程序修改
51hei.gif 51hei截图_20211108101636.png 51hei截图_20211108101752.png

单片机源程序如下:
  1. #include "REG52.H"
  2. #define const_voice_short 40 //蜂鸣器短叫的持续时间
  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();//显示数码管字模的驱动函数
  12. void display_service();//显示的窗口菜单服务程序

  13. void T0_time();//定时中断函数
  14. void key_service();//按键服务的应用程序
  15. void key_scan();//按键扫描函数 放在定时中断里
  16. sbit key_sr1=P1^0;
  17. sbit key_sr2=P1^1;
  18. sbit key_sr3=P1^2;
  19. sbit beep_dr=P2^7;//蜂鸣器的驱动 IO 口
  20. sbit led_dr=P3^5;//作为中途暂停指示灯 亮的时候表示中途暂停
  21. sbit dig_hc595_sh_dr=P2^3; //数码管的 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;//被触发的按键编号
  28. unsigned int uiKeyTimeCnt1=0;//按键去抖动延时计数器
  29. unsigned char ucKeyLock1=0;//按键触发后自锁的变量标志
  30. unsigned int uiKeyTimeCnt2=0;//按键去抖动延时计数器
  31. unsigned char ucKeyLock2=0;//按键触发后自锁的变量标志
  32. unsigned int uiKeyTimeCnt3=0;//按键去抖动延时计数器
  33. unsigned char ucKeyLock3=0;//按键触发后自锁的变量标志
  34. unsigned int uiVoiceCnt=0;//蜂鸣器鸣叫的持续时间计数器

  35. unsigned char ucDigShowTemp=0;//临时中间变量
  36. unsigned char ucDisplayDriveStep=1;//动态扫描数码管的步骤变量
  37. unsigned char ucWd1Update=1;//窗口 1 更新显示标志
  38. unsigned char ucWd2Update=0;//窗口 2 更新显示标志
  39. unsigned char ucWd3Update=0;//窗口 3 更新显示标志
  40. unsigned char ucWd4Update=0;//窗口 4 更新显示标志
  41. unsigned char ucWd=1;//本程序的核心变量,窗口显示变量。类似于一级菜单的变量。代表显示不同的窗口。

  42. unsigned int uiSetData1=999;//本程序中需要被设置的参数 1
  43. unsigned int uiSetData2=99;//本程序中需要被设置的参数 2
  44. unsigned int uiSetData3=9;//本程序中需要被设置的参数 3
  45. unsigned int uiSetData4=1;//本程序中需要被设置的参数 4

  46. //根据原理图得出的共阴数码管字模表
  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个小数点
  65. unsigned char ucDigShow[8];//要显示的8个数字
  66. void main()
  67. {
  68.         initial_myself();
  69.         delay_long(100);
  70.         initial_peripheral();
  71.         while(1)
  72.         {
  73.                 key_service();//按键服务的应用程序               
  74.                 display_service();//显示的窗口菜单服务程序               
  75.         }
  76. }
  77. void display_service() //显示的窗口菜单服务程序
  78. {        unsigned char i;
  79.         unsigned int temp;
  80.         switch(ucWd) //本程序的核心变量,窗口显示变量。类似于一级菜单的变量。代表显示不同的窗口。
  81.         {
  82.         case 1: //显示 P--1 窗口的数据
  83.                 if(ucWd1Update==1) //窗口 1 要全部更新显示
  84.                 {
  85.                         ucWd1Update=0;//及时清零标志,避免一直进来扫描                       
  86.                   ucDigShow[7]=12;//第 8 位数码管显示 P                       
  87.                         ucDigShow[6]=11;//第 7 位数码管显示-                       
  88.                         ucDigShow[5]=1;//第 6 位数码管显示 1                       
  89.                         ucDigShow[4]=10;//第 5 位数码管显示无               
  90.                         temp=uiSetData1;
  91.                         for(i=0;i<4;i++)//分解数字
  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 窗口的数据
  104.                 if(ucWd2Update==1) //窗口 2 要全部更新显示
  105.                 {
  106.                         ucWd2Update=0;//及时清零标志,避免一直进来扫描               
  107.                 ucDigShow[7]=12;//第 8 位数码管显示 P                       
  108.                         ucDigShow[6]=11;//第 7 位数码管显示-                       
  109.                         ucDigShow[5]=2;//第 6 位数码管显示 1                       
  110.                         ucDigShow[4]=10;//第 5 位数码管显示无                               
  111.                                 temp=uiSetData2;
  112.                         for(i=0;i<4;i++)//分解数字
  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 窗口的数据
  127.                 if(ucWd3Update==1) //窗口 3 要全部更新显示
  128.                 {
  129.                         ucWd3Update=0;//及时清零标志,避免一直进来扫描                       
  130.                         ucDigShow[7]=12;//第 8 位数码管显示 P                       
  131.                         ucDigShow[6]=11;//第 7 位数码管显示-                       
  132.                         ucDigShow[5]=3;//第 6 位数码管显示 1                       
  133.                         ucDigShow[4]=10;//第 5 位数码管显示无                               
  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 窗口的数据
  154.                 if(ucWd4Update==1) //窗口 4 要全部更新显示
  155.                 {
  156.                         ucWd4Update=0;//及时清零标志,避免一直进来扫描                       
  157.                   ucDigShow[7]=12;//第 8 位数码管显示 P                       
  158.                         ucDigShow[6]=11;//第 7 位数码管显示-                       
  159.                         ucDigShow[5]=4;//第 6 位数码管显示 1                       
  160.                         ucDigShow[4]=10;//第 5 位数码管显示无                               
  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()//按键扫描函数 放在定时中断里
  182. {
  183.         if(key_sr1==1)//IO 是高电平,说明按键没有被按下,这时要及时清零一些标志位
  184.         {
  185.                 ucKeyLock1=0;//按键自锁标志清零               
  186.                 uiKeyTimeCnt1=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。               
  187.         } else if(ucKeyLock1==0)//有按键按下,且是第一次被按下
  188.         {
  189.                 uiKeyTimeCnt1++;//累加定时中断次数               
  190.                 if(uiKeyTimeCnt1>const_key_time1)
  191.                 {
  192.                         uiKeyTimeCnt1=0;
  193.                         ucKeyLock1=1;//自锁按键置位,避免一直触发                       
  194.                         ucKeySec=1;//触发 1 号键                       
  195.                 }
  196.         }
  197.         if(key_sr2==1)//IO 是高电平,说明按键没有被按下,这时要及时清零一些标志位
  198.         {
  199.                 ucKeyLock2=0;//按键自锁标志清零               
  200.                 uiKeyTimeCnt2=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。               
  201.         } else if(ucKeyLock2==0)//有按键按下,且是第一次被按下
  202.         {
  203.                 uiKeyTimeCnt2++;//累加定时中断次数               
  204.                 if(uiKeyTimeCnt2>const_key_time2)
  205.                 {
  206.                         uiKeyTimeCnt2=0;
  207.                         ucKeyLock2=1;//自锁按键置位,避免一直触发                       
  208.                         ucKeySec=2;//触发 2 号键                       
  209.                 }
  210.         }
  211.         if(key_sr3==1)//IO 是高电平,说明按键没有被按下,这时要及时清零一些标志位
  212.         {
  213.                 ucKeyLock3=0;//按键自锁标志清零               
  214.                 uiKeyTimeCnt3=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。               
  215.         } else if(ucKeyLock3==0)//有按键按下,且是第一次被按下
  216.         {
  217.                 uiKeyTimeCnt3++;//累加定时中断次数               
  218.                 if(uiKeyTimeCnt3>const_key_time3)
  219.                 {
  220.                         uiKeyTimeCnt3=0;
  221.                         ucKeyLock3=1;//自锁按键置位,避免一直触发                       
  222.                         ucKeySec=3;//触发 3 号键                       
  223.                 }
  224.         }
  225. }
  226. void key_service() //按键服务的应用程序
  227. {
  228.         switch(ucKeySec) //按键服务状态切换
  229.         {
  230.                 case 1:// 加按键 对应朱兆祺学习板的 S1 键
  231.                 switch(ucWd) //在不同的窗口下,设置不同的参数
  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;//按键声音触发,滴一声就停。               
  267.                 ucKeySec=0;//响应按键服务处理程序后,按键编号清零,避免一致触发               
  268.                 break;
  269.                 case 2:// 减按键 对应朱兆祺学习板的 S5 键
  270.                 switch(ucWd) //在不同的窗口下,设置不同的参数
  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;//按键声音触发,滴一声就停
  306.                 ucKeySec=0;//响应按键服务处理程序后,按键编号清零,避免一致触发               
  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;//按键声音触发,滴一声就停。               
  331.                 ucKeySec=0;//响应按键服务处理程序后,按键编号清零,避免一致触发               
  332.                 break;
  333.         }
  334. }
  335. void display_drive() //显示驱动
  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;//显示小数点                       
  352.                 }
  353.                 dig_hc595_drive(ucDigShowTemp,dig[i]);
  354.                 break;               
  355.         }       
  356.         i++;
  357.         i=i%8;                       
  358. }
  359. //数码管的 74HC595 驱动函数
  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 引脚的上升沿把数据送入寄存器               
  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 引脚的上升沿把数据送入寄存器               
  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 引脚把两个寄存器的数据更新输出到 74HC595 的输出引脚上并且锁存起来       
  387.         delay_short(1);
  388.         dig_hc595_st_dr=1;
  389.         delay_short(1);
  390.         dig_hc595_sh_dr=0;//拉低,抗干扰就增强       
  391.         dig_hc595_st_dr=0;
  392.         dig_hc595_ds_dr=0;
  393. }

  394.        
  395. void T0_time() interrupt 1
  396. {
  397.         TF0=0;//清除中断标志       
  398.         TR0=0;//关中断       
  399.         key_scan();//按键扫描函数       
  400.         if(uiVoiceCnt!=0)
  401.         {
  402.                 uiVoiceCnt--;//每次进入定时中断都自减 1,直到等于零为止。才停止鸣叫               
  403.                 beep_dr=0;//蜂鸣器是 PNP 三极管控制,低电平就开始鸣叫

  404.         } else
  405.         {       
  406.                 beep_dr=1;               
  407.         }
  408.         display_drive();//数码管字模的驱动函数       
  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黑下载附件…………
复制代码
51hei.png

所有资料51hei附件下载:
029-74HC595菜单显示高位为零.zip (435.29 KB, 下载次数: 72)

评分

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

查看全部评分

回复

使用道具 举报

ID:246744 发表于 2022-3-15 10:37 | 显示全部楼层
赞美一下!谢谢分享
回复

使用道具 举报

无效楼层,该帖已经被删除
ID:492633 发表于 2024-8-14 19:51 | 显示全部楼层
case 1:
                               uiSetData1++;
                        if(uiSetData1>9999) //如果最大值是大于 9999
                        {
                                uiSetData1=0; //那么清零重新开始
改一下,不然到达9999就累计不了了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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