找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

单片机运用ADC判断不同按键,按下时数码管显示不同数字程序, 求解答

查看数: 1523 | 评论数: 6 | 收藏 2
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2023-2-3 10:56

正文摘要:

大伙们我下面实现的功能是:按下第一个按键,从0加到80 按下第二个按键,从80减到10 按下第三个按键,显示10 我下面的代码当按下第一个按键时,会一直加到80,但是数码管不能同时显示这两位,只能显示一位,按下第 ...

回复

ID:161164 发表于 2023-2-21 22:06
代码结构不太好
按键和显示混在一起
  1. //***********************************************************
  2. //数码管处理显示
  3. void  Display(void)
  4. {
  5.         unsigned int Key_value;
  6.         static unsigned char Current_num = 0;
  7.         static unsigned char Delay = 0;
  8.         static bit Swap = 0;
  9.         Key_value = GetAdcValue();  //获取ADC的值
  10.         if(Key_value > 2000 && Key_value < 2200)  //第一个按键
  11.         {
  12.                 if(++Delay >= 100)
  13.                 {
  14.                         Delay = 0;
  15.                         Current_num++;
  16.                 }
  17.                 if(Current_num > 0 && Current_num < 80)
  18.                 {
  19.                         if(Swap)
  20.                         {
  21.                                 Pos_selection(0x00);   //消影
  22.                                 Seg_selection(bcd[Current_num%10]);  //显示Current_num的个位
  23.                                 Pos_selection(0x02);   //第二位数码管
  24.                                 Delay_50us(20);
  25.                         }
  26.                         else
  27.                         {
  28.                                 Pos_selection(0x00);   //消影
  29.                                 Seg_selection(bcd[Current_num/10]);   //显示Current_num的十位
  30.                                 Pos_selection(0x01);   //第一位数码管
  31.                                 Delay_50us(20);
  32.                         }
  33.                         Swap = !Swap;
  34.                 }
  35.                 else
  36.                 {
  37.                         Current_num = 0;
  38.                 }
  39.         }
  40.         if(Key_value > 2600 && Key_value < 3000)  //第二个按键
  41.         {
  42.                 if(++Delay >= 100)
  43.                 {
  44.                         Delay = 0;
  45.                         Current_num--;
  46.                 }
  47.                 if(Current_num > 10 && Current_num < 80)
  48.                 {
  49.                         if(Swap)
  50.                         {
  51.                                 Pos_selection(0x00);   //消影
  52.                                 Seg_selection(bcd[Current_num%10]);  //显示Current_num的个位
  53.                                 Pos_selection(0x02);   //第二位数码管
  54.                                 Delay_50us(20);
  55.                         }
  56.                         else
  57.                         {
  58.                                 Pos_selection(0x00);   //消影
  59.                                 Seg_selection(bcd[Current_num/10]);   //显示Current_num的十位
  60.                                 Pos_selection(0x01);   //第一位数码管
  61.                                 Delay_50us(20);
  62.                         }
  63.                         Swap = !Swap;
  64.                 }
  65.                 else
  66.                 {
  67.                         Current_num = 0;
  68.                 }
  69.         }
  70.         if(Key_value > 3000 && Key_value < 3500)  //第三个按键
  71.         {

  72.                 if(Swap)
  73.                 {
  74.                         Pos_selection(0x00);   //消影
  75.                         Seg_selection(0x30);   //显示1
  76.                         Pos_selection(0x01);   //第一位数码管
  77.                         Delay_50us(20);      //延时
  78.                 }
  79.                 else
  80.                 {
  81.                         Pos_selection(0x00);   //消影
  82.                         Seg_selection(0x3F);   //显示1
  83.                         Pos_selection(0x02);   //第一位数码管
  84.                         Delay_50us(20);      //延时
  85.                 }
  86.                 Swap = !Swap;

  87.         }
  88. }
复制代码


ID:301191 发表于 2023-2-21 21:00
顶一下
ID:883242 发表于 2023-2-7 15:56
AllA1 发表于 2023-2-7 11:04
为什么要用ADC判断按键??

