伦伦影院久久影视,天天操天天干天天射,ririsao久久精品一区 ,一本大道香蕉大久在红桃,999久久久免费精品国产色夜,色悠悠久久综合88,亚洲国产精品久久无套麻豆,亚洲香蕉毛片久久网站,一本一道久久综合狠狠老

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

實戰指南:SGM58031 ADC從寄存器到驅動的全流程調試(含Linux 6.1適配、編譯報錯、I2C超時與寄存器精準讀取)

jf_44130326 ? 來源:Linux1024 ? 作者:Linux1024 ? 2026-02-07 07:16 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

SGM58031是一款低功耗、高精度的16位Σ-Δ型I2C接口ADC芯片,廣泛應用于工業采集、消費電子、醫療設備等場景。在Linux 6.1系統下適配該芯片驅動時,常遇到“iio_trigger_alloc ID錯誤”“remove函數返回值不兼容”“I2C驅動超時”“i2ctool讀取值跳變不真實”“ADC采樣值無變化”等問題。本文結合實戰調試經驗,從芯片基礎特性、Linux 6.1驅動適配、編譯排錯、設備樹配置、驅動節點操作、寄存器讀取、實戰調試維度,系統講解SGM58031的全流程調試方法。

wKgZPGmGdyGAcbqHAAAbSvDUUz0095.png

一、SGM58031芯片基礎特性

1.1通道特性

wKgZPGmGdyGAfdUYAABe1IfqlNk145.png

SGM58031支持單端/差分輸入模式,核心輸入通道配置如下:

?差分通道:AIN0(+)-AIN1(-)、AIN0(+)-AIN3(-)、AIN1(+)-AIN3(-)、AIN2(+)-AIN3(-),適用于高精度小信號采集;

?單端通道:AIN0-GND、AIN1-GND、AIN2-GND、AIN3-GND,參考地為芯片GND;

?輸入范圍:由內部PGA(可編程增益放大器)和參考電壓共同決定,具體見下表。

1.2增益配置(與數據手冊一致)

SGM58031內置可編程增益放大器(PGA),增益檔位由CONFIG寄存器的PGA位段配置,核心檔位與滿量程(FS)對應關系如下(基于內部參考電壓):

PGA Setting 對應量程(FS, V) 適用場景
2/3 ±6.144V 大信號采集(最大輸入范圍)
1 ±4.096V 大信號采集
2 ±2.048V 中等信號采集
4 ±1.024V 小信號采集
8 ±0.512V 微伏級小信號高精度采集
16 ±0.256V 超小信號高精度采集

注:模擬輸入電壓不得超過滿量程限制,否則會導致ADC飽和,采樣值固定為±32767。

1.3核心寄存器說明

SGM58031的寄存器地址寬度為8位,數據寬度為16位,核心寄存器功能如下:

寄存器地址 名稱 核心功能
0x00 CONV_REG 存儲最新16位ADC轉換結果,只讀
0x01 CONFIG_REG 配置采樣模式、增益、采樣率、通道選擇、轉換模式(單次/連續),讀寫
0x02 LOW_THRESH 低閾值寄存器,用于比較器功能配置
0x03 HIGH_THRESH 高閾值寄存器,用于比較器功能配置
0x04 CONFIG2 擴展配置寄存器,配置參考電壓、休眠模式等
0x05 ID_REG 芯片ID寄存器,固定值0x5803(只讀,用于識別芯片)

二、Linux 6.1驅動適配篇:核心API兼容修改

Linux 6.1內核對IIO子系統的部分API做了調整,SGM58031驅動需針對性修改以適配,核心修改點包含以下兩項:

2.1 iio_trigger_alloc ID參數錯誤修復

問題現象

編譯過程中出現類似報錯:

error: invalid argumenttypeforiio_trigger_alloc, expected deviceidtypebut got xxx

報錯原因是Linux 6.1對devm_iio_trigger_alloc的dev%d參數要求使用iio_device_id(indio_dev)獲取合法設備ID,而非自定義數值。

