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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4538|回復: 3
收起左側

關于單片機ADC做按鍵識別掃描的數據處理及應用

[復制鏈接]
ID:293534 發表于 2018-5-12 00:25 | 顯示全部樓層 |閱讀模式
我在STC上仿真的時候,發現只有按鍵的鍵號可以改變,但是電壓值恒為0.151V,ADC輸入端電壓為0-5V,不知道錯誤原因啊,急急急

  1. //程序功能說明:根據ADC轉換結果得到按鍵號,將按鍵號顯示在最左端
  2. //同時將AD轉換的電壓值顯示在右邊四位數碼管上x.xxx,單位:V
  3. #include "STC15Fxxxx.h"
  4. #define delt 16 //設置ADC允許偏差
  5. u8 code seg7[]={//標準字庫顯示段碼
  6. //  0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F  H  滅
  7. 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x76,0x0};
  8.   
  9. sbit P_HC595_SER   = P4^0; //pin 14 SER  data input
  10. sbit P_HC595_RCLK  = P5^4; //pin 12 RCLk store (latch) clock
  11. sbit P_HC595_SRCLK = P4^3; //pin 11 SRCLK Shift data clock
  12. u8 KeyNo=0; //給用戶使用的鍵碼, 1~16有效
  13. u8 code wei[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};//位選碼
  14. u8 dsply_buf[]={0x10,0x11,0x11,0x11,5,0,0,0};//顯示緩沖區定義
  15. u8 k=0;//  
  16. u16 adc_VAL=0;
  17. float volt=0;
  18. //u8 KeyNo1;
  19. u8 KeyNo2; //鍵碼中間變量
  20. u8 KeyNo3;
  21. u8 ge,shi,bai,qian; // 電壓的個位/十位/百位/千位(毫伏)
  22. void delay(u8 N); //延時N毫秒子程序
  23. void Send_595(u8 dat); //發送一個字節數據到595
  24. void display();//8位數碼管動態顯示
  25. char get_KeyNo();
  26. void mcu_int();
  27. void delay500ms();
  28. /**********************************************/
  29. void main(void)
  30. { mcu_int();
  31. while(1)
  32. { while(ADC_CONTR!=0xF4)//等待轉換完成
  33.    {}  
  34.    //ADC_FLAG=1,說明轉換完成
  35.    adc_VAL=ADC_RES*256+ADC_RESL;//第一次讀取轉換結果
  36.    ADC_CONTR=0xEC;//清除ADC_FLAG,繼續轉換
  37.   if (adc_VAL>32) //轉換結果不為零,說明有按鍵按下
  38.       { delay(3);  //延時3ms,
  39.      while(ADC_CONTR!=0xF4)//等待轉換完成
  40.              {}
  41.      adc_VAL=ADC_RES*256+ADC_RESL;//第二次讀取轉換結果
  42.      ADC_CONTR=0xEC; //清除ADC_FLAG,繼續轉換
  43.      if (adc_VAL>32)              //轉換結果不為零,說明確實有按鍵按下
  44.         {  KeyNo2=get_KeyNo();
  45.          NOP4();//短延時
  46.       while(ADC_CONTR!=0xF4)//等待轉換完成
  47.                    {}
  48.             adc_VAL=ADC_RES*256+ADC_RESL;//第三次讀取轉換結果
  49.             ADC_CONTR=0xEC; //清除ADC_FLAG,繼續轉換
  50.       KeyNo3=get_KeyNo();
  51.       if (KeyNo2==KeyNo3)//兩次讀取鍵碼相同,說明按鍵沒有錯誤
  52.         { //等待鍵松開
  53.           volt=(adc_VAL*5)/1.023;
  54.         while(1)
  55.          { while(ADC_CONTR!=0xF4)//等待轉換完成
  56.                            {}
  57.                       adc_VAL=ADC_RES*256+ADC_RESL;//第三次讀取轉換結果
  58.                       ADC_CONTR=0xEC; //清除ADC_FLAG,繼續轉換
  59.           if (adc_VAL<32)//鍵松開了,電壓低于5V×32/1023
  60.             break;
  61.            }
  62.           KeyNo=KeyNo2;
  63.       dsply_buf[0] = KeyNo / 10; //顯示鍵碼
  64.             dsply_buf[1] = KeyNo % 10; //顯示鍵碼
  65. //       dsply_buf[0]=KeyNo;
  66.        volt=(adc_VAL*5)/1.023;
  67.        adc_VAL=volt;
  68.        ge=adc_VAL%1000%100%10;
  69.        shi=adc_VAL%1000%100/10;
  70.        bai=adc_VAL%1000/100;
  71.        qian=adc_VAL/1000;
  72.        dsply_buf[7]=ge;
  73.        dsply_buf[6]=shi;
  74.        dsply_buf[5]=bai;
  75.        dsply_buf[4]=qian;
  76.         }
  77.       }
  78.    }
  79.     }  
  80. }
  81. void mcu_int()//初始化單片機
  82.    {// 端口初始化
  83.     P0M1 = 0; P0M0 = 0; //設置為準雙向口
  84. P1M1 = 0; P1M0 = 0; //設置為準雙向口
  85. P2M1 = 0; P2M0 = 0; //設置為準雙向口
  86. P3M1 = 0; P3M0 = 0; //設置為準雙向口
  87. P4M1 = 0; P4M0 = 0; //設置為準雙向口
  88. P5M1 = 0; P5M0 = 0; //設置為準雙向口
  89. P6M1 = 0; P6M0 = 0; //設置為準雙向口
  90. P7M1 = 0; P7M0 = 0; //設置為準雙向口
  91. // 定時器T0初始化,定時4ms,模式0,16位自動重裝方式,系統時鐘12M,定時器輸入12分頻
  92.    TMOD=0x00;
  93.    TH0=0xF8;
  94.    TL0=0x30;
  95.    EA=1;  //允許中斷
  96.    ET0=1;  //開T0中斷
  97.    TR0=1;  //啟動定時器T0
  98. //ADC初始化  
  99.   P1ASF=0x10;     //選擇P14為ADC輸入通道
  100.   CLK_DIV=0x20;   //ADRJ=1,10位模式,adc_val=ADC_RES*256+ADC_RESL
  101.   ADC_CONTR=0xE4; //打開ADC電源,速度90T,通道4 ADC_start位置0,轉換沒有開始
  102.   delay500ms();       //適當延時,等待內部電路穩定
  103.   ADC_CONTR=0xEC; //ADC_START=1,開始轉換
  104.   delay500ms(); //延時500ms,確保轉換電路穩定
  105.      }
  106. void delay(u8 N)    //@12.000MHz //軟件延時Nms函數
  107. {
  108. u8 i, j;
  109. i = 12*N;
  110. j = 169;
  111. do
  112. {
  113.   while (--j);
  114. } while (--i);
  115. }
  116. void Send_595(u8 dat)  // 向HC595發送一個字節函數/
  117. {
  118.   u8 i;
  119. for(i=0; i<8; i++)
  120. {
  121.   dat <<= 1;
  122.   P_HC595_SER   = CY;
  123.   P_HC595_SRCLK = 0;
  124.   P_HC595_SRCLK = 1;
  125.   }
  126. }
  127. void display() interrupt 1 //動態顯示緩沖區內容
  128.    {  u8 segcode;
  129.        TF0=0;    //清除T0中斷標志
  130.     segcode=seg7[dsply_buf[k]];
  131.        if (k==4)
  132.     {
  133.       segcode=(segcode|0x80);
  134.      }   //小數點位置1
  135.        Send_595(wei[k]);
  136.     Send_595(segcode);
  137.     P_HC595_RCLK = 0;
  138.       P_HC595_RCLK = 1;
  139.     k++; //指向下一位
  140.     if (k==8)
  141.       k=0;   
  142.     }
  143. char get_KeyNo() //根據adc_VAL確定按鍵號
  144.     {                 u8 KeyNo1;            
  145.                  if ((adc_VAL>48)&&(adc_VAL<80))     
  146.          { KeyNo1=0;}
  147.         if ((adc_VAL>112)&&(adc_VAL<144))
  148.           {KeyNo1=1;}
  149.         if ((adc_VAL>176)&&(adc_VAL<208))
  150.          {KeyNo1=2;}
  151.         if ((adc_VAL>240)&&(adc_VAL<272))
  152.          {KeyNo1=3;}
  153.         if ((adc_VAL>304)&&(adc_VAL<336))
  154.          {KeyNo1=4;}
  155.         if ((adc_VAL>368)&&(adc_VAL<400))
  156.          {KeyNo1=5;}
  157.         if ((adc_VAL>432)&&(adc_VAL<464))
  158.          {KeyNo1=6;}
  159.         if ((adc_VAL>496)&&(adc_VAL<528))
  160.          {KeyNo1=7;}
  161.         if ((adc_VAL>560)&&(adc_VAL<592))
  162.          {KeyNo1=8;}
  163.         if ((adc_VAL>624)&&(adc_VAL<656))
  164.          {KeyNo1=9; }
  165.         if ((adc_VAL>688)&&(adc_VAL<720))
  166.          {KeyNo1=0xA;}
  167.         if ((adc_VAL>752)&&(adc_VAL<784))
  168.          {KeyNo1=0xB;}
  169.         if ((adc_VAL>816)&&(adc_VAL<848))
  170.          {KeyNo1=0xC;}
  171.         if ((adc_VAL>880)&&(adc_VAL<912))  
  172.          {KeyNo1=0xD;}
  173.         if ((adc_VAL>944)&&(adc_VAL<976))
  174.          {KeyNo1=0xE;}
  175.         if ((adc_VAL>1007)&&(adc_VAL<=1023))
  176.          {KeyNo1=0xF;}
  177.       return KeyNo1;
  178.   }
  179. //延時500ms
  180. void delay500ms()  //@12.000MHz
  181. {
  182. unsigned char l,m,n;
  183. _nop_();
  184. _nop_();
  185. l = 23;
  186. m = 205;
  187.     n = 120;
  188. do
  189. {
  190.   do
  191.   {
  192.    while (--n);
  193.   } while (--m);
  194. } while (--l);
  195. }
