找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機+ADS1115讀數(shù)據(jù)異常,求助高手幫忙解決

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:66862 發(fā)表于 2025-6-5 00:07 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 七彩的夢想 于 2025-6-5 23:44 編輯

最近心血來潮買了幾個ADS1115模塊,想找個時間測驗證一下。發(fā)現(xiàn)模塊配送的資料是Arduino平臺,手頭沒有Arduino硬件,只有STC8G1K08單片機,于是在本論壇找了個現(xiàn)成的51系列的ADS1115代碼修修改改發(fā)現(xiàn)基本能用,但是讀數(shù)據(jù)有點問題,15位數(shù)據(jù)的低4位無法正常讀取,一直為0,用邏輯分析儀看了數(shù)據(jù)波形是正常的沒發(fā)現(xiàn)問題在哪。折騰了好幾天還是沒能解決。我已經(jīng)排除過硬件是沒有問題的,問題應(yīng)該還是出在軟件上,望論壇里的高手幫忙看看指點我一下。謝謝!
ADS1115配置為:單端輸入, A0端口輸入0---5V   滿量程配置為4.096V  正常轉(zhuǎn)換范圍0---32767現(xiàn)在異常轉(zhuǎn)換值范圍是這樣的:0,16,32,48,64,80,96,112,,,,,,,,32752。隨著電壓增加 AD轉(zhuǎn)換值以每16個LSB跳躍累加。

問題重點:低4位數(shù)據(jù)讀回來一直為0


以下是用邏輯分析儀采集的波形圖

異常波形圖

波形圖1



波形圖2



波形圖3



波形圖4



波形圖5



大于0的第一個值




對應(yīng)波形圖5數(shù)據(jù)顯示



最大值




最小值




硬件連接


