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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 439|回復: 4
收起左側

單片機+ADS1115讀數據異常,求助高手幫忙解決

[復制鏈接]
ID:66862 發表于 2025-6-5 00:07 | 顯示全部樓層 |閱讀模式
本帖最后由 七彩的夢想 于 2025-6-5 23:44 編輯

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

問題重點:低4位數據讀回來一直為0


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

異常波形圖

低4位異常

低4位異常


波形圖1
波形圖1.png


波形圖2

波形圖2

波形圖2



波形圖3
波形圖3.png


波形圖4

波形圖4

波形圖4



波形圖5

波形圖5

波形圖5



大于0的第一個值

大于0的第一個值

大于0的第一個值




對應波形圖5數據顯示

對應波形圖5數據顯示

對應波形圖5數據顯示



最大值

最大值

最大值




最小值

最小值

最小值




硬件連接

硬件連接

硬件連接


代碼部分:
  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個位變量,對應LED1---LED8 ,5個按鍵標志位
  14.         sbit  SCL=P3^2;//ADS1115時鐘線
  15.   sbit  SDA=P3^3;//ADS1115數據線
  16.   sbit  clk = P5^4;//TM1637時鐘端口
  17.   sbit  dio = P5^5;//TM1637數據端口
  18.   uchar buf[6];//6個數碼管緩存區
  19.         int D_ADS;   //轉換的數字量
  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 轉換速率
  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應答 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無應答
  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)//檢查從機是否有應答:1--有,0--無
  151. {
  152.    unsigned char slaveack;
  153.    SDA=1;
  154.    _nop_();
  155.           _nop_();
  156.   _nop_();
  157.    SCL=1;
  158.    slaveack = SDA;   //讀入SDA數值
  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)//寫一字節
  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)//寫多字節
  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)//讀一字節
  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)//讀多字節
  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();  //不連續讀字節
  239.       else                        
  240.       ACK();//連續讀字節
  241.     }
  242.       Stop();
  243. }

  244. ///==================================================================================================================================================================
  245. void WriteWord(void)//寫一個Word
  246. {
  247.     int t;
  248.     Start();   //寫入4個字節
  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個字節
  262.    do
  263.    {
  264.      t=Write_N_Byte(Readbuff,2);
  265.    }
  266.                  while(t==0);
  267.      Start();   //寫入2個字節
  268.    do
  269.    {
  270.      t=Write_N_Byte(&Readbuff[2],1);
  271.    }
  272.                  while(t==0);
  273.          
  274.      Read_N_Byte(Result,2);  //讀出2個字節
  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轉換】+【MUX_A0通道0】+【PGA 電壓量程FS=4.096】+【DR總線數據速率】+【COMP_QUE ALERT引腳輸出配置】+【MODE=0x0000 連續轉換 MODE=0x0100單次轉換】;

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

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

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

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

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

  305. ///==================================================================================================================================================================        
  306.   uint ADC_operation()//ADC數據運算處理
  307.   {
  308.                 static unsigned char count = 0;//ADC采樣次數,計數
  309.     static unsigned long sum   = 0;//ADC采樣總數,“和”
  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];//調試用
  316.          //AD_Value=Result[1];//調試用
  317. //                Delay_us (5);
  318.                
  319. //    if(count < 100)//如果采集次數小于100
  320. //                {
  321. //      sum += AD_temp;//AD值累計
  322. //      count++;//采樣計數加一
  323. //    }
  324. //               
  325. //    if(count >= 100)//如果采集次數大于等于100
  326. //                {
  327. //      AD_Value = sum / 100;//總數“和”除100,慮除波動值
  328. //      count = 0;//采集次數清零
  329. //      sum   = 0;//總數“和”變量清零
  330. //    }        
  331.                         return AD_Value;//返回處理好的AD值
  332.         }

  333. ///==================================================================================================================================================================        
  334.                                                        /* 往下是TM1637代碼區域 */
  335. ///==================================================================================================================================================================        

  336.   uchar key_data,key_value;//按鍵處理過程變量
  337.   uint  Display;//待顯示數據
  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() //初始化函數
  344.         {
  345.           P3M0 = 0x0c; P3M1 = 0x0c;
  346.                 //P3M0 = 0x00; P3M1 = 0x00;//IO口模式配置【準雙向口】
  347.     P5M0 = 0x00; P5M1 = 0x00;//IO口模式配置【準雙向口】
  348.     switch_CHN=1;//指定顯示內容               
  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 應答
  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 寫一個字節
  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; //在讀按鍵前拉高數據線
  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);//設置首地址,
  443.     I2Cask();
  444.     for(i=0;i<6;i++)//地址自加,不必每次都寫地址
  445.     {
  446.       if(i<5)
  447.       {I2CWrByte(SMG_table[buf[i]]);}//送數據
  448.       else
  449.       {I2CWrByte(buf[5]);}//送數據        
  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個二進制位成一個字節
  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)//主函數
  494.   {
  495.     init();//初始化

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

  498.            Bit0=1;//Mot    (LED1)對應set_led()函數里面的Bit0
  499.      Bit1=0;//Ch4    (LED2)對應set_led()函數里面的Bit1
  500.      Bit2=0;//Valley (LED3)對應set_led()函數里面的Bit2
  501.      Bit3=0;//Ch3    (LED4)對應set_led()函數里面的Bit3
  502.      Bit4=0;//Peak   (LED5)對應set_led()函數里面的Bit4
  503.      Bit5=0;//Ch2    (LED6)對應set_led()函數里面的Bit5
  504.      Bit6=0;//Net    (LED7)對應set_led()函數里面的Bit6
  505.      Bit7=0;//Ch1    (LED8)對應set_led()函數里面的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號查詢函數
  515.    //if(key_data!=0xff){key_value=16;}//如果沒有按鍵按下,顯示空白(編碼表第16個元素,對應不顯示)
  516.          //Display=12345;//數碼管顯示內容
  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設置LED狀態
  525.                  
  526.      SMG_Display();//數碼管顯示控制                                                                                                        
  527.    }
  528.          
  529.   }
  530.         
  531.         
  532.       




