3

我们在读取 Measurement Specialties MS5637 的 D1 (0x40 ~ 0x4A) 和 D2 (0x50 ~ 0x5A) 寄存器时遇到了一些问题。每次对这些寄存器进行 I2C 调用时,它们总是返回 0。这很奇怪,因为我们可以很好地读取 PROM。

我们的设置如下:我们有一个定制的 PCB,其中包含一个连接到 MS5637 和一些其他传感器的 BLE121LR(带有嵌入式 TI 微控制器)。

到目前为止,我们的程序是: 1. 在 0x1E 处写入复位 2. 在 0xA0 ~ 0xA5 处读取 PROM 3. 在 0x40 和 0x50 处读取 D1 和 D2 -> 这在任何 OSR 处总是返回 0。

我希望这里有人能发现我们的错误并帮助我们启动和运行 MS5637。

我附上了我们的运行代码(BGscript),希望能有所帮助。在每个命令之前,我已经评论了它的功能:

#=======================================================================================
# MS5637 BaroWITHer
# address:    1110110x (write : x=0, read : x=1) EC ED
# RESET:      0x1E
# PROM READ:  0xA0 to 0xAE
# READ ADC:   0x00
#=======================================================================================

## RESET COMMAND
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\x1E")(MSResetwritten)

## WRITE TO PROM A0
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\xA0")(MSPromwritten)
## READ TO PROM A0
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 2)(i2c_result, data_len, prom(0:2))

## WRITE TO PROM A1
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\xA1")(MSPromwritten)
## READ TO PROM A1
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 2)(i2c_result, data_len, prom(2:2))

## WRITE TO PROM A2
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\xA2")(MSPromwritten)
## READ TO PROM A2
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 2)(i2c_result, data_len, prom(4:2))

## WRITE TO PROM A3
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\xA3")(MSPromwritten)
## READ TO PROM A3
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 2)(i2c_result, data_len, prom(6:2))

## WRITE TO PROM A4
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\xA4")(MSPromwritten)
## READ TO PROM A4
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 2)(i2c_result, data_len, prom(8:2))

## WRITE TO PROM A5
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\xA5")(MSPromwritten)
## READ TO PROM A5
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 2)(i2c_result, data_len, prom(10:2))

## WRITE THE PROM VALUES TO BLE SERVICE prom_handle
#  call attributes_write(handle, offset, value_len, value_data)(result)
call attributes_write(prom_handle, 0, 12, prom(0:12))

#-----------------------------
# D1 & D2
#-----------------------------
## READ D1 WITH OSR=256
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\x40")(MSD1D2written)
## READ D1
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 3)(i2c_result, data_len, dvalues(0:3))

## READ D2 WITH OSR=256
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\x50")(MSD1D2written)
## READ D2
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 3)(i2c_result, data_len, dvalues(3:3))

## WRITE THE D1 & D2 VALUES TO BLE SERVICE d2_handle
#  call attributes_write(handle, offset, value_len, value_data)(result)
call attributes_write(d_handle, 0, 6, dvalues(0:6))
4

3 回答 3

2

经过大量实验,我正在回答我自己的问题,希望它可以帮助其他人。

以下是通过 I2C 从 MS5637 读取 D1 和 D2 值的步骤:

  1. 写入 D 寄存器(对于 D1,这是 0x40 (HEX))
  2. 写入 ADC 寄存器 (0x00)
  3. 读取 ADC(ADC 将返回 D1 值)
  4. 如果像我这样使用蓝牙:将值写入蓝牙服务。在 BG 脚本中,这是通过以下方式完成的:“call attributes_write”
于 2015-07-09T10:23:49.657 回答
1

所以在使用 BGScript 的读/写命令时需要小心(仅供参考:我在这里有一个关于如何操作的旧示例:http: //www.sureshjoshi.com/embedded/ble112-how-to-use-i2c/ )

如何阅读:

如果要从寄存器中读取,则需要使用 7 位设备地址调用 hardware_i2c_write,左移一次,然后将您感兴趣的寄存器地址写入设备,无需设置停止标志 (0)。

从设备会将数据放在 I2C 线上,因此要接收它,请使用相同的设备地址调用 hardware_i2c_read,将停止标志设置为 1(让设备知道您已完成)并读取 1 个字节数据(将包含寄存器位信息)。

并写:

第一个字节是您要写入的寄存器,第二个是您要写入的数据。请确保您使用“\x”转义数据的第二个字节

以上假设您有一个使用地址结构的设备 -> 寄存器 -> 值...查看您的数据表(http://www.meas-spec.com/downloads/MS5637-02BA03.pdf),它出现只是地址->值。奇怪的。

要记住的关键是读/写命令的“地址”部分始终相同!在内部,LSB 根据命令本身变为 1 或 0。

const MS5637_I2C_ADDRESS = $88

## RESET COMMAND
call hardware_i2c_write(MS5637_I2C_ADDRESS, 1, 1, "\x1E")(MSResetwritten)

此外,对于您的 D1/D2 难题,请尝试将初始写入的停止位设置为 0,以便您的设备知道它仍在等待命令(老实说,即使 I2C 是一个规范,每个设备都有自己的古怪实现):

## READ D1
call hardware_i2c_write(MS5637_I2C_ADDRESS, 0, 1, "\x40")(MSD1D2written)
call hardware_i2c_read(MS5637_I2C_ADDRESS, 1, 3)(i2c_result, data_len, dvalues(0:3))
于 2015-07-08T04:25:26.647 回答
0

您需要做的另一件事是在写入 0x40 和 0x00 之间延迟一点。如果您不延迟,并且 0x40 命令尚未完成,您将返回 0,或无效值。适当的延迟如下:

> switch (cmd & 0x0f) {
>     case MS5637_CMD_ADC_256 : wait_us(900); break;
>     case MS5637_CMD_ADC_512 : wait_ms(3); break;
>     case MS5637_CMD_ADC_1024: wait_ms(4); break;
>     case MS5637_CMD_ADC_2048: wait_ms(6); break;
>     case MS5637_CMD_ADC_4096: wait_ms(10); break; }
于 2016-02-02T21:52:29.407 回答