This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] ADS1220:在 Raspberry Pi 上、读取寄存器出错、CS 和 DRDY 保持高电平

Guru**** 2491935 points
Other Parts Discussed in Thread: ADS1220

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/1526071/ads1220-on-raspberry-pi-read-register-goes-wrong-cs-and-drdy-remain-high

器件型号:ADS1220

工具/软件:

大家好!

我希望你很好,并准备好帮助我;-)

我尝试将 ADS1220(CJMCU-1220 品牌)连接 到 Raspberry Pi 4B、然后借助 可编程电源对其进行测试(在差分 A0A1 中)。 我可以通过一个万用表 Keithley 2701 来检查真实的张力。  

我的 布线如下:  

   Raspberry Pi          ADS1220
-----------------     -------------
3.3V (Pin 1)   --->   AVDD (Pin 8), DVDD (Pin 6)
GND (Pin 6)    --->   AGND (Pin 9), DGND (Pin 7)
MOSI (Pin 19)  --->   MOSI (Pin 3)
MISO (Pin 21)  --->   MISO (Pin 2)
SCLK (Pin 23)  --->   SCLK (Pin 4)
CE0 (Pin 24)   --->   CS (Pin 5)
GPIO17 (Pin 11) --->  DRDY (Pin 1)

我使用的代码是:  

import spidev
import RPi.GPIO as GPIO
import time
import csv
import os
from datetime import datetime

# Raspberry Pi pins connected to the ADS1220
CS_PIN = 8  # Chip Select (GPIO8/CE0)
DRDY_PIN = 17  # Data Ready (GPIO17)

# SPI configuration
SPI_BUS = 0
SPI_DEVICE = 0
SPI_SPEED_HZ = 1000000  # 1 MHz

# ADS1220 commands
CMD_RESET = 0x06
CMD_START = 0x08
CMD_POWERDOWN = 0x02
CMD_RDATA = 0x10
CMD_WREG = 0x40
CMD_RREG = 0x20

# ADS1220 registers
REG_CONF0 = 0x00
REG_CONF1 = 0x01
REG_CONF2 = 0x02
REG_CONF3 = 0x03

# Conversion parameters
VREF = 2.048  # Volts (internal reference of ADS1220)
FSR = (2**23) # Full scale range (24 bits with 1 sign bit)
CSV_FILENAME = "ads1220_data.csv"

def ask_gain():
    print("Choose the gain for the ADS1220:")
    print(" 1 : Gain = 1")
    print(" 2 : Gain = 2")
    print(" 4 : Gain = 4")
    print(" 8 : Gain = 8")
    print("16 : Gain = 16")
    print("32 : Gain = 32")
    print("64 : Gain = 64")
    print("128: Gain = 128")
    valid_gains = [1,2,4,8,16,32,64,128]
    while True:
        try:
            g = int(input("Enter the desired gain value: "))
            if g in valid_gains:
                return g
            else:
                print("Invalid value. Try again.")
        except Exception:
            print("Invalid input. Try again.")

def wait_drdy():
    cpt = 0
    while GPIO.input(DRDY_PIN):
        time.sleep(0.001)
        cpt += 1
        if cpt % 1000 == 0:
            print(f"[DEBUG] Still waiting for DRDY ({cpt} ms)")

def ads1220_write_reg(spi, reg, value):
    spi.xfer2([CMD_WREG | (reg << 2), 0x00, value])

def ads1220_read_reg(spi, reg):
    resp = spi.xfer2([CMD_RREG | (reg << 2), 0x00, 0x00])
    return resp[2]

def ads1220_read_data(spi):
    resp = spi.xfer2([CMD_RDATA, 0x00, 0x00, 0x00])
    raw = (resp[1] << 16) | (resp[2] << 8) | resp[3]
    if raw & 0x800000:
        raw -= 1 << 24
    return raw

def ads1220_init(spi, gain):
    # Converter reset
    spi.xfer2([CMD_RESET])
    time.sleep(0.1)

    # MUX[3:0]=0000 (A0-A1), PGA enabled, user-selected gain
    mux_bits = 0b0000 << 4
    pga_enable = 0 << 3
    # GAIN bits (2:0), according to table
    gain_map = {
        1: 0b000,
        2: 0b001,
        4: 0b010,
        8: 0b011,
        16: 0b100,
        32: 0b101,
        64: 0b110,
        128: 0b111
    }
    gain_bits = gain_map[gain]
    reg0 = mux_bits | pga_enable | gain_bits

    reg1 = 0b00000000  # Data rate=20SPS, normal mode, single-shot conversion
    reg2 = 0b00010000  # Internal VREF, 50/60Hz rejection
    reg3 = 0x00        # Disable IDACs

    ads1220_write_reg(spi, REG_CONF0, reg0)
    ads1220_write_reg(spi, REG_CONF1, reg1)
    ads1220_write_reg(spi, REG_CONF2, reg2)
    ads1220_write_reg(spi, REG_CONF3, reg3)

    # Register debug
    val0 = ads1220_read_reg(spi, REG_CONF0)
    print(f"[DEBUG] REG0 after init : {bin(val0)} (0x{val0:02X}), gain={gain}")