代碼部分:
  1. /*******************************************************************************************************************************************************************
  2. /*ADS1115+TM1637例程
  3. /*本示例在STC8G1K08A驗證暫不OK
  4. /*工作頻率11.0592MHz
  5. /*編輯日期:2025/05/26,星期一,00:10
  6. *********************************************************************************************************************************************************************/
  7.   #include<AI8G.h>//STC8G系列頭文件
  8.   #define uchar unsigned char  //0---255
  9.   #define uint  unsigned int   //0---65535      
  10.   #define ulong unsigned long  //0---4294967295  
  11.                
  12. ///==================================================================================================================================================================
  13.    bit  Bit0,Bit1,Bit2,Bit3,Bit4,Bit5,Bit6,Bit7,K1_flag,K2_flag,K3_flag,K4_flag,switch_CHN;//8個位變量,對應(yīng)LED1---LED8 ,5個按鍵標(biāo)志位
  14.         sbit  SCL=P3^2;//ADS1115時鐘線
  15.   sbit  SDA=P3^3;//ADS1115數(shù)據(jù)線
  16.   sbit  clk = P5^4;//TM1637時鐘端口
  17.   sbit  dio = P5^5;//TM1637數(shù)據(jù)端口
  18.   uchar buf[6];//6個數(shù)碼管緩存區(qū)
  19.         int D_ADS;   //轉(zhuǎn)換的數(shù)字量
  20.   uint Config;//
  21.   uint Result[2];//
  22.   uchar Writebuff[4],Readbuff[3];//
  23.         
  24. ///==================================================================================================================================================================        
  25. #define TRUE        1    //真
  26. #define FALSE       0    //假
  27. #define ADDRESS_0  0x90  //ADDR PIN ->GND
  28. #define ADDRESS_1  0x92  //ADDR PIN ->VDD
  29. #define ADDRESS_2  0x94  //ADDR PIN ->SDA
  30. #define ADDRESS_3  0x96  //ADDR PIN ->SCL

  31. /************POINTERREGISTER*****************/
  32. #define Pointer_0  0x00  //Convertion register
  33. #define Pointer_1  0x01  //Config register
  34. #define Pointer_2  0x02  //Lo_thresh register
  35. #define Pointer_3  0x03  //Hi_thresh register

  36. /************CONFIG REGISTER*****************/
  37. #define OS_0   0x0000
  38. #define OS_1   0x8000
  39. #define MUX_0  0x0000 //AINp=AIN0, AINn=AIN1
  40. #define MUX_1  0x1000 //AINp=AIN0, AINn=AIN3
  41. #define MUX_2  0x2000 //AINp=AIN1, AINn=AIN3
  42. #define MUX_3  0x3000 //AINp=AIN2, AINn=AIN3
  43. #define MUX_4  0x4000 //AINp=AIN0, AINn=GND
  44. #define MUX_5  0x5000 //AINp=AIN1, AINn=GND
  45. #define MUX_6  0x6000 //AINp=AIN2, AINn=GND
  46. #define MUX_7  0x7000 //AINp=AIN3, AINn=GND

  47. #define PGA_0  0x0000  //FS=6.144V
  48. #define PGA_1  0x0200  //FS=4.096V
  49. #define PGA_2  0x0400  //FS=2.048V
  50. #define PGA_3  0x0600  //FS=1.024V
  51. #define PGA_4  0x0800  //FS=0.512V
  52. #define PGA_5  0x0A00  //FS=0.256V
  53. #define PGA_6  0x0C00  //FS=0.256V
  54. #define PGA_7  0x0E00  //FS=0.256V

  55. #define MODE_0 0x0000  //
  56. #define MODE_1 0x0100  //

  57. #define DR_0   0x0000  //Data Rate = 8
  58. #define DR_1   0x0020  //Data Rate = 16
  59. #define DR_2   0x0040  //Data Rate = 32
  60. #define DR_3   0x0060  //Data Rate = 64
  61. #define DR_4   0x0080  //Data Rate = 128
  62. #define DR_5   0x00A0  //Data Rate = 250
  63. #define DR_6   0x00C0  //Data Rate = 475
  64. #define DR_7   0x00E0  //Data Rate = 860

  65. #define COMP_MODE_0  0x0000
  66. #define COMP_MODE_1  0x0010
  67. #define COMP_POL_0   0x0000
  68. #define COMP_POL_1   0x0008
  69. #define COMP_LAT_0   0x0000
  70. #define COMP_LAT_1   0x0040
  71. #define COMP_QUE_0   0x0000
  72. #define COMP_QUE_1   0x0001
  73. #define COMP_QUE_2   0x0002
  74. #define COMP_QUE_3   0x0003

  75. //*************ADDRInitial********************/
  76. #define ADDRESS    ADDRESS_0    //ADDR PIN ->GND
  77. #define ADDRESS_W  ADDRESS|0x00 //寫地址
  78. #define ADDRESS_R  ADDRESS|0x01 //讀地址

  79. /*************ConfigInitial*********************/
  80. #define OS         OS_1
  81. #define MUX_A0     MUX_4     //AINp=AIN0, AINn=GND
  82. #define MUX_A1     MUX_5     //AINp=AIN1, AINn=GND
  83. #define MUX_A2     MUX_6     //AINp=AIN2, AINn=GND
  84. #define MUX_A3     MUX_7     //AINp=AIN3, AINn=GND
  85. #define PGA        PGA_1     //FS=4.096V分辨率
  86. #define MODE       MODE_1    //Continuous conversion mode
  87. #define DR         DR_0      //Data Rate = 8 轉(zhuǎn)換速率
  88. #define COMP_QUE   COMP_QUE_3
  89. ///==================================================================================================================================================================
  90. void Delay_us(unsigned int i) //N_us 微秒延時
  91. {
  92.   for(;i>0;i--);
  93. }        

  94. ///==================================================================================================================================================================
  95. void Start(void)//IIC開始
  96. {
  97.    SDA=1;
  98.    SCL=1;
  99.          Delay_us (1);
  100.    SDA=0;
  101.          Delay_us (5);
  102.    SCL=0;
  103.    _nop_();  _nop_();
  104.          _nop_();  _nop_();
  105.          _nop_();  _nop_();
  106.          _nop_();  _nop_();
  107. }

  108. ///==================================================================================================================================================================
  109. void Stop(void)//IIC停止
  110. {
  111.         //Delay_us (1);
  112.    SCL=1;
  113.    Delay_us (2);
  114.    SDA=1;
  115. //        Delay_us (5);
  116. //   SCL=0;
  117. //   Delay_us (5);//00&91中間波形
  118. //         SDA=0;
  119. }

  120. ///==================================================================================================================================================================
  121. void ACK(void)//IIC應(yīng)答 7F&F0中間波形
  122. {
  123.    _nop_();
  124.          _nop_();
  125.    SDA=0;
  126.    _nop_();
  127.          _nop_();
  128.    SCL=1;
  129.    Delay_us (4);
  130.    SCL=0;
  131.    SDA=1;
  132. }

  133. ///==================================================================================================================================================================
  134. void NACK(void)//IIC無應(yīng)答
  135. {
  136.    unsigned int x;
  137.    for(x=1;x>0;x--);
  138.    SDA=1;
  139.    _nop_();
  140.          _nop_();
  141.    SCL=1;
  142.    Delay_us (4);
  143.    SCL=0;
  144.    _nop_();
  145.          _nop_();
  146.    SDA=0;   
  147.    Delay_us (2);      
  148. }

  149. ///==================================================================================================================================================================
  150. unsigned char Check(void)//檢查從機是否有應(yīng)答:1--有,0--無
  151. {
  152.    unsigned char slaveack;
  153.    SDA=1;
  154.    _nop_();
  155.           _nop_();
  156.   _nop_();
  157.    SCL=1;
  158.    slaveack = SDA;   //讀入SDA數(shù)值
  159.          Delay_us (5);//90&01中間波形
  160.    SCL=0;
  161.    //Delay_us (1);
  162.    if(slaveack)  
  163.          return FALSE;
  164.    else            
  165.          return TRUE;
  166. }

  167. ///==================================================================================================================================================================
  168. void Write_1_Byte(unsigned char DataByte)//寫一字節(jié)
  169. {
  170.    int i;
  171.          SCL=0;
  172.         
  173.     for(i=0;i<8;i++)
  174.     {
  175.       if(DataByte&0x80)  //if((DataByte<<i)&0x80)
  176.       SDA=1;
  177.       else
  178.                         SDA=0;
  179.                         DataByte <<= 1;
  180.       SCL=1;
  181.       Delay_us (5);//
  182.       SCL=0;
  183.       Delay_us (3);//
  184.     }
  185.       SDA=1;
  186.                
  187. }

  188. ///==================================================================================================================================================================
  189. unsigned char Write_N_Byte(unsigned char*writebuffer,unsigned char n)//寫多字節(jié)
  190. {
  191.     int i;
  192.     for(i=0;i<n;i++)
  193.     {
  194.       Write_1_Byte(*writebuffer);
  195.       if(Check())
  196.       {
  197.         writebuffer++;
  198.       }
  199.       else
  200.       {
  201.         Stop();
  202.                                 return FALSE;
  203.       }
  204.     }
  205.                 Delay_us (1);//
  206.         Stop();
  207.         return TRUE;
  208. }

  209. ///==================================================================================================================================================================
  210. unsigned char Read_1_Byte(void)//讀一字節(jié)
  211. {
  212.    unsigned char data_Value = 0, FLAG, i;  
  213.         for(i=0;i<8;i++)
  214.    {     
  215.      SDA=1;
  216.      Delay_us (3);
  217.      SCL=1;
  218.      Delay_us (3);
  219.      FLAG=SDA;
  220.      data_Value <<= 1;
  221.      if(FLAG)
  222.      data_Value |= 0x01;
  223.      SCL=0;
  224.                  _nop_();_nop_();
  225.                  _nop_();_nop_();
  226.                  _nop_();_nop_();
  227.     }

  228.    return data_Value;
  229. }

  230. ///==================================================================================================================================================================
  231. void Read_N_Byte(unsigned int*readbuff,unsigned char n)//讀多字節(jié)
  232. {
  233.     unsigned char i;
  234.     for(i=0;i<n;i++)
  235.     {
  236.       readbuff[i]=Read_1_Byte();
  237.       if(i==n-1)
  238.       NACK();  //不連續(xù)讀字節(jié)
  239.       else                        
  240.       ACK();//連續(xù)讀字節(jié)
  241.     }
  242.       Stop();
  243. }

  244. ///==================================================================================================================================================================
  245. void WriteWord(void)//寫一個Word
  246. {
  247.     int t;
  248.     Start();   //寫入4個字節(jié)
  249.     do
  250.     {
  251.       t=Write_N_Byte(Writebuff,4);
  252.     }
  253.                 while(t==0);
  254.                 Stop();
  255. }

  256. ///==================================================================================================================================================================
  257. void ReadWord(void)//讀Word
  258. {
  259.    int t;
  260.         
  261.    Start();  //寫入2個字節(jié)
  262.    do
  263.    {
  264.      t=Write_N_Byte(Readbuff,2);
  265.    }
  266.                  while(t==0);
  267.      Start();   //寫入2個字節(jié)
  268.    do
  269.    {
  270.      t=Write_N_Byte(&Readbuff[2],1);
  271.    }
  272.                  while(t==0);
  273.          
  274.      Read_N_Byte(Result,2);  //讀出2個字節(jié)
  275. }

  276. ///==================================================================================================================================================================
  277. void InitADS1115(bit S_MUX_0, bit S_MUX_1)//ADS1115初始化
  278. {      
  279.    if(S_MUX_0 == 0 && S_MUX_1 == 0)         //AIN0
  280.    Config= OS+MUX_A0+PGA+DR+COMP_QUE+MODE;//【OS=1開始ADC轉(zhuǎn)換】+【MUX_A0通道0】+【PGA 電壓量程FS=4.096】+【DR總線數(shù)據(jù)速率】+【COMP_QUE ALERT引腳輸出配置】+【MODE=0x0000 連續(xù)轉(zhuǎn)換 MODE=0x0100單次轉(zhuǎn)換】;

  281.    if(S_MUX_0 == 0 && S_MUX_1 == 1)         //AIN1
  282.    Config= OS+MUX_A1+PGA+DR+COMP_QUE+MODE;//【OS=1開始ADC轉(zhuǎn)換】+【MUX_A0通道0】+【PGA 電壓量程FS=4.096】+【DR總線數(shù)據(jù)速率】+【COMP_QUE ALERT引腳輸出配置】+【MODE=0x0000 連續(xù)轉(zhuǎn)換 MODE=0x0100單次轉(zhuǎn)換】;

  283.    if(S_MUX_0 == 1 && S_MUX_1 == 0)         //AIN2
  284.    Config= OS+MUX_A2+PGA+DR+COMP_QUE+MODE;//【OS=1開始ADC轉(zhuǎn)換】+【MUX_A0通道0】+【PGA 電壓量程FS=4.096】+【DR總線數(shù)據(jù)速率】+【COMP_QUE ALERT引腳輸出配置】+【MODE=0x0000 連續(xù)轉(zhuǎn)換 MODE=0x0100單次轉(zhuǎn)換】;

  285.    if(S_MUX_0 == 1 && S_MUX_1 == 1)         //AIN3
  286.    Config= OS+MUX_A3+PGA+DR+COMP_QUE+MODE;//【OS=1開始ADC轉(zhuǎn)換】+【MUX_A0通道0】+【PGA 電壓量程FS=4.096】+【DR總線數(shù)據(jù)速率】+【COMP_QUE ALERT引腳輸出配置】+【MODE=0x0000 連續(xù)轉(zhuǎn)換 MODE=0x0100單次轉(zhuǎn)換】;

  287.    Writebuff[0]=ADDRESS_W;//寫數(shù)據(jù),從機地址0x90(最低位bit0決定讀寫操作R/W 0讀 1寫)
  288.    Writebuff[1]=Pointer_1;//數(shù)據(jù)要寫入的寄存器地址(地址指針,0x01)
  289.    Writebuff[2]=Config/256;//參數(shù)配置寄存器高8位【對應(yīng)OS,MUX,PGA,MODE】
  290.    Writebuff[3]=Config%256;//參數(shù)配置寄存器低8位【對應(yīng)DR,COMP_MODE,COMP_POL,COMP_LAT,COMP_QUE】
  291.      
  292.    Readbuff[0]=ADDRESS_W;//寫數(shù)據(jù),從機地址0x90(最低位bit0決定讀寫操作R/W 0讀 1寫)
  293.    Readbuff[1]=Pointer_0;//數(shù)據(jù)要寫入的寄存器地址(地址指針,0x00)  
  294.    Readbuff[2]=ADDRESS_R;//讀數(shù)據(jù),從機地址0x91(最低位bit0決定讀寫操作R/W 0讀 1寫)
  295. }

  296. ///==================================================================================================================================================================
  297. unsigned int ADS1115(bit S_MUX_0, bit S_MUX_1)//從指定AD輸入通道讀取AD轉(zhuǎn)換值
  298. {
  299.    InitADS1115(S_MUX_0, S_MUX_1);
  300.    WriteWord();
  301.    ReadWord();      
  302.    D_ADS=Result[0]*256+Result[1];   //轉(zhuǎn)換的數(shù)字量
  303.    return D_ADS;
  304. }        

  305. ///==================================================================================================================================================================        
  306.   uint ADC_operation()//ADC數(shù)據(jù)運算處理
  307.   {
  308.                 static unsigned char count = 0;//ADC采樣次數(shù),計數(shù)
  309.     static unsigned long sum   = 0;//ADC采樣總數(shù),“和”
  310.     static unsigned int AD_Value = 0;//處理好的平均值
  311.                 static unsigned int AD_temp  = 0;//未處理的AD值
  312.                
  313.                 AD_Value=ADS1115(0,0);    //ADS1115取值_AIN0
  314.         //AD_temp=ADS1115(0,0);    //ADS1115取值_AIN0
  315.         //AD_Value=Result[0];//調(diào)試用
  316.          //AD_Value=Result[1];//調(diào)試用
  317. //                Delay_us (5);
  318.                
  319. //    if(count < 100)//如果采集次數(shù)小于100
  320. //                {
  321. //      sum += AD_temp;//AD值累計
  322. //      count++;//采樣計數(shù)加一
  323. //    }
  324. //               
  325. //    if(count >= 100)//如果采集次數(shù)大于等于100
  326. //                {
  327. //      AD_Value = sum / 100;//總數(shù)“和”除100,慮除波動值
  328. //      count = 0;//采集次數(shù)清零
  329. //      sum   = 0;//總數(shù)“和”變量清零
  330. //    }        
  331.                         return AD_Value;//返回處理好的AD值
  332.         }

  333. ///==================================================================================================================================================================        
  334.                                                        /* 往下是TM1637代碼區(qū)域 */
  335. ///==================================================================================================================================================================        

  336.   uchar key_data,key_value;//按鍵處理過程變量
  337.   uint  Display;//待顯示數(shù)據(jù)
  338.   uchar code SMG_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};//0-F編碼表
  339. //uchar code key_table[]={0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef};//key1--key16按鍵倒序識別碼
  340.   uchar code key_table[]={0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0,0xef,0xee,0xed,0xec,0xeb,0xea,0xe9,0xe8};//key1--key16按鍵順序識別碼
  341.         
  342. ///==================================================================================================================================================================
  343.         void init() //初始化函數(shù)
  344.         {
  345.           P3M0 = 0x0c; P3M1 = 0x0c;
  346.                 //P3M0 = 0x00; P3M1 = 0x00;//IO口模式配置【準(zhǔn)雙向口】
  347.     P5M0 = 0x00; P5M1 = 0x00;//IO口模式配置【準(zhǔn)雙向口】
  348.     switch_CHN=1;//指定顯示內(nèi)容               
  349.         }
  350.         
  351. ///==================================================================================================================================================================        
  352. //  void Delay_us(unsigned int i) //N_us 微秒延時
  353. //  {
  354. //                unsigned char j;
  355. //    for(;i>0;i--)
  356. //    for(j=10;j>0;j--);
  357. //  }        

  358. ///==================================================================================================================================================================
  359.   void I2CStart(void)//TM1637 開始
  360.   {
  361.     clk = 1;
  362.     dio = 1;
  363.     Delay_us(2);
  364.     dio = 0;
  365.   }
  366.         
  367. ///==================================================================================================================================================================
  368.   void I2Cask(void)//TM1637 應(yīng)答
  369.   {
  370.     clk = 0;
  371.     Delay_us(5);//在第八個時鐘下降沿之后延時 5us,開始判斷 ACK 信號
  372.     while(dio);
  373.     clk = 1;
  374.     Delay_us(2);
  375.     clk=0;
  376.   }
  377.         
  378. ///==================================================================================================================================================================
  379.   void I2CStop(void)//TM1637 停止
  380.   {
  381.     clk = 0;
  382.     Delay_us(2);
  383.     dio = 0;
  384.     Delay_us(2);
  385.     clk = 1;
  386.     Delay_us(2);
  387.     dio = 1;
  388.   }
  389.         
  390. ///==================================================================================================================================================================
  391.   void I2CWrByte(unsigned char oneByte)//TM1637 寫一個字節(jié)
  392.   {
  393.     unsigned char i;
  394.     for(i=0;i<8;i++)
  395.     {  
  396.                   clk = 0;
  397.       if(oneByte&0x01)//低位在前
  398.       {dio = 1;}
  399.       else
  400.       {dio = 0;}
  401.       Delay_us(3);
  402.       oneByte=oneByte>>1;
  403.       clk=1;
  404.       Delay_us(3);
  405.     }
  406.   }
  407.         
  408. ///==================================================================================================================================================================
  409.   unsigned char Scankey(void)//TM1637 讀按鍵
  410.   {
  411.     unsigned char rekey,i;
  412.     I2CStart();
  413.     I2CWrByte(0x42);//讀按鍵命令
  414.     I2Cask();
  415.     dio=1; //在讀按鍵前拉高數(shù)據(jù)線
  416.     for(i=0;i<8;i++)//從低位開始讀
  417.     {  
  418.                   clk=0;
  419.       rekey=rekey>>1;
  420.       Delay_us(30);
  421.       clk=1;
  422.       if(dio)
  423.       {rekey=rekey|0x80;}
  424.       else
  425.       {rekey=rekey|0x00;}
  426.       Delay_us(30);
  427.     }
  428.       I2Cask();
  429.       I2CStop();
  430.       return (rekey);
  431.   }
  432.         
  433. ///==================================================================================================================================================================
  434.   void SMG_Display(void)//TM1637 寫顯示寄存器
  435.   {
  436.     unsigned char i;
  437.     I2CStart();
  438.     I2CWrByte(0x40); // 40H 地址自動加 1 模式,44H 固定地址模式,本程序采用自加 1 模式
  439.     I2Cask();
  440.     I2CStop();
  441.     I2CStart();
  442.     I2CWrByte(0xc0);//設(shè)置首地址,
  443.     I2Cask();
  444.     for(i=0;i<6;i++)//地址自加,不必每次都寫地址
  445.     {
  446.       if(i<5)
  447.       {I2CWrByte(SMG_table[buf[i]]);}//送數(shù)據(jù)
  448.       else
  449.       {I2CWrByte(buf[5]);}//送數(shù)據(jù)        
  450.       I2Cask();
  451.     }
  452.     I2CStop();
  453.     I2CStart();
  454.     I2CWrByte(0x8f);//開顯示 ,最大亮度
  455.     I2Cask();
  456.     I2CStop();
  457.   }
  458.         
  459. ///==================================================================================================================================================================
  460.   void key_inquiry(unsigned char key_data)//TM1637 按鍵ID查詢,識別按鍵
  461.   {
  462.     uchar i;
  463.     for(i=0;i<16;i++)
  464.     {if(key_data==key_table[i])break;}
  465.     key_value=i;//查詢到的ID號
  466.   }
  467.         
  468. ///==================================================================================================================================================================
  469.   unsigned char set_led()//合并8個二進(jìn)制位成一個字節(jié)
  470.   {
  471.           unsigned char Byte = 0;
  472.     unsigned char Temp;

  473.     Temp = (unsigned char)Bit0;
  474.     Byte |= (Temp & 1) << 0;

  475.     Temp = (unsigned char)Bit1;
  476.     Byte |= (Temp & 1) << 1;

  477.     Temp = (unsigned char)Bit2;
  478.     Byte |= (Temp & 1) << 2;

  479.     Temp = (unsigned char)Bit3;
  480.     Byte |= (Temp & 1) << 3;

  481.     Temp = (unsigned char)Bit4;
  482.     Byte |= (Temp & 1) << 4;

  483.     Temp = (unsigned char)Bit5;
  484.     Byte |= (Temp & 1) << 5;

  485.     Temp = (unsigned char)Bit6;
  486.     Byte |= (Temp & 1) << 6;

  487.     Temp = (unsigned char)Bit7;
  488.     Byte |= (Temp & 1) << 7;

  489.     return Byte;
  490.   }
  491.         
  492. ///==================================================================================================================================================================               
  493.   void main(void)//主函數(shù)
  494.   {
  495.     init();//初始化

  496.    while(1)//循環(huán)體
  497.    {         

  498.            Bit0=1;//Mot    (LED1)對應(yīng)set_led()函數(shù)里面的Bit0
  499.      Bit1=0;//Ch4    (LED2)對應(yīng)set_led()函數(shù)里面的Bit1
  500.      Bit2=0;//Valley (LED3)對應(yīng)set_led()函數(shù)里面的Bit2
  501.      Bit3=0;//Ch3    (LED4)對應(yīng)set_led()函數(shù)里面的Bit3
  502.      Bit4=0;//Peak   (LED5)對應(yīng)set_led()函數(shù)里面的Bit4
  503.      Bit5=0;//Ch2    (LED6)對應(yīng)set_led()函數(shù)里面的Bit5
  504.      Bit6=0;//Net    (LED7)對應(yīng)set_led()函數(shù)里面的Bit6
  505.      Bit7=0;//Ch1    (LED8)對應(yīng)set_led()函數(shù)里面的Bit7
  506.                  
  507.                  if(switch_CHN==1){Display=ADC_operation();}//顯示ADC值
  508.                  if(switch_CHN==0){if(key_value==0){if(K1_flag==0){K1_flag=1;Display=12345;}}else{K1_flag=0;}}//KEY1按鍵事件處理
  509.                  if(switch_CHN==0){if(key_value==1){if(K2_flag==0){K2_flag=1;if(Display>0){Display--;}}}else{K2_flag=0;}}//KEY2按鍵事件處理
  510.                  if(key_value==2){if(K3_flag==0){K3_flag=1;switch_CHN=~switch_CHN;}}else{K3_flag=0;}//KEY3按鍵事件處理
  511.                  if(switch_CHN==0){if(key_value==3){if(K4_flag==0){K4_flag=1;if(Display<65535){Display++;}}}else{K4_flag=0;}}//KEY4按鍵事件處理
  512.                           
  513.      key_data=Scankey();//讀出的按鍵值不作處理。
  514.      key_inquiry(key_data);//按鍵ID號查詢函數(shù)
  515.    //if(key_data!=0xff){key_value=16;}//如果沒有按鍵按下,顯示空白(編碼表第16個元素,對應(yīng)不顯示)
  516.          //Display=12345;//數(shù)碼管顯示內(nèi)容
  517.          //buf[4]=key_value;//按鍵ID號顯示
  518.                  
  519.      if(Display>999){buf[0]=Display%100000/10000;}else{buf[0]=16;}//萬
  520.      if(Display>999){buf[1]=Display%10000/1000;}else{buf[1]=16;}//千
  521.      if(Display>99){buf[2]=Display%1000/100;}else{buf[2]=16;}//百
  522.      if(Display>9){buf[3]=Display%100/10;}else{buf[3]=16;}//十
  523.      buf[4]=Display%10;//個        
  524.      buf[5]= set_led();//8個LED燈輸出控制,通過Bit0---Bit7設(shè)置LED狀態(tài)
  525.                  
  526.      SMG_Display();//數(shù)碼管顯示控制                                                                                                        
  527.    }
  528.          
  529.   }
  530.         
  531.         
  532.       