復制代碼



回復

使用道具 舉報

ID:293534 發表于 2018-5-12 00:25 | 顯示全部樓層
希望有大佬教教我,哎做的好累
回復

使用道具 舉報

ID:299924 發表于 2018-5-12 09:46 | 顯示全部樓層
ADC 初始化,時鐘開了嗎?
回復

使用道具 舉報

ID:293534 發表于 2018-5-12 12:00 | 顯示全部樓層
wj0755 發表于 2018-5-12 09:46
ADC 初始化,時鐘開了嗎?

請問是什么意思?ADC_START我開了啊,ADC_POWER也開了,我是小白不是很懂
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一区二区视频 | 两性午夜视频 | 亚洲视频精品 | 99精品久久 | 国产日韩欧美在线播放 | 久久777| av在线播放国产 | 伊人精品在线 | 日本三级线观看 视频 | 日韩精品一二三区 | www4虎| 欧美三级电影在线播放 | 午夜av成人 | 中文字幕精品一区二区三区精品 | 精品欧美一区二区三区久久久小说 | 日本黄色高清视频 | 亚洲欧美激情精品一区二区 | 精品中文字幕视频 | 国产精品视频一区二区三区不卡 | 国产精品亚洲片在线播放 | 91精品国产色综合久久 | 欧美一级网站 | 久久久久久国产精品久久 | 国产探花在线精品一区二区 | 成人一区二 | 成人亚洲 | 欧美成人手机视频 | 亚洲男人天堂2024 | 91精品国产一二三 | av中文在线| 欧美日韩亚洲国产综合 | 人妖videosex高潮另类 | 日韩欧美在线免费观看 | 中国一级大毛片 | 在线观看成人小视频 | 亚洲国产黄色av | 亚洲精品免费在线观看 | 欧美成人精品 | 色999日韩 | 日日夜夜免费精品视频 | 国产特级毛片aaaaaa喷潮 |