节约单片机IO端口数量来降成本,小家电里面常见的设计。
ID:1034262 发表于 2023-2-7 15:29
用ADC做按键,要回溯过去两三个采样点的值,计算变化率,变化率小于一定值,才认为ADC值已经稳定,可以判断按键了,非常可靠的。
ID:1047633 发表于 2023-2-7 11:04
为什么要用ADC判断按键??
ID:213173 发表于 2023-2-4 14:07
代码和原理图都是错的,给你一个容易理解的不规则端口驱动数码管的代码参考。


  1. #include <reg51.H>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. #define key_S 3                                        //宏定义短按(约15ms)
  5. #define key_L key_S*40                        //宏定义长按(约600ms)
  6. #define key_I key_S*20                        //宏定义长按连+间隔(约300ms)

  7. sbit K1=P2^6;//连接按键

  8. sbit dula0=P0^2;
  9. sbit dula1=P0^1;
  10. sbit dula2=P0^5;
  11. sbit dula3=P2^1;
  12. sbit dula4=P2^4;
  13. sbit dula5=P0^3;
  14. sbit dula6=P0^4;
  15. sbit dula7=P2^0;//连接冒号

  16. sbit wela0=P0^0;
  17. sbit wela1=P2^5;
  18. sbit wela2=P2^7;
  19. sbit wela3=P1^7;


  20. uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳LED段码表
  21. uchar data dis_buf[4];//显示数据缓存
  22. char shi=12,fen=30,sec=0;//时,分,秒
  23. uchar Cnt5ms;//5ms时基
  24. uchar KeySec;//键值
  25. uint num=0;//计数
  26. bit flashing=0;//闪烁标志

  27. //定时器初始化程序
  28. void Timer0Init(void)                //5毫秒@12.000MHz
  29. {
  30.         TMOD |= 0x01;                //设置定时器模式
  31.         TL0 = 0x78;                //设置定时初始值
  32.         TH0 = 0xEC;                //设置定时初始值
  33.         TF0 = 0;                //清除TF0标志
  34.         TR0 = 1;                //定时器0开始计时
  35. }

  36. void keyscan()
  37. {
  38.         static unsigned int time=0;//计数变量
  39.         if(!K1)//按键按下
  40.         {
  41.                 time++;
  42.                 if(time>=key_L)//长按
  43.                 {
  44.                         switch(KeySec)
  45.                         {
  46.                                 case 1: shi++;if(shi>23)shi=0; break;
  47.                                 case 2: fen++;if(fen>59)fen=0; break;
  48.                         }
  49.                         time=key_I;//连+间隔
  50.                         num=1000;//自复位变量赋值(5秒)
  51.                 }
  52.         }
  53.         else                                //松手
  54.         {
  55.                 if(time>key_S && time<key_I)//短按
  56.                 {
  57.                         KeySec++;
  58.                         if(KeySec>2)
  59.                         {
  60.                                 KeySec=0;
  61.                                 Cnt5ms=0;
  62.                                 sec=0;
  63.                         }
  64.                         num=1000;//自复位变量赋值(5秒)
  65.                 }
  66.                 time=0;

  67.         }
  68. }
  69. void dula(uchar i)        //写入8位段码
  70. {   
  71.         dula0=i&0x01;i>>=1;
  72.         dula1=i&0x01;i>>=1;
  73.         dula2=i&0x01;i>>=1;
  74.         dula3=i&0x01;i>>=1;
  75.         dula4=i&0x01;i>>=1;
  76.         dula5=i&0x01;i>>=1;
  77.         dula6=i&0x01;i>>=1;
  78.         dula7=i&0x01;
  79. }
  80. void wela(uchar i)        //写入4位位码
  81. {
  82.         wela0=i&0x01;i>>=1;
  83.         wela1=i&0x01;i>>=1;
  84.         wela2=i&0x01;i>>=1;
  85.         wela3=i&0x01;
  86. }

  87. void display()//数码管动态显示函数
  88. {
  89.         static uchar i=0;

  90.         switch(i)//分解数据
  91.         {
  92.                 case 0: dis_buf[0] = table[shi/10%10];break;
  93.                 case 1: dis_buf[1] = table[shi%10];   break;
  94.                 case 2: dis_buf[2] = table[fen/10%10];break;
  95.                 case 3: dis_buf[3] = table[fen%10];   break;
  96.         }

  97.         wela(0x00);//位码消隐

  98.         switch(KeySec)//送段码
  99.         {
  100.                 case 0: if(KeySec==0)dula(dis_buf[i]);break; //正常走时
  101.                 case 1: if(flashing && (i==0||i==1) && K1)dula(0xff);
  102.                                 else dula(dis_buf[i]);break;         //调整时闪烁
  103.                 case 2: if(flashing && (i==2||i==3) && K1)dula(0xff);
  104.                                 else dula(dis_buf[i]);break;         //调整分闪烁
  105.                 default: break;
  106.         }
  107.         if(!KeySec && flashing)dula7=1;//冒号闪烁               
  108.         else dula7=0;

  109.         wela(0x01<<i);//送位码
  110.         i=++i%4;    //循环计数
  111. }

  112. void Timing()
  113. {
  114.         Cnt5ms++;
  115.         if(KeySec!=0)
  116.         {
  117.                 num--;
  118.                 if(num==0)//按键停止操作5秒自动恢复正常显示
  119.                 {
  120.                         KeySec=0;
  121.                         Cnt5ms=0;
  122.                         sec=0;
  123.                 }
  124.                 if(Cnt5ms%50==0)   //0.25s 快闪调时
  125.                         flashing=~flashing;
  126.         }
  127.         else if(Cnt5ms%100==0)//0.5s  慢闪显秒
  128.                         flashing=~flashing;

  129.         if(Cnt5ms==200)//1s
  130.         {
  131.                 Cnt5ms=0;
  132.                 sec++;
  133.                 if(sec>=60)
  134.                 {
  135.                         sec=0;
  136.                         fen++;
  137.                         if(fen>=60)
  138.                         {
  139.                                 fen=0;
  140.                                 shi++;
  141.                                 if(shi>23)
  142.                                         shi=0;
  143.                         }
  144.                 }
  145.         }
  146. }

  147. void main()//主函数
  148. {
  149.         Timer0Init();//初始化定时器
  150.         while(1)
  151.         {
  152.                 if(TF0)//查询定时器中断请求位
  153.                 {
  154.                         TF0=0;
  155.                         TL0 = 0x78;                //设置定时初始值
  156.                         TH0 = 0xEC;                //设置定时初始值
  157.                         Timing();                //计时函数
  158.                         keyscan();                //按键扫描函数
  159.                         display();                //数码管显示函数
  160.                 }
  161.         }
  162. }
复制代码



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

Powered by 单片机教程网

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