復(fù)制代碼
下面是滿量程的時候?qū)?yīng)的波形圖



視頻展示:

https://v.youku.com/video?vid=XNjQ4NDEwMDYwNA%3D%3D

ADS1115_STC8G1K08A.rar

53.14 KB, 下載次數(shù): 0

工程文件

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

使用道具 舉報

沙發(fā)
ID:1121801 發(fā)表于 2025-6-5 10:44 | 只看該作者
感覺很復(fù)雜,我進(jìn)來是標(biāo)記一下等著學(xué)習(xí)的,大神快出來
回復(fù)

使用道具 舉報

板凳
ID:155507 發(fā)表于 2025-6-5 16:42 | 只看該作者
AI的回復(fù)。

根據(jù)你的描述(“15位數(shù)據(jù)的低4位無法正常讀取,一直為0”),結(jié)合你提供的ADS1115驅(qū)動代碼,這里分析可能的原因和解決方案:

---

## 1. **ADS1115數(shù)據(jù)格式分析**

ADS1115是16位ADC,但實際有效數(shù)據(jù)為15位(最高位為符號位,單端輸入時符號位為0)。數(shù)據(jù)寄存器為2字節(jié),結(jié)構(gòu)如下:


15  14   13   12   11   10    9    8    7    6    5     4     3   2    1   0
S   D14 D13 D12 D11 D10 D9  D8  D7  D6  D5  D4  D3  D2  D1  D0

