我们在读取测量专业MS5637的D1 (0x40 ~ 0x4A)和D2 (0x50 ~ 0x5A)寄存器时遇到了一些麻烦。每次I2C调用这些寄存器时,它们总是返回0。这很奇怪,因为我们可以很好地读取毕业舞会。
我们的设置如下:我们有一个定制的PCB,里面有一个BLE121LR(带有嵌入式TI微控制器),它连接到MS5637和其他一些传感器。
到目前为止,我们的过程是:1. 写复位在0x1E2. 读取0xA0 ~ 0xA5的PROM3.读取D1 &D2在0x40 &0x50 ->在任何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))
经过多次实验,我回答了我自己的问题,希望它能帮助别人。
以下是读取D1 &从MS5637通过I2C的D2值:
- 写入D寄存器(对于D1,这是0x40 (HEX))
- 写入ADC寄存器(0x00)
- 读取ADC (ADC将返回D1值)
- 如果在我的情况下使用蓝牙:将值写入蓝牙服务。在BG脚本中,这是完成的:"call attributes_write"
所以你需要小心使用BGScript的读/写命令(供参考:我有一个关于如何做到这一点的老例子:http://www.sureshjoshi.com/embedded/ble112-how-to-use-i2c/)
如何阅读:
如果你想从寄存器中读取,你需要调用Hardware_i2c_write使用7位设备地址,左移一次然后给设备写你感兴趣的寄存器地址,没有设置停止标志(0).
从设备将把数据放在I2C线路上,以便接收如果使用相同的设备地址调用hardware_i2c_read,则设置停止标志为1(让设备知道您已经完成了它)和读取1字节的数据(其中包含寄存器位信息)。
和写:
第一个字节是你想要写入的寄存器其次是要写入的数据。请确保用"x"
转义数据的第二个字节
上面的假设你有一个设备,它使用地址->寄存器->值…查看您的数据表(http://www.meas-spec.com/downloads/MS5637-02BA03.pdf),它似乎只是地址->值。奇怪。
要记住的关键是读/写命令的'address'部分总是相同的!在内部,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))
您需要做的另一件事是在写入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; }