def raw_to_voltage(raw):
    v = (raw / float(FSR)) * (VREF)
    return v

def append_to_csv(filename, row):
    file_exists = os.path.isfile(filename)
    with open(filename, 'a', newline='') as csvfile:
        writer = csv.writer(csvfile, delimiter=';')
        if not file_exists:
            writer.writerow(['Timestamp', 'Raw_value', 'Diff_voltage_V', 'Gain'])
        writer.writerow(row)

def get_timestamp():
    return datetime.now().strftime("%d/%m/%y - %H:%M:%S")

def main():
    print("[DEBUG] GPIO initialization")
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(DRDY_PIN, GPIO.IN)

    gain = ask_gain()

    print(f"[DEBUG] SPI initialization (bus={SPI_BUS}, device={SPI_DEVICE}, speed={SPI_SPEED_HZ} Hz)")
    spi = spidev.SpiDev()
    spi.open(SPI_BUS, SPI_DEVICE)
    spi.max_speed_hz = SPI_SPEED_HZ
    spi.mode = 1

    ads1220_init(spi, gain)

    try:
        while True:
            spi.xfer2([CMD_START])
            wait_drdy()
            value_raw = ads1220_read_data(spi)
            value_volts = raw_to_voltage(value_raw)
            timestamp = get_timestamp()
            print(f"{timestamp} ; {value_raw} ; {value_volts:.6f} ; {gain}")
            append_to_csv(CSV_FILENAME, [timestamp, value_raw, f"{value_volts:.6f}", gain])
            time.sleep(1)
    finally:
        print("[DEBUG] Closing SPI and cleaning up GPIO")
        spi.close()
        GPIO.cleanup()

if __name__ == '__main__':
    main()

问题在于、读寄存器函数(行 112:val0 = ads1220_read_reg(SPI, REG_CONF0)) 总是返回“0b11111111 (0xFF)“、而不是像“0b000000000000"。“。

我已经检查了 Raspberry Pi 的 SPI 通信功能并运行良好。

我必须承认、我不知道这是硬件问题还是软件问题、还是两者兼而有...

我希望你能帮我!

提前感谢您!

