久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1519|回復: 6
打印 上一主題 下一主題
收起左側

單片機運用ADC判斷不同按鍵,按下時數碼管顯示不同數字程序, 求解答

[復制鏈接]
跳轉到指定樓層
樓主
ID:1041297 發表于 2023-2-3 10:56 來自觸屏版 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
大伙們我下面實現的功能是:按下第一個按鍵,從0加到80
按下第二個按鍵,從80減到10
按下第三個按鍵,顯示10
我下面的代碼當按下第一個按鍵時,會一直加到80,但是數碼管不能同時顯示這兩位,只能顯示一位,按下第二個按鍵也是一樣,第三個按鍵也是一樣
請大伙給個代碼例程或者給我講講哪些錯誤的地方需要改,按鍵是由ADC來判斷的
  1. //段
  2. sbit pin_seg1 = P0^2;
  3. sbit pin_seg2 = P0^1;
  4. sbit pin_seg3 = P0^5;
  5. sbit pin_seg4 = P2^1;
  6. sbit pin_seg5 = P2^4;
  7. sbit pin_seg6 = P0^3;
  8. sbit pin_seg7 = P0^4;
  9. sbit pin_seg8 = P2^0;

  10. //位
  11. sbit pin_com1 = P1^7; //第一個數碼管
  12. sbit pin_com2 = P2^7; //第二個數碼管
  13. sbit pin_com3 = P2^5; //第三個數碼管
  14. sbit pin_com4 = P0^0; //第四個數碼管
  15. sbit pin_com5 = P1^6; //兩個點
  16. unsigned int ADCValue = 0x0000;
  17. bit AdcFlag = 0;

  18.             //------------------------0,---1;-----2;----3;----4;----5;----6;----7;----8;----9;----10---11;--12;--13;---14;---15
  19. unsigned char code bcd[]={0x3f,0x30,0x5b,0x79,0x74,0x6d,0x6f,0x38,0x7f,0x7d,0x77,0x79,0x39,0x5e,0x4f,0x71};      
  20. /*****************************************************
  21. *函數名稱:void Delay_50us(unsigned int n)
  22. *函數功能:延時函數
  23. *入口參數:n
  24. *出口參數:void
  25. *****************************************************/  
  26. void Delay_50us(unsigned int n)           
  27. {
  28.         unsigned char i;
  29.         while(n--)
  30.         {
  31.                 for(i=0;i<15;i++);
  32.         }
  33. }

  34. /**************************************ADC采樣口選擇*****************************************/
  35. #if (IC_MODEL == SC92F7323)
  36.         enum Channel {AIN0=0,AIN1,AIN2,AIN3,AIN4,AIN5,AIN6,AIN7,AIN8,AIN9,VDD4=15};
  37. #endif

  38. #if (IC_MODEL == SC92F7322)
  39.         enum Channel {AIN0=0,AIN1,AIN4=4,AIN5,AIN6,AIN7,AIN8,AIN9,VDD4=15};
  40. #endif
  41.         
  42. #if (IC_MODEL == SC92F7321)
  43.         enum Channel {AIN0=0,AIN1,AIN2,AIN3,AIN8=8,AIN9,VDD4=15};
  44. #endif
  45.         
  46. #if (IC_MODEL == SC92F7320)
  47.         enum Channel {AIN0=0,AIN1,AIN6=6,AIN7,VDD4=15};
  48. #endif
  49.         

  50. /*****************************************************
  51. *函數名稱:void ADC_Init(unsigned int Channel)
  52. *函數功能:ADC初始化
  53. *入口參數:Channel
  54. *出口參數:void
  55. *****************************************************/
  56. void ADC_Init(unsigned int Channel)
  57. {
  58.         ADCCON = 0X80|Channel;                //開啟ADC,ADC采樣頻率為2M ,選擇Channel位ADC采樣口
  59.         if(Channel<8)
  60.         {
  61.                 ADCCFG0 = 1<<Channel;   //設置Channel作為采樣口
  62.         }
  63.         else
  64.         {
  65.                 ADCCFG1 = 1<<(Channel-8);   //設置Channel作為采樣口
  66.         }
  67.         IE |= 0X40;        //開啟ADC中斷
  68. }

  69. /*****************************************************
  70. *函數名稱:void GetAdcValue(void)
  71. *函數功能:ADC測試
  72. *入口參數:void
  73. *出口參數:void
  74. *函數作用:獲取ADC的值
  75. *****************************************************/
  76. unsigned int GetAdcValue(void)
  77. {
  78.         ADC_Init(AIN6);   //設置通道6為ADC輸入
  79.         ADCCON |= 0X40;   //開始ADC轉換
  80.         while(!AdcFlag);        //等待 ADC轉換完成;
  81.         AdcFlag = 0;
  82.         ADCValue = (ADCVH<<4)+(ADCVL>>4);
  83.         return ADCValue;
  84. }

  85. void ADC_Interrupt(void) interrupt 6
  86. {
  87.         static unsigned char TIME1 = 0;
  88.         ADCCON &= ~(0X10);  //清中斷標志位
  89.         AdcFlag = 1;
  90. }



  91. /*****************************************************
  92. *函數名稱:void Seg_selection2(void)
  93. *函數功能:將傳進來的num值,分別賦值給各個引腳
  94. *入口參數:void
  95. *出口參數:void
  96. *****************************************************/
  97. void Seg_selection(unsigned char num)  //num是a~h
  98. {
  99.         pin_seg1 = num & 0x01;num=num>>1;   //num^0是a段
  100.         pin_seg2 = num & 0x01;num=num>>1;   //num^1是b段
  101.         pin_seg3 = num & 0x01;num=num>>1;   //num^2是c段
  102.         pin_seg4 = num & 0x01;num=num>>1;   //num^3是d段
  103.         pin_seg5 = num & 0x01;num=num>>1;   //num^4是e段
  104.         pin_seg6 = num & 0x01;num=num>>1;   //num^5是f段
  105.         pin_seg7 = num & 0x01;num=num>>1;   //num^6是g段
  106.         pin_seg8 = num & 0x01;num=num>>1;   //num^7是h段
  107. }


  108. /*****************************************************
  109. *函數名稱:void Pos_selection(void)
  110. *函數功能:點亮某一位數碼管
  111. *入口參數:void
  112. *出口參數:void
  113. *****************************************************/
  114. void Pos_selection(unsigned char num)   //num的1~5位分別對應數碼管的1~5位
  115. {
  116.         pin_com1 = num & 0x01;num=num>>1;   //num^0是第一個數碼管
  117.         pin_com2 = num & 0x01;num=num>>1;   //num^1是第二個數碼管
  118.         pin_com3 = num & 0x01;num=num>>1;   //num^2是第三個數碼管
  119.         pin_com4 = num & 0x01;num=num>>1;   //num^3是第四個數碼管
  120.         pin_com5 = num & 0x01;num=num>>1;   //num^4是第兩個點
  121. }

  122. //***********************************************************
  123. //數碼管處理顯示
  124. void  Display(void)               
  125. {
  126.         unsigned int Key_value;
  127.         static unsigned char Current_num = 0;
  128.         Key_value = GetAdcValue();  //獲取ADC的值
  129.         if(Key_value > 2000 && Key_value < 2200)  //第一個按鍵
  130.         {
  131.                 Current_num++;
  132.                 if(Current_num > 0 && Current_num < 80)
  133.                 {
  134.                         Pos_selection(0x00);   //消影
  135.                         Seg_selection(bcd[Current_num%10]);  //顯示Current_num的個位
  136.                         Pos_selection(0x02);   //第二位數碼管
  137.                         Delay_50us(2000);
  138.                         
  139.                         Pos_selection(0x00);   //消影
  140.                         Seg_selection(bcd[Current_num/10]);   //顯示Current_num的十位
  141.                         Pos_selection(0x01);   //第一位數碼管
  142.                         Delay_50us(2000);
  143.                 }        
  144.                 else
  145.                 {
  146.                         Current_num = 0;
  147.                 }
  148.         }
  149.         if(Key_value > 2600 && Key_value < 3000)  //第二個按鍵
  150.         {
  151.                 Current_num--;
  152.                 if(Current_num > 10 && Current_num < 80)  
  153.                 {
  154.                         Pos_selection(0x00);   //消影
  155.                         Seg_selection(bcd[Current_num%10]);  
  156.                         Pos_selection(0x02);   //第二位數碼管
  157.                         Delay_50us(2000);
  158.                         
  159.                         Pos_selection(0x00);   //消影
  160.                         Seg_selection(bcd[Current_num/10]);  
  161.                         Pos_selection(0x01);   //第一位數碼管
  162.                         Delay_50us(2000);
  163.                 }        
  164.                 else
  165.                 {
  166.                         Current_num = 0;
  167.                 }
  168.         }
  169.         if(Key_value > 3000 && Key_value < 3500)  //第三個按鍵
  170.         {
  171.                 Pos_selection(0x00);   //消影
  172.                 Seg_selection(0x30);   //顯示1
  173.                 Pos_selection(0x01);   //第一位數碼管
  174.                 Delay_50us(2000);      //延時
  175.                
  176.                 Pos_selection(0x00);   //消影
  177.                 Seg_selection(0x3F);   //顯示1
  178.                 Pos_selection(0x02);   //第一位數碼管
  179.                 Delay_50us(2000);      //延時
  180.                
  181.         }
  182. }


  183. void main(void)
  184. {
  185.         IO_Init();
  186.         EA = 1;
  187.         while(1)
  188.         {
  189.                 Display();
  190.         }

  191. }


