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.

[参考译文] ADS7142:手动模式双通道读取返回0x00 -需要有关正确配置和示例代码的帮助

Guru**** 2455560 points
Other Parts Discussed in Thread: ADS7142

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

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/1407396/ads7142-manual-mode-dual-channel-read-returns-0x00---need-help-with-correct-configuration-and-sample-code

器件型号:ADS7142

工具与软件:

我使用的是 ADS7142 ADC、并尝试在手动模式、双通道单端配置中从两个通道读取数据。 与芯片的通信正常、而且我能够写入和读取寄存器。 但是、我尝试读取 ADC 转换数据时、该数据始终0x00针对两个通道返回。

我认为错误是由于对寄存器配置和寄存器值的解释误解造成的。

这是我使用的寄存器

#define OPMODE_SEL_REG 0x1C
#define AUTO_SEQ_CHEN_REG 0x20
#define START_SEQUENCE_REG 0x1E
#define SEQUENCE_STATUS_REG 0x04
#define ABORT_SEQUENCE_REG 0x1F
#define DOUT_FORMAT_CFG_REG 0x28
#define CHANNEL_INPUT_CFG_REG 0x24
#define CONVERSION_RESULT_REG 0x00  

这是我用于读取和写入寄存器的函数

// Function to write to a register
int write_register(int file, int reg, int value) {
    char data[3] = {0x08, reg, value};  // Opcode 0x08 for single register write
    if (write(file, data, 3) != 3) {
        perror("Failed to write to the i2c bus");
        return -1;
    }
    usleep(100000);  // Wait 100ms after write operation
    return 0;
}

// Function to read data from a register
int read_register(int file, int reg, int read_len) {
    char cmd[2] = {0x10, reg}; // Opcode 0x10 for single register read
    if (write(file, cmd, 2) != 2) {
        perror("Failed to write to the i2c bus for read");
        return -1;
    }
    usleep(100000);  // Wait 100ms after setting register

    char data[read_len];
    if (read(file, data, read_len) != read_len) {  // Read specified bytes
        perror("Failed to read from the i2c bus");
        return -1;
    }

    int result = 0;
    for (int i = 0; i < read_len; i++) {
        result = (result << 8) | data[i];  // Combine MSB and LSB
    }
    return result;
}

以下是我尝试读取两个通道值的序列:

int main() {
    int file;
    char filename[20];

    snprintf(filename, 19, I2C_DEVICE);

    // Open the I2C device
    if ((file = open(filename, O_RDWR)) < 0) {
        perror("Failed to open the i2c bus");
        exit(1);
    }

    // Specify the address of the I2C device
    if (ioctl(file, I2C_SLAVE, ADS7142_ADDRESS) < 0) {
        perror("Failed to acquire bus access and/or talk to slave");
        close(file);
        exit(1);
    }

    // Step 1: Verify auto-sequence enabled by reading AUTO_SEQ_CHEN register (Addr: 0x20)
    int auto_seq = read_register(file, AUTO_SEQ_CHEN_REG, 1);
    if (auto_seq != 0x03) {  // Both CH0 and CH1 should be enabled
        printf("Auto-sequence not enabled properly: 0x%02x\n", auto_seq);
        close(file);
        exit(1);
    }

    // Step 2: Configure Two-Channel Single-Ended Input (Addr: 0x24)
    write_register(file, CHANNEL_INPUT_CFG_REG, 0x00);  // Set for 2-channel, single-ended

    // Step 3: Set OPMODE_SEL to Manual Mode with Auto Sequence enabled (Addr: 0x1C)
    write_register(file, OPMODE_SEL_REG, 0x04);  // Manual mode with auto sequence

    // Step 4: Confirm OPMODE_SEL is set correctly by reading (Addr: 0x1C)
    int opmode_status = read_register(file, OPMODE_SEL_REG, 1);
    printf("OPMODE_SEL Register: 0x%02x\n", opmode_status);

    if (opmode_status != 0x04) {
        printf("Failed to set manual mode with auto sequence. Current mode: 0x%02x\n", opmode_status);
        close(file);
        exit(1);
    }

    // Step 5: Read SEQUENCE_STATUS Register (Addr: 0x04) to verify Auto Seq enabled
    int seq_status = read_register(file, SEQUENCE_STATUS_REG, 1);
    printf("SEQUENCE_STATUS Register: 0x%02x\n", seq_status);

    if (seq_status != 0x02) {
        printf("Auto sequence is not enabled. Current status: 0x%02x\n", seq_status);
        close(file);
        exit(1);
    }

    // Step 6: Set DOUT_FORMAT_CFG to provide at least CHID (Addr: 0x28)
    write_register(file, DOUT_FORMAT_CFG_REG, 0x01);  // Configure data output format

    // Step 7: Start the conversion sequence (Addr: 0x1E)
    write_register(file, START_SEQUENCE_REG, 0x01);

    // Step 8: Read conversion results continuously
    int read_count = 0;
    while (read_count < 20) {  // Read continuously for 20 iterations (adjust as needed)
        usleep(200000);  // Wait 200ms before reading to allow conversion to complete
        int result = read_register(file, CONVERSION_RESULT_REG, 4);  // Read 4 bytes
        printf("ADC Result: 0x%08x\n", result);
        read_count++;
    }

    // Step 9: Stop the conversion sequence (Addr: 0x1F)
    write_register(file, ABORT_SEQUENCE_REG, 0x01);

    // Close the I2C device
    close(file);

    return 0;
}