修復代碼

// 僅修改ID參數,保留原有邏輯data->trig = devm_iio_trigger_alloc(dev,"%s-dev%d",  indio_dev->name,  iio_device_id(indio_dev));

2.2 remove函數返回值調整為void類型

問題現象

編譯時出現返回值不兼容報錯:

error: conflicting typesfor'sgm58031_remove'; have'int(struct i2c_client *)'but expected'void(struct i2c_client *)'

修復代碼

staticvoidsgm58031_remove(struct i2c_client *client){dev_info(&client->dev,"SGM58031 driver unloadedn");}

配套修改:驅動注冊結構體

staticstructi2c_driver sgm58031_driver = {  .driver = {    .name ="sgm58031",    .of_match_table = sgm58031_of_match,  },  .probe = sgm58031_probe,  .remove= sgm58031_remove,// 匹配void類型的remove函數  .id_table = sgm58031_id,};module_i2c_driver(sgm58031_driver);

三、編譯篇:驅動編譯報錯排查與解決

3.1常見編譯報錯類型及解決思路

1.函數指針類型不兼容:incompatible pointer type 'sgm58031_read_raw'

?解決方式:確保回調函數簽名與IIO子系統要求一致。

2.Linux 6.1特有報錯

?iio_trigger_alloc ID錯誤:使用iio_device_id(indio_dev)替換自定義ID參數;

?remove函數返回值不兼容:將remove函數調整為void類型,無返回值。

四、設備樹篇:I2C與SGM58031配置詳解

4.1 I2C控制器配置(以RK3588的i2c4為例)

&i2c4 {  status ="okay";           pinctrl-names ="default";      pinctrl-0= <&i2c8m2_xfer>;     clock-frequency = <100000>;   
  sgm58031@48{    compatible ="sgmicro,sgm58031";     reg = <0x48>;             default-gain = <0>;       // 默認增益1倍(對應±4.096V量程)    status ="okay";           };};

4.2引腳配置(pinctrl)與內部上拉

i2c8m2_xfer: i2c8m2-xfer {  rockchip,pins = , // SCL引腳,開啟內部上拉    <1?RK_PD7?9?&pcfg_pull_up_smt> // SDA引腳,開啟內部上拉  >;};

4.3引腳占用檢查

通過以下命令查看引腳復用狀態,確認I2C引腳未被其他外設占用:

cat/sys/kernel/debug/gpiocat/sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins

五、驅動節點操作與配置(sysfs接口)

SGM58031驅動適配Linux IIO子系統后,所有配置和采樣操作均可通過/sys/bus/iio/devices/iio:device1/下的sysfs節點完成,以下是核心節點的操作方法:

5.1查看設備基本信息

# 進入設備目錄cd/sys/bus/iio/devices/iio:device1/# 查看設備名稱(確認驅動匹配成功)catname# 輸出:sgm58031

5.2讀取ADC采樣原始值

SGM58031提供4個差分通道和4個單端通道的原始采樣值,讀取方式如下:

# 讀取差分通道0(AIN0-AIN1)原始值catin_voltage0-voltage1_raw# 讀取單端通道0(AIN0-GND)原始值catin_voltage4_raw# 讀取單端通道1(AIN1-GND)原始值catin_voltage5_raw# 讀取單端通道2(AIN2-GND)原始值catin_voltage6_raw# 讀取單端通道3(AIN3-GND)原始值catin_voltage7_raw

注:原始值為16位有符號整數,需結合增益(scale)換算為實際電壓。

5.3配置增益(量程)

增益(scale)決定ADC的輸入量程,操作方式如下:

# 查看支持的增益值(僅可寫入這些值)catin_voltage_scale_available# 輸出:6144 4096 2048 1024 512 256(對應PGA設置2/3、1、2、4、8、16)# 配置單端通道0(AIN0-GND)的增益為±4.096V(對應值4096)echo4096 > in_voltage4_scale# 驗證配置結果catin_voltage4_scale# 輸出:4.096000000(驅動自動換算為mV/LSB)

注:所有通道的增益配置是全局生效的,修改任意通道的scale節點,所有通道的量程都會同步更新。

5.4設置采樣率

采樣率決定ADC的轉換速度,操作方式如下:

# 查看支持的采樣率catsampling_frequency_available# 輸出:6 12 25 50 100 200 400 800 960(單位:SPS)# 設置采樣率為100SPSecho100 > sampling_frequency# 驗證配置結果catsampling_frequency# 輸出:100

5.5配置比較器功能

比較器用于觸發中斷,當采樣值超出閾值時觸發,操作方式如下:

# 設置比較器低閾值(十進制16位值)echo128> comp_low_thresh# 設置比較器高閾值(十進制16位值)echo256> comp_high_thresh# 配置比較器觸發隊列(0=1次超閾值觸發,1=2次,2=4次,3=禁用)echo0> comp_queue

5.6設置轉換模式與特殊功能

# 設置轉換模式:0=連續轉換,1=單次轉換echo0> conv_mode# 配置外部參考電壓:0=內部參考,1=外部參考(需硬件支持)echo0> ext_ref# 配置斷線檢測(Burnout):0=關閉,1=開啟(用于檢測傳感器斷線)echo0> burnout# 配置I2C總線泄漏阻斷:0=關閉,1=開啟(提升總線穩定性)echo0> bus_leakage

六、寄存器篇:精準讀取(內核打印vs i2ctool)

6.1 i2ctool讀取寄存器值跳變、不真實的核心原因

核心原因是SGM58031單個寄存器地址存儲16位數據,但i2ctool默認按8位讀取,拆分讀取過程中易獲取無效值;輔助原因是i2ctool無鎖保護,與驅動并發讀寫時會讀取到“半寫”狀態的值,進一步加劇數值跳變。

6.2解決方案:內核驅動中打印寄存器值

6.2.1內核讀取函數(集成Linux 6.1適配,保留原有邏輯)

int readreg(struct iio_dev *indio_dev){  intval;  struct sgm58031_data *data= iio_priv(indio_dev);  u16 read_config = regmap_read(data->regmap, SGM58031_REG_CONFIG, &val);if(read_config client->dev,"Failed to read config: %dn", read_config);returnread_config;}  printk("xsc config: 0x%02xn",val);  read_config = regmap_read(data->regmap,2, &val);if(read_config client->dev,"Failed to read config: %dn", read_config);returnread_config;}  printk("xsc 2: 0x%02xn",val);  read_config = regmap_read(data->regmap,3, &val);if(read_config client->dev,"Failed to read config: %dn", read_config);returnread_config;}  printk("xsc 3: 0x%02xn",val);  read_config = regmap_read(data->regmap,4, &val);if(read_config client->dev,"Failed to read config: %dn", read_config);returnread_config;}  printk("xsc 4: 0x%02xn",val);  read_config = regmap_read(data->regmap,5, &val);if(read_config client->dev,"Failed to read config: %dn", read_config);returnread_config;}  printk("xsc 5: 0x%02xn",val);  read_config = regmap_read(data->regmap,0, &val);if(read_config client->dev,"Failed to read config: %dn", read_config);returnread_config;}  printk("xsc 0: 0x%02xn",val); return0;}// probe函數中集成Linux 6.1的trigger修復static int sgm58031_probe(struct i2c_client *client,            conststruct i2c_device_id *id){ // 原有probe邏輯  struct iio_dev *indio_dev = devm_iio_device_alloc(&client->dev, sizeof(struct sgm58031_data));  struct sgm58031_data *data= iio_priv(indio_dev);
 // Linux 6.1 trigger修復 data->trig = devm_iio_trigger_alloc(&client->dev,"%s-dev%d",                    indio_dev->name,                    iio_device_id(indio_dev)); // 調用寄存器讀取函數  readreg(indio_dev); // 后續邏輯 return0;}// void類型remove函數static void sgm58031_remove(struct i2c_client *client){dev_info(&client->dev,"SGM58031 driver unloadedn");}

