标题: 单片机按键实现0-9999计数器程序+仿真 4位一体数码管显示 [打印本页]

作者: 陈润源home    时间: 2019-4-6 21:54
标题: 单片机按键实现0-9999计数器程序+仿真 4位一体数码管显示
*********************************************************************************************                                                                               本文已锁,请进来解锁*********************************************************************************************
  恭喜您解开本贴,既然来了就请认真看完再走吧
  名称:按键调节数码管显示

  功能:通过按键加减数码管所显示的数字
            按下k1加1,最大加到9999
            按下k2减1,最小减到0
            按下k3清零复位   
   用了最简单的思路,各路大神不喜勿喷.

   小弟就不和各位爷绕弯子了,直接上图

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. //----------------------------------------------------------------------
  2. //名称:按键调节数码管显示
  3. //----------------------------------------------------------------------
  4. //功能:通过按键加减数码管所显示的数字
  5. //     按下k1加1,最大加到9999
  6. //     按下k2减1,最小减到0
  7. //     按下k3清零复位   
  8. //----------------------------------------------------------------------
  9. #include <reg51.h>
  10. #define uchar unsigned char
  11. #define uint unsigned int

  12. sbit k1 = P1^0;                   //加
  13. sbit k2 = P1^1;                   //减
  14. sbit k3 = P1^2;                   //复位
  15. void key(void);
  16. void display(void);

  17. uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,
  18.                     0x92,0x82,0xf8,0x80,0x90};           //数组
  19.                        
  20. char m=99,n=98;                                //显示初值,m,n的值决定开机显示数值
  21. //****************************************
  22. //延时程序
  23. //****************************************
  24. void delayms(uint xms)
  25. {
  26.    uint i,j;
  27.    for(i=xms;i>0;i--)
  28.    for(j=110;j>0;j--);
  29. }
  30. //***********************************************
  31. //显示程序
  32. //***********************************************
  33. void display(void)
  34. {
  35.         P2=0X08;
  36.                 P0=table[m%10];   //显示个位
  37.                 delayms(5);  
  38.                 P2=0X04;
  39.             P0=table[m/10];          //显示十位
  40.                 delayms(5);                                                              
  41.             P2=0X02;
  42.                 P0=table[n%10];          //显示百位
  43.                 delayms(5);
  44.                 P2=0X01;
  45.                 P0=table[n/10];          //显示千位
  46.                 delayms(5);
  47. }

  48. //***************************************************
  49. //按键处理
  50. //***************************************************
  51. void key()
  52. {
  53.   if(k1==0)                                         //检测按键是否被按下
  54.    {                                                 //延时消抖
  55.            delayms(10);                         
  56.         if(k1==0)                                 //再次检测是否真正按下按键
  57.         {
  58.           m++;                                         //m自加一
  59.           if(m>=100)                         //如果m加到100则n加一 (限制m的取值范围) 个位、十位最大显示99
  60.           {
  61.                   n++;                                 //n自加一
  62.                 m=0;                                 //使m又从0开始计数
  63.                 if(n>=100)                         //如果n加到100则m=n=99 (限制n的取值范围) 百位、千位最大显示99
  64.                 {
  65.                   m=99;                                 //最大显示9999
  66.                   n=99;
  67.                 }
  68.           }
  69.         }
  70.         while(!k1);                                 //按键松开
  71.    }

  72.   if(k2==0)                                         //检测按键是否被按下
  73.    {                                                 //延时消抖
  74.            delayms(10);                         //再次检测是否真正按下按键
  75.         if(k2==0)
  76.         {                                                 //m自减一
  77.           m--;
  78.           if(m<=0)                                 //如果m减到0则n减一 (限制n的取值范围) 个位、十位最小显示00
  79.           {                                                 
  80.             m=99;                                 //重新给m装初值
  81.                   n--;                                 //n自减一
  82.                 if(n==-1)                         //如果n减到-1,则m=n=0 (限制n的取值范围) 百位、千位最小显示00
  83.                 {
  84.                  n=0;                                 //最小显示0000
  85.                  m=0;
  86.                 }
  87.           }
  88.         }
  89.         while(!k2);                                 //按键松开
  90.    }

  91. if(k3==0)                                         //检测按键是否被按下
  92. {
  93.    delayms(10);                                 //延时消抖
  94.    if(k3==0)                                 //再次检测是否真正按下按键
  95.    {
  96.             m=0;                                         //复位,显示0000
  97.          n=0;
  98.    }
  99.    while(!k3);                                 //按键松开
  100. }
  101. }

  102. void main()
  103. {
  104.   while(1)
  105.   {                                                         //调用按键检测
  106.    key();                                         //数码管显示

  107. ……………………

  108. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


所有资料51hei提供下载:
0~9999计数器.zip (53.03 KB, 下载次数: 226)



作者: kevintang    时间: 2020-3-21 12:23
谢谢分享。
作者: 123321151155    时间: 2020-4-29 15:41
多谢大佬分享
作者: 木头人51hei    时间: 2020-7-10 23:20
你好  可预置计数值 的多步语言能写一个吗  赋予输出口  1000hz以内的
作者: zwtaitc    时间: 2020-11-23 14:42
这个跟中断方式有关系吗

作者: zhangleixbyl    时间: 2021-2-20 16:36
用stc89c52怎么改程序啊
作者: bxyyhan    时间: 2021-2-22 10:03
zhangleixbyl 发表于 2021-2-20 16:36
用stc89c52怎么改程序啊

不用改,直接用,实在手痒愿意改把头文件改成REG52。
作者: zhangleixbyl    时间: 2021-2-23 05:41
89c52显示器全亮没倒计时显示,没按按键显示都是零,按了按键显示都是888是什么问题?不兼容吗
作者: bxyyhan    时间: 2021-2-26 20:08
zhangleixbyl 发表于 2021-2-23 05:41
89c52显示器全亮没倒计时显示,没按按键显示都是零,按了按键显示都是888是什么问题?不兼容吗

检查你的数码管驱动电路,他是直接驱动共阳数码管,用89C52可能亮度不够,用12或15单片机,用推挽模式驱动就好了。
作者: zhangleixbyl    时间: 2021-2-26 23:36
bxyyhan 发表于 2021-2-26 20:08
检查你的数码管驱动电路,他是直接驱动共阳数码管,用89C52可能亮度不够,用12或15单片机,用推挽模式驱 ...

小白初学者不会改啊,谢谢大神指点。
作者: bxyyhan    时间: 2021-2-27 20:20
zhangleixbyl 发表于 2021-2-26 23:36
小白初学者不会改啊,谢谢大神指点。

看代码的19-20行,{0xc0,0xf9,0xa4,0xb0,0x99, 0x92,0x82,0xf8,0x80,0x90}; 这是共阳数码管的段码,分别对应数字0-9,既然是共阳数码管,在显示的时候就要在每位数码管的阳极接通高电平才能点亮。

再看37-48行,

这里表明显示的时候分别往数码管阳极输出高电平,如果能的电路用了三极管扩流驱动数码管,那么就需要输出低电平,也就是“取反“,不然就是你那种现象,该亮的不亮,不该亮的全亮。如果你使用的是12或15单片机,可以在函数后加上
P0M1 = 0x00; P0M0 = 0xFF; //P0(00000000B,11111111B)
P2M1 = 0x00; P2M0 = 0x0F; //P2(00000000B,00001111B)
使用单片机推挽模式直接驱动数码管。

作者: zhangleixbyl    时间: 2021-3-10 13:10
bxyyhan 发表于 2021-2-27 20:20
看代码的19-20行,{0xc0,0xf9,0xa4,0xb0,0x99, 0x92,0x82,0xf8,0x80,0x90}; 这是共阳数码管 ...

谢谢,指点




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1