![]() |
發布時間: 2025-6-5 00:07
正文摘要:本帖最后由 七彩的夢想 于 2025-6-5 23:44 編輯 最近心血來潮買了幾個ADS1115模塊,想找個時間測試驗證一下。發現模塊配送的資料是Arduino平臺,手頭沒有Arduino硬件,只有STC8G1K08單片機,于是在本論壇找了個現 ... |
從波形圖上看,讀回來的數據就有問題,是滿量程的時候對應數據 7F F0 |
angmall 發表于 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]。 |
感覺很復雜,我進來是標記一下等著學習的,大神快出來![]() |