输出只是0、不知道原因是什么:

OPMODE_SEL 寄存器:0x04
SEQUENCE_STATUS 寄存器:0x02
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000
ADC 结果:0x00000000

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

    尊敬的 Zura:

    遗憾的是、我们很难对为我们的器件编写的软件提供支持和故障排除、尤其是在各种控制器平台上。 为了将您的问题与您的代码隔离开、共享发送至器件的逻辑捕获将会更有帮助、确保器件实际上正在接收正确的传输。  

    此致、
    Joel

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

    有道理、我只是尝试使用以下步骤读取数据:

    • 步骤1. :发送0x10至 REGISTER0x20 以读取寄存器AUTO_SEQ_CHEN并检查是否启用了两个通道的自动序列。

    • 步骤2. :发送0x08到注册0x24数据以0x00将器件配置为双通道单端输入模式。

    • 步骤3. :发送0x080x1C使用数据进行注册0x04、以在启用自动序列的情况下将设备设置为手动模式。

    • 步骤4. :发送0x10到注册0x1C以从寄存器读回OPMODE_SEL,并验证具有自动序列的手动模式已正确设置。

    • 步骤5. :发送0x10到注册0x04以读取寄存器SEQUENCE_STATUS并确认自动序列已启用。

    • 步骤6. :发送0x08到注册0x28数据0x01,设置输出格式,以至少提供通道 ID (Chid)。

    • 步骤7. :发送0x08到注册0x1E数据0x01以启动 ADC 转换序列。

    • 步骤8. :发送0x10到 register0x00 以从CONVERSION_RESULT寄存器连续读取4字节的 ADC 转换结果20次迭代。

    • 步骤9. :发送0x08到注册0x1F数据0x01以停止 ADC 转换序列。

    我试图遵循数据表、但我在某个地方犯了一个错误、不确定在哪里。 因为我可以从 OPMODE_SEL 寄存器和 SEQUENCE_STATUS 寄存器中正确地写入和读取、所以当我尝试读取通道数据时、唯一的问题是:ADC 结果:0x00000000

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

    尊敬的 Zura:

    我认为理解这个问题。 在手动模式下、转换数据需要在 I2C SDA 线上读取、而不是从寄存器读取。 我也不相信这个特定器件有一个"conversion_Result"寄存器、这就使得我认为您的序列的第8步是错误的;地址0x00对应于 OPMODE_I2CMODE_STATUS 寄存器。  

    要在手动模式下读取转换、必须遵循数据表图56中所示的过程。 在这种情况下、在7位器件地址之后提供"读取"位、而不是"写入"位。

    我希望这能够解决这个问题!  

    此致、
    Joel