0

我使用 MAX5825 作为 RPi 的外部 DAC。
根据数据表,该组件的分辨率为12 位
当我阅读时,我应该在 CODEn (0x8n) 寄存器中写入我想要设置的值,n 是我想要设置的 DAC 通道,然后在 LOADn (0x9n) 寄存器中写入任何内容,或者使用 CODEn_LOADn (0xBn) 注册一步完成。请参阅此处的数据表摘录
我正在使用 pigpio 守护程序库来接口 I²C 通信

void AnalogOutput::updateValue(int value) { 
    i2c_write_word_data(my_pi_device, my_handler, 0xB0, value << 4);
} 

这应该将我的 CODE0 寄存器设置为value参数。
但是,我有一个奇怪的行为,所以我尝试从 CODEn (0x80) 寄存器中读取数据,以查看我的设置尝试是否正确。

i2c_read_word_data(my_pi_device, my_handler, 0x80);

我不确定我是否可以从命令寄存器中读取一个值,但是当我的值超过 0xFF 时,我从 I²C 读取得到的返回看起来像value & 0xFF。(即,当我将寄存器设置为 0xFF 时,我在寄存器中读取 0xFF,当我将寄存器设置为 0x100 时,我读取 0x00)
此外,当 CODEn 寄存器设置为 0xFF 时,我的 DAC0 通道的输出电压处于最大量程。我使用了 4.0V 内部基准,当我将设置为 0xFF 时,输出电压为 4.0V-ish。
我不明白为什么 0xFF 是 12 位分辨率 DAC 的最大刻度?我是否缺少配置分辨率或类似方法的方法?
到目前为止我已经尝试过:

  • 移除设置值上的 << 4 移位:行为没有变化
  • 反转写入 CODEn 寄存器的 LSByte 和 MSByte(我在 pigpiod API 上看到 SMBus 标准应该在一个字写入过程中发送 LSByte 然后 MSByte): CODEn 寄存器的读取跳过了 0x0FFF 值。MAX5825 应该与 SMBus 标准兼容。
  • 使用i2c_write_block_data代替 pigpiod lib 的 i2c_write_word_data函数:行为没有变化。

谢谢你的时间 !

参考:
MAX5825 数据表:https:
//datasheets.maximintegrated.com/en/ds/MAX5823-MAX5825.pdf pigpio API:https ://abyz.me.uk/rpi/pigpio/pdif2.html

4

1 回答 1

1

好的,我使用 i2cget 和 i2cset 修复了它,我对 LSByte 和 MSByte 的假设是正确的。
CODEn 寄存器用 12 个 MSB 填充。这意味着 0x0ABC 的设定值需要通过 0xABC0 存储在 CODEn 寄存器中。pigpio 遵循 SMBus 标准先发送带有 LSByte 的 I²C 字消息,然后是 MSByte,所以如果我通过 I²C 发送 0x0ABC 消息,它实际上会发送 0xBC0A。当我尝试反转 LSByte 和 MSByte 时,我通过 I²C 发送消息 0xBC0A,所以存储在 MAX5825 中的是 0x0AB。
一种功能解决方法是:

void AnalogOutput::updateValue(int value) {
    int codeRegisterData = (value >> 4) + ((value & 0xF)<<12);
    i2c_write_word_data(my_pi_device, my_handler, 0xB0, codeRegisterData);
}

如果value = 0x0ABC,codeRegisterData将 = 0xC0AB,因此 pigpio 将通过 I²C 总线将消息 0xABC0 写入 CODEn 寄存器。

于 2021-08-18T12:28:33.600 回答