其中,S為符號位(單端輸入時為0),D14~D0為數(shù)據(jù)位。

你代碼中的讀取方式為:

D_ADS = Result[0] * 256 + Result[1];

這里`Result`和`Result[1]`分別對應(yīng)高字節(jié)和低字節(jié)。

---

## 2. **低4位為0的可能原因**

### **(1)數(shù)據(jù)拼接問題**

- **Result和Result[1]的類型是否正確?**
  - 如果`Result`數(shù)組定義為`unsigned int`,而你用`Read_N_Byte(Result, 2);`讀取數(shù)據(jù),那么`Result`和`Result[1]`應(yīng)該分別對應(yīng)高字節(jié)和低字節(jié)。
  - 但`Read_N_Byte`函數(shù)原型為`void Read_N_Byte(unsigned int*readbuff,unsigned char n)`,而`Read_1_Byte`返回的是`unsigned char`,所以`readbuff[i] = Read_1_Byte();`會把每個字節(jié)存到`unsigned int`數(shù)組的一個單元里,而不是連續(xù)存兩個字節(jié)。
  - **正確做法**:`Result`應(yīng)該定義為`unsigned char Result[2];`,然后`Read_N_Byte(Result, 2);`(此時函數(shù)參數(shù)類型也要改為`unsigned char*`)。
  - **你目前的實現(xiàn)**:`Result`和`Result[1]`都是`unsigned int`,每個單元只存了一個字節(jié),但拼接時直接相加,低字節(jié)可能被高位覆蓋或未正確賦值。