復制代碼





IMG_20230203_104622.jpg (1.15 MB, 下載次數: 47)

IMG_20230203_104622.jpg

IMG_20230203_100934.jpg (907.35 KB, 下載次數: 52)

IMG_20230203_100934.jpg
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
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. }
復制代碼



回復

使用道具 舉報

板凳
ID:1047633 發表于 2023-2-7 11:04 來自觸屏版 | 只看該作者
為什么要用ADC判斷按鍵??
回復

使用道具 舉報

地板
ID:1034262 發表于 2023-2-7 15:29 | 只看該作者
用ADC做按鍵,要回溯過去兩三個采樣點的值,計算變化率,變化率小于一定值,才認為ADC值已經穩定,可以判斷按鍵了,非常可靠的。
回復

使用道具 舉報

5#
ID:883242 發表于 2023-2-7 15:56 | 只看該作者
AllA1 發表于 2023-2-7 11:04
為什么要用ADC判斷按鍵??

節約單片機IO端口數量來降成本,小家電里面常見的設計。
回復

使用道具 舉報

6#
ID:301191 發表于 2023-2-21 21:00 | 只看該作者
頂一下
回復

使用道具 舉報

7#
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. }
復制代碼


回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91久久综合亚洲鲁鲁五月天 | 亚洲视频免费一区 | 久久久蜜桃 | 久久国内| 草久在线 | 国产成人精品午夜视频免费 | 亚洲精品乱码久久久久久按摩 | 中文字幕一区在线 | 中文无码日韩欧 | 欧美一区成人 | 激情欧美日韩一区二区 | 欧美精品一区三区 | 一级久久久久久 | 日韩一二三区 | 日产久久| 九九在线精品视频 | 日韩视频一区二区 | 久久精品国产99国产精品 | 精品国产乱码久久久久久影片 | 久久成人18免费网站 | 国产精品一区在线观看 | 亚洲精品一区二区 | 国产精品视频在线播放 | 欧美在线a | 国产黄色小视频在线观看 | 欧美极品少妇xxxxⅹ免费视频 | 国产精品一区二区三 | 人人叉 | 懂色av色香蕉一区二区蜜桃 | 毛片视频观看 | 日本欧美视频 | 91视频在线看 | 紧缚调教一区二区三区视频 | 日本三级电影在线观看视频 | 一区二区三区在线播放 | 国产小视频自拍 | 日韩精品在线观看视频 | 久久久久久久久久久国产 | 成人久久久 | 中文字幕在线人 | 97av视频 |