復制代碼
下面是滿量程的時候對應的波形圖

滿量程

滿量程



視頻展示:

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

ADS1115_STC8G1K08A.rar

53.14 KB, 下載次數: 0

工程文件

回復

使用道具 舉報

ID:1121801 發表于 2025-6-5 10:44 | 顯示全部樓層
感覺很復雜,我進來是標記一下等著學習的,大神快出來
回復

使用道具 舉報

ID:155507 發表于 2025-6-5 16:42 | 顯示全部樓層
AI的回復。

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

---

## 1. **ADS1115數據格式分析**

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


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為數據位。

你代碼中的讀取方式為:

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

這里`Result`和`Result[1]`分別對應高字節和低字節。

---

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

### **(1)數據拼接問題**

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

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

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

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

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

### **(4)數據對齊問題**

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

---

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

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


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


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


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();
}


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


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


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

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

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


#define MODE MODE_0  // 單次轉換

并在每次讀取前寫入配置寄存器啟動轉換。

---

## 4. **總結**

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

---

## 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();
}

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


這樣修改后,低4位數據應該能正常讀取[1]。
回復

使用道具 舉報

ID:66862 發表于 2025-6-5 23:33 | 顯示全部樓層
angmall 發表于 2025-6-5 16:42
AI的回復。

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

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

使用道具 舉報

ID:66862 發表于 2025-6-5 23:41 | 顯示全部樓層
從波形圖上看,讀回來的數據就有問題,是滿量程的時候對應數據 7F F0
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产伦精品一区二区免费 | 国产精品偷乱一区二区三区 | 中文字幕亚洲精品 | 四虎在线免费视频 | 成人高清 | 伊人av网 | 国产不卡在线观看 | 免费高清av| 成人激情在线观看 | 久久艹国产 | 国产精品免费一区 | 欧美精品一区在线观看 | 色爽 | 国产伦精品一区二区 | 欧美日韩视频 | 免费毛片网站 | 亚洲第十页 | 一区二区三区视频 | 在线免费看a | 精品在线观看视频 | 黄色小视频免费观看 | 免费淫片 | 午夜视频成人 | 久久久久久一区 | av免费网| 日韩午夜精品 | 欧美国产精品 | a毛片视频| 人人干人人看 | 成人免费视频一区二区 | 国产成人免费在线视频 | 精品一区二区三区视频 | 一区在线视频 | 91成人国产 | 色婷婷av一区二区三区之e本道 | 欧美日韩91| 欧美日韩精品一区 | 五月婷婷色综合 | 岛国精品在线播放 | 久久久精品国产sm调教网站 | 中文有码在线观看 |