### **(2)I2C讀取時序問題**

- **I2C讀取時,是否完整讀取了兩個字節(jié)?**
  - 確保`Read_N_Byte`函數(shù)正確讀取了兩個字節(jié),且低字節(jié)(Result[1])的數(shù)據(jù)沒有被丟棄或覆蓋。
  - 檢查`Read_1_Byte`函數(shù)是否正確返回每個字節(jié)。

### **(3)ADS1115配置問題**

- **是否配置為單端輸入、正確通道、正確PGA?**
  - 你的代碼中配置為單端輸入(MUX_A0~A3),PGA為4.096V,基本沒問題。
- **是否配置為連續(xù)轉(zhuǎn)換模式?**
  - 你的代碼中`MODE = MODE_1`(連續(xù)轉(zhuǎn)換),建議改為單次轉(zhuǎn)換(MODE_0),并在每次讀取前啟動轉(zhuǎn)換。

### **(4)數(shù)據(jù)對齊問題**

- **如果Result和Result[1]都是unsigned int,且每個單元只存了一個字節(jié),那么低字節(jié)的低4位可能被高位覆蓋。**
  - 例如,如果`Result = 0x12`,`Result[1] = 0x34`,拼接時`Result * 256 + Result[1]`理論上沒問題,但如果`Result[1]`的值不正確(比如被覆蓋或未賦值),那么低4位會為0。

