找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索

單片機(jī)運(yùn)用ADC判斷不同按鍵,按下時數(shù)碼管顯示不同數(shù)字程序, 求解答

查看數(shù): 1548 | 評論數(shù): 6 | 收藏 2
關(guān)燈 | 提示:支持鍵盤翻頁<-左 右->
    組圖打開中,請稍候......
發(fā)布時間: 2023-2-3 10:56

正文摘要:

大伙們我下面實(shí)現(xiàn)的功能是:按下第一個按鍵,從0加到80 按下第二個按鍵,從80減到10 按下第三個按鍵,顯示10 我下面的代碼當(dāng)按下第一個按鍵時,會一直加到80,但是數(shù)碼管不能同時顯示這兩位,只能顯示一位,按下第 ...

回復(fù)

ID:161164 發(fā)表于 2023-2-21 22:06
代碼結(jié)構(gòu)不太好
按鍵和顯示混在一起
  1. //***********************************************************
  2. //數(shù)碼管處理顯示
  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);   //第二位數(shù)碼管
  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);   //第一位數(shù)碼管
  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);   //第二位數(shù)碼管
  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);   //第一位數(shù)碼管
  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);   //第一位數(shù)碼管
  77.                         Delay_50us(20);      //延時
  78.                 }
  79.                 else
  80.                 {
  81.                         Pos_selection(0x00);   //消影
  82.                         Seg_selection(0x3F);   //顯示1
  83.                         Pos_selection(0x02);   //第一位數(shù)碼管
  84.                         Delay_50us(20);      //延時
  85.                 }
  86.                 Swap = !Swap;

  87.         }
  88. }
復(fù)制代碼


ID:301191 發(fā)表于 2023-2-21 21:00
頂一下
ID:883242 發(fā)表于 2023-2-7 15:56
AllA1 發(fā)表于 2023-2-7 11:04
為什么要用ADC判斷按鍵??

節(jié)約單片機(jī)IO端口數(shù)量來降成本,小家電里面常見的設(shè)計(jì)。
ID:1034262 發(fā)表于 2023-2-7 15:29
用ADC做按鍵,要回溯過去兩三個采樣點(diǎn)的值,計(jì)算變化率,變化率小于一定值,才認(rèn)為ADC值已經(jīng)穩(wěn)定,可以判斷按鍵了,非常可靠的。
ID:1047633 發(fā)表于 2023-2-7 11:04
為什么要用ADC判斷按鍵??
ID:213173 發(fā)表于 2023-2-4 14:07
代碼和原理圖都是錯的,給你一個容易理解的不規(guī)則端口驅(qū)動數(shù)碼管的代碼參考。


  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];//顯示數(shù)據(jù)緩存
  22. char shi=12,fen=30,sec=0;//時,分,秒
  23. uchar Cnt5ms;//5ms時基
  24. uchar KeySec;//鍵值
  25. uint num=0;//計(jì)數(shù)
  26. bit flashing=0;//閃爍標(biāo)志

  27. //定時器初始化程序
  28. void Timer0Init(void)                //5毫秒@12.000MHz
  29. {
  30.         TMOD |= 0x01;                //設(shè)置定時器模式
  31.         TL0 = 0x78;                //設(shè)置定時初始值
  32.         TH0 = 0xEC;                //設(shè)置定時初始值
  33.         TF0 = 0;                //清除TF0標(biāo)志
  34.         TR0 = 1;                //定時器0開始計(jì)時
  35. }

  36. void keyscan()
  37. {
  38.         static unsigned int time=0;//計(jì)數(shù)變量
  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;//自復(fù)位變量賦值(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;//自復(fù)位變量賦值(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()//數(shù)碼管動態(tài)顯示函數(shù)
  88. {
  89.         static uchar i=0;

  90.         switch(i)//分解數(shù)據(jù)
  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;         //調(diào)整時閃爍
  103.                 case 2: if(flashing && (i==2||i==3) && K1)dula(0xff);
  104.                                 else dula(dis_buf[i]);break;         //調(diào)整分閃爍
  105.                 default: break;
  106.         }
  107.         if(!KeySec && flashing)dula7=1;//冒號閃爍               
  108.         else dula7=0;

  109.         wela(0x01<<i);//送位碼
  110.         i=++i%4;    //循環(huán)計(jì)數(shù)
  111. }

  112. void Timing()
  113. {
  114.         Cnt5ms++;
  115.         if(KeySec!=0)
  116.         {
  117.                 num--;
  118.                 if(num==0)//按鍵停止操作5秒自動恢復(fù)正常顯示
  119.                 {
  120.                         KeySec=0;
  121.                         Cnt5ms=0;
  122.                         sec=0;
  123.                 }
  124.                 if(Cnt5ms%50==0)   //0.25s 快閃調(diào)時
  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()//主函數(shù)
  148. {
  149.         Timer0Init();//初始化定時器
  150.         while(1)
  151.         {
  152.                 if(TF0)//查詢定時器中斷請求位
  153.                 {
  154.                         TF0=0;
  155.                         TL0 = 0x78;                //設(shè)置定時初始值
  156.                         TH0 = 0xEC;                //設(shè)置定時初始值
  157.                         Timing();                //計(jì)時函數(shù)
  158.                         keyscan();                //按鍵掃描函數(shù)
  159.                         display();                //數(shù)碼管顯示函數(shù)
  160.                 }
  161.         }
  162. }
復(fù)制代碼



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

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

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