找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 4673|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

關(guān)于STC12C5A60S2單片機(jī)AD讀取值跳動(dòng)的問(wèn)題

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
之前我的程序能夠讀取AD值,但是會(huì)跳動(dòng),而且初始的電壓不是0V,現(xiàn)在我程序修改以后,它是穩(wěn)定了,讀不了AD了是怎么回事?只能讀到0.01V?


  1. #include "reg52.h"                                                   
  2. #include "intrins.h"  

  3. typedef  unsigned char uchar;                                               
  4. typedef  unsigned int uint;   
  5. #define  _Nop() _nop_()

  6. /*------------------------以下為L(zhǎng)CD1602顯示模塊定義-----------------------*/
  7. unsigned char data_char_table[]= {"0123456789ABCDEF"};                        //LCD數(shù)據(jù)
  8. unsigned char Lcd_Dis1_table[] = {"Position:No.    "};                        //第一行顯示框架
  9. unsigned char pos_char_table[] = {"             D  "};                        //      顯示位置
  10. unsigned char Lcd_Dis2_table[] = {"Voltage :      V"};                        //第二行顯示框架
  11. unsigned char num_char_table[] = {"         9A.CD V"};                        //      顯示位置


  12. sbit lcd_rs_port = P2^4;                                                 //定義LCD控制端口,根據(jù)硬件調(diào)整
  13. sbit lcd_rw_port = P2^3;                                                                                
  14. sbit lcd_en_port = P2^2;
  15. #define lcd_data_port P0

  16. void lcd_delay(uchar ms);                                                                        //LCD1602 延時(shí)
  17. void lcd_busy_wait();                                                                                 //LCD1602 忙等待
  18. void lcd_command_write(uint command);                                                 //LCD1602 命令字寫(xiě)入
  19. void lcd_system_reset();                                                                                //LCD1602 初始化
  20. void lcd_char_write(uint x_pos,y_pos,lcd_dat);                                         //LCD1602 字符寫(xiě)入
  21. void lcd_bad_check();                                                                                 //LCD1602 壞點(diǎn)檢查
  22. void Num_to_Disp(uchar i, uint Num);                                                        //顯示數(shù)據(jù)處理
  23. void LcdDisp(uchar j, uint num);                                                                //液晶顯示函數(shù)

  24. /*------------------------以下為ADC相應(yīng)寄存器初始化及端口定義-------------*/                           
  25. /***** 定義與ADC相關(guān)的特殊功能寄存器 *****/                       
  26. sfr  ADC_CONTR =  0xBC;                 //ADC控制寄存器                    
  27. sfr  ADC_RES   =  0xBD;                 //ADC hight 8-bit result register
  28. sfr  ADC_RESL  =  0xBE;                 //ADC low 2-bit result register
  29. sfr  P1ASF     =  0x9D;                 //P1口功能控制寄存器P1ASF
  30. sfr  P1M0      =  0x92;                  //I/O模式寄存器
  31. sfr  P1M1      =  0x91;                  //I/O模式寄存器
  32. /************定義相應(yīng)操作位***************/
  33. #define  ADC_POWER          0x80            //ADC電源控制位,0:關(guān)閉,1:打開(kāi)
  34. #define  ADC_FLAG           0x10            //ADC結(jié)束標(biāo)志位
  35. #define  ADC_START          0x08            //ADC啟動(dòng)控制位
  36. #define  ADC_SPEEDLL        0x00            //540 clocks___________選擇轉(zhuǎn)換速度

  37. /*------------------------以下為相關(guān)函數(shù)聲明------------------------------*/
  38. void InitADC();                                                                                                        //ADC初始化
  39. uint GetADCResult(uchar ch);                                                                                                                                                                        
  40. void Delay(uint n);                                                                                         //延時(shí)程序
  41. void delay_1ms(uchar x);



  42. /*-------------------------------- ADC 取值 ------------------------------*/
  43. uint GetADCResult(uchar channel)
  44. {
  45.         ADC_CONTR=0x88|channel;    //開(kāi)啟AD轉(zhuǎn)換1000 1000 即POWER SPEED1 SPEED0 ADC_FLAG   ADC_START CHS2 CHS1 CHS0
  46.         _nop_(); _nop_(); _nop_(); _nop_();//要經(jīng)過(guò)4個(gè)CPU時(shí)鐘的延時(shí),其值才能夠保證被設(shè)置進(jìn)ADC_CONTR 寄存器         
  47. //        ADC_RES=0xdf;
  48. //        ADC_RESL=0xef;
  49.         while(!(ADC_CONTR&0x10));    //等待轉(zhuǎn)換完成
  50.         ADC_CONTR&=0xe7;      //關(guān)閉AD轉(zhuǎn)換,ADC_FLAG位由軟件清0
  51.         return(ADC_RES*4+ADC_RESL);   //返回AD轉(zhuǎn)換完成的10位數(shù)據(jù)(16進(jìn)制)
  52. }



  53. /*---------------------------- 初始化ADC特殊功能寄存器 -------------------*/

  54. void InitADC( )
  55. {
  56.         
  57.           P1ASF = P1 | 0x3f;                //Set  P1.0 - P1.5 as analog input port
  58.           ADC_RES  = 0;                  //Clear previous result
  59.           ADC_RESL = 0;
  60.           ADC_CONTR = ADC_POWER | ADC_SPEEDLL ;
  61.           Delay(20);                      //ADC power-on delay and Start A/D conversion
  62. }
  63. /*---------------------------- LCD1602相應(yīng)函數(shù) ---------------------------*/

  64. ///////////////以下為L(zhǎng)CD顯示數(shù)據(jù)處理/////////////////
  65. void Num_to_Disp(uchar i, uint Num)
  66. {
  67.         float NUM;
  68.         int xx, yy, zz;
  69.         NUM =(Num * 5/ 1024.0);        //計(jì)算公式:10-bit A/D Conversion Result = 1024 x (Vin / Vcc)
  70.         xx = (int)NUM;
  71.         yy = (int)((NUM - (float)(xx)) * 10);
  72.         zz = (int)((NUM - (float)(xx)) * 100)%10;  

  73.         num_char_table[9] = data_char_table[xx / 10];                //電壓值十位
  74.         num_char_table[10]= data_char_table[xx % 10];                //電壓值個(gè)位
  75.         num_char_table[12]= data_char_table[yy];                        //電壓值小數(shù)點(diǎn)后一位
  76.         num_char_table[13]= data_char_table[zz];                        //電壓值小數(shù)點(diǎn)后兩位?

  77.         pos_char_table[13]= data_char_table[i];                        //當(dāng)前ADC接口
  78. }
  79. //////////////////以下為L(zhǎng)CD顯示////////////////////
  80. void LcdDisp(uchar j, uint num)
  81. {
  82.         uint i=0;

  83.         for (i=0;i<16;i++)
  84.         {
  85.                 lcd_char_write(i,0,Lcd_Dis1_table[i]);
  86.                 lcd_char_write(i,1,Lcd_Dis2_table[i]);                  //顯示框架
  87.         }
  88.         Num_to_Disp(j, num);
  89.         lcd_char_write(13,0,pos_char_table[13]);
  90.         for(i = 9; i < 14; i++)
  91.         {
  92.                 lcd_char_write(i,1,num_char_table[i]);                  //顯示電壓
  93.         }                                                                                         
  94.         delay_1ms(100);
  95. }
  96. //////////////以下是LCD1602驅(qū)動(dòng)程序////////////////

  97. void lcd_delay(uchar ms) /*LCD1602 延時(shí)*/
  98. {
  99.     uchar j;
  100.     while(ms--){
  101.         for(j=0;j<250;j++)
  102.             {;}
  103.         }   
  104. }

  105. void lcd_busy_wait() /*LCD1602 忙等待*/
  106. {
  107.     lcd_rs_port = 0;
  108.     lcd_rw_port = 1;
  109.     lcd_en_port = 1;
  110.     lcd_data_port = 0xff;
  111.     while (lcd_data_port&0x80);
  112.     lcd_en_port = 0;

  113. }

  114. void lcd_command_write(uint command) /*LCD1602 命令字寫(xiě)入*/
  115. {
  116.     lcd_busy_wait();
  117.     lcd_rs_port = 0;
  118.     lcd_rw_port = 0;
  119.     lcd_en_port = 0;
  120.     lcd_data_port = command;
  121.     lcd_en_port = 1;
  122.     lcd_en_port = 0;     
  123. }

  124. void lcd_system_reset() /*LCD1602 初始化*/
  125. {
  126.     lcd_delay(20);
  127.     lcd_command_write(0x38);
  128.     lcd_delay(100);
  129.     lcd_command_write(0x38);
  130.     lcd_delay(50);
  131.     lcd_command_write(0x38);
  132.     lcd_delay(10);
  133.     lcd_command_write(0x08);
  134.     lcd_command_write(0x01);
  135.     lcd_command_write(0x06);
  136.     lcd_command_write(0x0c);
  137. }

  138. void lcd_char_write(uint x_pos,y_pos,lcd_dat) /*LCD1602 字符寫(xiě)入*/
  139. {
  140.     x_pos &= 0x0f; /* X位置范圍 0~15 */
  141.     y_pos &= 0x01; /* Y位置范圍 0~ 1 */
  142.     if(y_pos==1) x_pos += 0x40;
  143.     x_pos += 0x80;
  144.     lcd_command_write(x_pos);
  145.     lcd_busy_wait();
  146.     lcd_rs_port = 1;
  147.     lcd_rw_port = 0;
  148.     lcd_en_port = 0;
  149.     lcd_data_port = lcd_dat;
  150.     lcd_en_port = 1;
  151.     lcd_en_port = 0;
  152. }
  153. void lcd_bad_check() /*LCD1602 壞點(diǎn)檢查*/
  154. {
  155.     char i,j;
  156.     for(i=0;i<2;i++){
  157.         for(j=0;j<16;j++) {
  158.             lcd_char_write(j,i,0xff);
  159.             }
  160.         }
  161.     lcd_delay(200);
  162.     lcd_delay(200);
  163.         lcd_delay(200);
  164.         lcd_delay(100);
  165.         lcd_delay(200);
  166.     lcd_command_write(0x01); /* clear lcd disp */
  167. }
  168. //////////////////以上是LCD1602驅(qū)動(dòng)程序////////////////
  169. /*-----------------------------    延時(shí)程序    ---------------------------*/                    
  170. void Delay(uint n)                                                                                 
  171. {
  172.           uint x;

  173.           while (n--)
  174.            {
  175.                      x = 500;
  176.                      while (x--);
  177.            }
  178. }  
  179. /*1MS為單位的延時(shí)程序*/
  180. void delay_1ms(uchar x)
  181. {
  182.     uchar j;
  183. while(x--)
  184. {
  185.         for(j=0;j<125;j++)
  186.             {;}
  187.     }   
  188. }  

  189. /*****************************************************************
  190. 函數(shù): averageValueVolgate()
  191. 用途: 求多次采集電壓平均值
  192. 傳入?yún)?shù):chan是端口號(hào)
  193. 返回值:Val_Av是多次采樣的電壓值平均值  
  194. ******************************************************************/
  195. float averageValueVolgate(uchar chan)
  196. {
  197.         float voltageValue=0;
  198.         uchar num;
  199.         for(num=100;num>0;num--)
  200.         {
  201.                 voltageValue+=GetADCResult(chan);
  202.         }
  203.         voltageValue/=100.0;
  204.         voltageValue=voltageValue*5.0/1024;
  205.         return (voltageValue);
  206. }


  207. /*-------------------------------- 主函數(shù) --------------------------------*/                                             
  208. void main()
  209. {
  210.                 uchar i;
  211.                 lcd_system_reset();                                                   //LCD1602 初始化
  212.                 lcd_bad_check();                                                           //LCD1602 壞點(diǎn)檢查
  213.         InitADC();                                      //初始化ADC特殊功能寄存器
  214.         //        P1M1 = 0xFF;                                         //P1.0/P1.5高阻 0011 1111
  215.       //  P1M0 = 0x00;                                         //P1.0/P1.5高阻 0000 0000
  216.         while (1)
  217.      {         
  218.          i = 0;
  219.          LcdDisp(i,averageValueVolgate(0));      //液晶1602顯示第3通道電壓值
  220.          Delay(1000);
  221.      }                        
  222. }
復(fù)制代碼


評(píng)分

參與人數(shù) 1黑幣 +10 收起 理由
cciejs12345 + 10

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:309126 發(fā)表于 2018-5-17 21:23 | 只看該作者
這是液晶顯示的結(jié)果

777.JPG (1.72 MB, 下載次數(shù): 33)

777.JPG
回復(fù)

使用道具 舉報(bào)

板凳
ID:309126 發(fā)表于 2018-5-18 14:46 | 只看該作者
沒(méi)人嗎
回復(fù)

使用道具 舉報(bào)

地板
ID:213173 發(fā)表于 2018-5-18 21:11 | 只看該作者

見(jiàn)前貼《關(guān)于STC12C5A60S2單片機(jī)AD采樣電壓跳動(dòng)不準(zhǔn)的問(wèn)題》的回復(fù)。
回復(fù)

使用道具 舉報(bào)

5#
ID:208262 發(fā)表于 2018-5-19 11:40 | 只看該作者
怎么回復(fù)這么多,還沒(méi)有明白呢,前面的回答可以的
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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