SU

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 

    您的连接与器件上的实际引脚完全不同、请参阅下面 ADS1220 的引脚图。 我建议您首先仔细检查您的连接。

    您与 ADS1220 的连接:
    ------------------------------------------------
    AVDD(引脚 8)、DVDD(引脚 6)
    AGND(引脚 9)、DGND(引脚 7)
    MOSI(引脚 3)
     MISO(引脚 2)
     SCLK(引脚 4)
    CS(引脚 5)
    DRDY(引脚 1)

    ------------------------------------------------

    - Dale

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Dale
    非常感谢您的快速回答。
    我昨天给出的引脚编号与安装 ADS1220 的 CJMCU-1220 器件相对应。
    为了更好地理解、这里是我的接线示意图。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 

    感谢您的澄清。 如果使用内部时钟、则 CLK 引脚应连接到 GND。 请重新测试并向我发送一个逻辑分析仪  、其中显示了在 CLK 引脚短接至 GND 后来自/发送到 ADC 的通信信号。

    -戴尔

    2024 年 9 月 6 日 
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Dale:
    感谢您的宝贵帮助!  
    我重试了您建议的将 CLK 连接到 GND 的相同代码、但仍然收到相同的寄存器问题(“0b11111111 (0xFF)“、而不是“0b00000000")“)。
    因此、即使我的张力值接近实值、也没有考虑增益变化、偏移看起来仍然很高。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的  Soizic GIBEAUX

    您能否向我发送一个逻辑分析仪  、其中显示了来自 ADC 的通信信号或发送到 ADC 的通信信号?

    BR、

    Dale

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Dale:
    我目前尚无逻辑分析仪可用、但我能够  在两周内向您发送一个显示来自/发送到 ADC 的通信信号的图。
    此致

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的  Soizic GIBEAUX

    如果您有时序图、这将很容易确定问题所在。

    BR、

    Dale

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Dale:

    我使用 PulseView 测试了 ADS1220 和 Raspberry Pi 之间的 SPI 通信。
    我得到了这些结果:

    e2e.ti.com/.../Annotations_5F00_ADS1220.txt

    在这里,我通过执行我的脚本得到了 RPi 监视器:

    sudo python ads1220_logging_gain_A0A1_v7.py
    [DEBUG] Initialisation GPIO
    [DEBUG] Initialisation SPI (bus=0, device=0, speed=1000000 Hz)
    [DEBUG] REG0 après init : 0b11111111 (0xFF), gain=1
    03/07/25 - 10:01:07 ; -65 ; -0.000016 ; 1
    03/07/25 - 10:01:08 ; -73 ; -0.000018 ; 1
    03/07/25 - 10:01:09 ; -96 ; -0.000023 ; 1
    03/07/25 - 10:01:10 ; -55 ; -0.000013 ; 1
    03/07/25 - 10:01:11 ; -47 ; -0.000011 ; 1
    03/07/25 - 10:01:12 ; -74 ; -0.000018 ; 1
    03/07/25 - 10:01:13 ; -43 ; -0.000010 ; 1
    03/07/25 - 10:01:14 ; -74 ; -0.000018 ; 1
    03/07/25 - 10:01:15 ; -58 ; -0.000014 ; 1
    

    我希望这能够澄清发生的确切情况、以及为什么我无法选择正确的寄存器来更改 PGA 值等。

    再次感谢您的帮助!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    提醒一下我的问题、我的脚本在 设置 参数  后显示寄存器、初始化后始终为“0b11111111 (0xFF)“、而不是“00000000 (0x00)“(对于 PGA 1)或“0b00000001 (0x01)“(对于 PGA 2)……

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    具体而言、脚本的以下部分:

    def ads1220_init(spi, gain):
        # Reset du convertisseur
        spi.xfer2([CMD_RESET])
        time.sleep(0.1)
    
        # MUX[3:0]=0000 (A0-A1), PGA enabled, gain selon l'utilisateur
        mux_bits = 0b0000 << 4
        pga_enable = 0 << 3
        # GAIN bits (2:0), selon table
        gain_map = {
            1: 0b000,
            2: 0b001,
            4: 0b010,
            8: 0b011,
            16: 0b100,
            32: 0b101,
            64: 0b110,
            128: 0b111
        }
        gain_bits = gain_map[gain]
        reg0 = mux_bits | pga_enable | gain_bits
    
        print(f"[DEBUG] reg0 calculé : 0b{reg0:08b} (0x{reg0:02X})")
    
        reg1 = 0b00000000  # Data rate=20SPS, mode normal, conversion single-shot
        reg2 = 0b00010000  # Internal VREF, 50/60Hz rejection
        reg3 = 0x00        # Désactive IDACs
    
        ads1220_write_reg(spi, REG_CONF0, reg0)
        ads1220_write_reg(spi, REG_CONF1, reg1)
        ads1220_write_reg(spi, REG_CONF2, reg2)
        ads1220_write_reg(spi, REG_CONF3, reg3)
    
        # Debug registre
        val0 = ads1220_read_reg(spi, REG_CONF0)
        print(f"[DEBUG] REG0 après init : {bin(val0)} (0x{val0:02X}), gain={gain}")

    始终会给出以下结果:

    sudo python ads1220_logging_gain_A0A1_v8.py
    [DEBUG] Initialisation GPIO
    [DEBUG] Initialisation SPI (bus=0, device=0, speed=1000000 Hz)
    [DEBUG] reg0 calculé : 0b00000000 (0x00)
    [DEBUG] REG0 après init : 0b11111111 (0xFF), gain=1
    03/07/25 - 11:24:57 ; 101 ; 0.000025 ; 1
    03/07/25 - 11:24:58 ; 106 ; 0.000026 ; 1
    03/07/25 - 11:24:59 ; 57 ; 0.000014 ; 1
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的  Soizic GIBEAUX

    您能否与逻辑分析仪共享一个清晰(放大)的时序来读取一个寄存器?

    BR、

    Dale

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Dale:

    这是图的放大。 我希望这会有所帮助。

    祝你度过美好的一天

    Soizic

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的  Soizic GIBEAUX

    今天是在美国度假、我们将在下周回答您的问题。 感谢您的耐心

    -布莱恩

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Soizic GIBEAUX:

    我检查了您的时序并汇总了以下各项、0x08 命令会启动或重新启动转换。  ADS1220 使用 单字节命令、 您的命令在哪里读取寄存器?

    第 1 帧:

    • MOSI:0x08
    • MISO:0xFF

    第 2 个帧:

    • mosi:0x10 00 00 00
    • MISO:0x00 00 02 C1

    第 3 个 帧:

    • MOSI:0x08
    • MISO:0xFF

    第 4 帧:

    • mosi:0x10 00 00 00
    • MISO:0x00 00 01 EB

    写入序列应为(以下数据仅为示例):

    • 0x40、0x00
    • 0x44、0x21
    • 0x48、0x43
    • 0x4C、0x22

    或者、您可以一次写入所有 4 个字节:

    • 0x43、0x00、0x21、0x43、0x22

    读取操作是类似的、只是它不再是 0x4x、而是变为 0x2x。  

    BR、

    Dale