6.2.2查看內核打印日志

通過以下命令查看寄存器打印結果:

dmesg-w | grep"xsc"

輸出示例:

[ 650.016361]xsc config:0x4298[ 650.016400] xsc2:0x8000[ 650.016409] xsc3:0x7fff[ 650.016415] xsc4:0x00[ 650.016422] xsc5:0x80

6.3 i2ctool與內核打印的核心對比

維度 i2ctool(i2cget) 內核printk + regmap_read
讀取寬度 默認8位,易拆分/截斷16位值 原生16位,匹配芯片架構
并發保護 無鎖機制,數值易跳變 帶mutex_lock互斥鎖,讀取原子化
適用場景 快速驗證設備是否在線 精準調試寄存器配置

七、調試篇:從現象到根因(實戰案例)

7.1案例1:I2C驅動超時

核心原因與解決方式

1.外部無上拉電阻:在SDA、SCL引腳各添加4.7kΩ上拉電阻,連接至3.3V電源

2.內部上拉未配置:在設備樹pinctrl節點中配置&pcfg_pull_up_smt屬性;

3.引腳占用:檢查設備樹中其他節點的pinctrl配置,修改或禁用占用I2C引腳的節點。

7.2案例2:i2ctool讀取值跳變

核心原因:SGM58031單個地址存儲16位值,i2ctool默認按8位讀取,拆分讀取易獲取無效值;