---

## 3. **解決方案**

### **(1)修改Result數(shù)組類型**


unsigned char Result[2]; // 改為unsigned char


### **(2)修改Read_N_Byte函數(shù)**


void Read_N_Byte(unsigned char *readbuff, unsigned char n)
{
    unsigned char i;
    for(i = 0; i < n; i++)
    {
        readbuff[i] = Read_1_Byte();
        if(i == n - 1)
            NACK();  // 不連續(xù)讀字節(jié)
        else
            ACK();   // 連續(xù)讀字節(jié)
    }
    Stop();
}


### **(3)修改數(shù)據(jù)拼接方式**


D_ADS = ((unsigned int)Result[0] << 8) | Result[1];


### **(4)檢查I2C時序和硬件連接**

- **確保SCL和SDA引腳配置正確,無干擾。**
- **確保ADS1115供電和參考電壓正常。**

### **(5)建議改為單次轉(zhuǎn)換模式**


#define MODE MODE_0  // 單次轉(zhuǎn)換

并在每次讀取前寫入配置寄存器啟動轉(zhuǎn)換。

---

## 4. **總結(jié)**

- **低4位為0的根本原因很可能是Result數(shù)組類型和Read_N_Byte函數(shù)實現(xiàn)不匹配,導(dǎo)致低字節(jié)數(shù)據(jù)未正確保存。**
- **建議將Result改為unsigned char數(shù)組,并修改Read_N_Byte函數(shù)為unsigned char*類型。**
- **數(shù)據(jù)拼接時使用位操作,確保低字節(jié)不被覆蓋。**

---

## 5. **示例修正代碼片段**


unsigned char Result[2]; // 改為unsigned char

void Read_N_Byte(unsigned char *readbuff, unsigned char n)
{
    unsigned char i;
    for(i = 0; i < n; i++)
    {
        readbuff[i] = Read_1_Byte();
        if(i == n - 1)
            NACK();
        else
            ACK();
    }
    Stop();
}

// 讀取數(shù)據(jù)
Read_N_Byte(Result, 2);
D_ADS = ((unsigned int)Result[0] << 8) | Result[1];


這樣修改后,低4位數(shù)據(jù)應(yīng)該能正常讀取[1]。
回復(fù)

使用道具 舉報

地板
ID:66862 發(fā)表于 2025-6-5 23:33 | 只看該作者
angmall 發(fā)表于 2025-6-5 16:42
AI的回復(fù)。

根據(jù)你的描述(“15位數(shù)據(jù)的低4位無法正常讀取,一直為0”),結(jié)合你提供的ADS1115驅(qū)動代碼 ...

感謝你的解答與幫助,我抽個時間好好檢查一下
回復(fù)

使用道具 舉報

5#
ID:66862 發(fā)表于 2025-6-5 23:41 | 只看該作者
從波形圖上看,讀回來的數(shù)據(jù)就有問題,是滿量程的時候?qū)?yīng)數(shù)據(jù) 7F F0
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

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