解決方案:使用內核函數readreg讀取寄存器值,通過regmap_read獲取完整16位值,避免數值跳變問題。

7.3案例3:ADC采樣值始終無變化

現象

驅動加載正常、I2C通訊無異常,但改變輸入電壓后,CONV_REG(0x00)的采樣值始終固定,無任何變化。

排查過程

1.寄存器配置核查:讀取CONFIG_REG確認通道選擇、增益、轉換模式(連續模式)配置正確;

2.時序分析:通過邏輯分析儀抓取I2C時序,確認寄存器讀寫時序、ADC轉換時序符合數據手冊要求;

3.硬件核查:最終發現ADC輸入引腳未有效連接待測電壓(焊接虛焊/杜邦線接觸不良),導致ADC輸入端無電平變化,采樣值固定。

解決方式

1.檢查ADC輸入引腳焊接狀態,重新焊接確保接觸良好;

2.確認待測電壓源正常輸出,且通過合適的限流/分壓電路連接至ADC輸入引腳;

3.驗證:調整待測電壓,讀取CONV_REG值隨電壓變化,確認問題解決。

注意事項

ADC采樣值無變化是調試中高頻問題,優先排查硬件連接(輸入引腳、參考電壓、GND),再核查寄存器配置和時序,避免過度聚焦軟件問題而忽略基礎硬件故障。

八、避坑指南:高頻錯誤總結

1.Linux 6.1適配

?iio_trigger_alloc:采用iio_device_id(indio_dev)獲取合法設備ID;

?remove函數:調整為void類型,無返回值。

2.I2C超時:按“外部上拉電阻→內部上拉配置→引腳占用”的順序排查解決。

3.寄存器讀取:放棄i2ctool裸操作,使用readreg函數讀取,保證數據準確性。

4.設備樹配置:確保I2C控制器、設備節點的status屬性均配置為"okay",引腳配置與硬件實際接線一致。

5.ADC采樣值無變化:優先核查輸入引腳硬件連接,再排查寄存器配置和時序。

6.增益配置:嚴格遵循數據手冊的PGA Setting與滿量程對應關系,避免因量程不匹配導致采樣飽和或精度不足。

7.sysfs操作:增益配置需寫入in_voltage_scale_available中的合法值,采樣率需匹配支持的SPS檔位,避免配置不生效。

九、總結

SGM58031在Linux 6.1下的調試核心要點為:

1.內核API適配:僅修改iio_trigger_alloc參數和remove函數返回值,保留驅動核心邏輯;

2.硬件基礎:掌握芯片通道、增益、寄存器特性,為調試提供理論依據;

3.驅動操作:通過sysfs節點完成采樣讀取、增益配置、采樣率設置等操作,無需修改內核代碼;

4.故障排查:按“硬件連接→I2C通訊→寄存器配置→軟件邏輯”的順序排查,優先解決基礎硬件問題;

5.寄存器讀取:通過內核驅動內的regmap_read接口讀取,規避i2ctool的8位讀取缺陷。

該調試思路可遷移至其他16位寄存器架構的I2C外設,為同類ADC芯片的驅動適配和調試提供參考。

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 寄存器
    +關注

    關注

    31

    文章

    5612

    瀏覽量

    130167
  • adc
    adc
    +關注

    關注

    100

    文章

    7528

    瀏覽量

    556398
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    74HC595 8位移位寄存器:設計與應用解析

    74HC595 8位移位寄存器:設計與應用解析 在電子工程師的工具箱中,移位寄存器是一個非常實用的組件。今天,我們就來深入了解一下SG Micro Corp的74HC595 8位串行輸入/串行輸出
    的頭像 發表于 03-16 10:35 ?177次閱讀

    SGM58031:低功耗16位模數轉換的卓越之選

    SGM58031:低功耗16位模數轉換的卓越之選 在電子設計領域,模數轉換ADC)是連接模擬世界和數字世界的關鍵橋梁。今天,我們來深入探討SG
    的頭像 發表于 03-12 10:10 ?129次閱讀

    RK806中斷處理流程深度解析:架構調試實戰

    RK806 作為瑞芯微主流 PMIC(電源管理芯片),其中斷機制是實現“電源鍵響應、電壓異常保護、休眠喚醒、 watchdog 超時處理” 等核心功能的基礎。Linux 驅動基于regmap_irq框架設計,屏蔽了底層
    的頭像 發表于 02-05 13:46 ?1461次閱讀
    RK806中斷處理<b class='flag-5'>流程</b>深度解析:<b class='flag-5'>從</b>架構<b class='flag-5'>到</b><b class='flag-5'>調試</b><b class='flag-5'>實戰</b>

    “能用”“懂原理”:ARMv8寄存器架構深度拆解

    做嵌入式或芯片開發的同學,大概率都有過這樣的困惑: 寫匯編時知道X0-X30是通用寄存器,調用函數時按規矩用X0-X7傳參,但為什么是這8個?剩下的寄存器又該怎么劃分職責?調試異常時,盯著SPSR
    的頭像 發表于 01-10 07:10 ?187次閱讀
    <b class='flag-5'>從</b>“能用”<b class='flag-5'>到</b>“懂原理”:ARMv8<b class='flag-5'>寄存器</b>架構深度拆解

    什么是(UID)寄存器

    產品唯一身份標識(UID)寄存器(80bit) UID寄存器存儲了芯片的唯一身份標識符,UID在芯片生產時寫入,用戶無法修改。UID 寄存器支持以單字節 / 半字 / 字等方式
    發表于 12-05 06:28

    嵌入式系統必懂的 20 個寄存器

    嵌入式開發看起來很復雜,但很多操作其實都離不開寄存器寄存器就是MCU內部的存儲單元,它們控制著處理和外設的行為。熟悉這些寄存器,你就能更精確地操作硬件,提高開發效率,減少
    的頭像 發表于 11-14 10:28 ?1199次閱讀
    嵌入式系統必懂的 20 個<b class='flag-5'>寄存器</b>

    NVMe高速傳輸之擺脫XDMA設計32:寄存器功能驗證與分析2

    寄存器最大值為 64’hFFFFFFFFFFFFFFFF,到達最大值后一個時鐘周期后翻轉回 0, 在隨機時刻使用 force 將寄存器賦值臨近最大值, 當寄存器達到最大值后, 翻轉回到 0,
    的頭像 發表于 10-14 17:06 ?781次閱讀
    NVMe高速傳輸之擺脫XDMA設計32:<b class='flag-5'>寄存器</b>功能驗證與分析<b class='flag-5'>2</b>

    ?SN74HCT595 8位移位寄存器技術解析與應用指南

    Texas Instruments SN74HCT595/SN74HCT595-Q1 8位移位寄存器包含8位串進并出移位寄存器,向8位D類存儲寄存器饋送信號。存儲寄存器具有并行 3 狀
    的頭像 發表于 09-19 14:31 ?1037次閱讀
    ?SN74HCT595 8位移位<b class='flag-5'>寄存器</b>技術解析與應用<b class='flag-5'>指南</b>

    ?TLC6C5912 12通道移位寄存器LED驅動器技術文檔總結

    該TLC6C5912是一款單片、中壓、低電流功率 12 位移位寄存器 設計用于需要相對中等負載功率的系統,例如 LED。 該器件包含一個 12 位串行輸入并行輸出移位寄存器,可為 12 位饋電
    的頭像 發表于 08-26 14:16 ?1039次閱讀
    ?TLC6<b class='flag-5'>C</b>5912 12通道移位<b class='flag-5'>寄存器</b>LED<b class='flag-5'>驅動器</b>技術文檔總結

    SN74LV595B-EP低噪聲8位移位寄存器技術解析與應用指南

    Texas Instruments SN74LV595B-EP低噪聲8位移位寄存器包含一個8位串行輸入、并行輸出移位寄存器,可為8位D類存儲寄存器饋送信號。存儲寄存器具有并行 3 狀態
    的頭像 發表于 08-15 09:28 ?1292次閱讀
    SN74LV595B-EP低噪聲8位移位<b class='flag-5'>寄存器</b>技術解析與應用<b class='flag-5'>指南</b>

    使用寄存器點亮LED燈

    學習本章時,配合以上芯片手冊中的“19. I/O Ports”章節一起閱讀,效果會更佳,特別是涉及寄存器說明的部分。本章內容涉及較多寄存器
    的頭像 發表于 05-28 17:37 ?1379次閱讀
    使用<b class='flag-5'>寄存器</b>點亮LED燈

    MAX7312 2線接口、16位、輸入/輸出端口擴展,帶有中斷和熱插入保護技術手冊

    MAX7312是2線接口擴展,為SMBus?和I2C應用提供16位并行輸入/輸出(I/O)端口擴展。MAX7312包
    的頭像 發表于 05-26 15:41 ?1031次閱讀
    MAX7312 <b class='flag-5'>2</b>線接口、16位、輸入/輸出端口擴展<b class='flag-5'>器</b>,帶有中斷和熱插入保護技術手冊

    通過I2C總線讀取所有PDO,但在HPI規范中找不到相應的寄存器,為什么?

    我想通過I2C總線讀取所有PDO,但在HPI規范中找不到相應的寄存器。 我發現可以通過 HPI 實用程序讀取它們,所以信息一定在那里。
    發表于 05-16 06:10

    MAX25069怎么通過I2C修改寄存器

    我手上有一個客戶的MAX25069的板子,請問下:怎么通過I2C接口修改寄存器的值?以寄存器0x2(REG_CTRL[7:0])為例。
    發表于 04-25 07:11

    如何用C語言操作寄存器——瑞薩RA系列FSP庫開發實戰指南(10)

    由于寄存器的數量是非常之多的,如果每個寄存器都用像*((uint32_t*)(0x40080000+0x0020*1))這樣的方式去訪問的話,會顯得很繁瑣、很麻煩。為了更方便地訪問寄存器,我們會借助
    的頭像 發表于 04-22 15:30 ?2033次閱讀
    如何用<b class='flag-5'>C</b>語言操作<b class='flag-5'>寄存器</b>——瑞薩RA系列FSP庫開發<b class='flag-5'>實戰</b><b class='flag-5'>指南</b>(10)