我在ESP8266上使用 I2c 协议时遇到了一些问题。
我正在使用基本引脚(用于 SDA 的 GPIO2 和用于 SCL 的 GPIO14)并且仅使用 C 语言。
我正在尝试与只能从属的 gps 模块 (Sam-M8q) 进行交换。
https://www.u-blox.com/sites/default/files/sam-m8q_datasheet_(UBX-16012619).pdf
当我使用 Raspberry 3 作为主服务器时,
通信工作正常。
我遇到的主要麻烦是 I2c 时钟(通过 saleae 逻辑软件获取的数据):
- 第1张图片:请求执行读取任务,但Esp8266未启动时钟以按应有的方式开始通信,因此交换不起作用,我得到了错误的数据(0x00不是有效字符是NMEA帧)
- 第 2 张图片:未发送足够的时钟段(仅发送 7 个,而请求的为 9 个)
我知道奴隶可以拉长时钟,让他有时间计算和发送数据,但他不能启动时钟序列,只有主人才能做到。
Esp 和 GPS 设置在面包板上,通过标准电缆和恒定的 3.3V
电源连接。
以下是我正在使用的以下代码:
--> HalI2cWrite and HalI2cRead are basic func
tions using the Esp I2c_master.h functions, they are sending the setup address to read/write and then they send or receive the data only one byte at a time.
--> I am not sending a positioning order each time I want to read as the Gps documentation certifies that multiple read will always read in this position once it has been set once
uint16 HalSamM8qGetFrame(uint8 *gnrmcFrame_tu8, uint8 maxFrameLength_u8)
{
uint8 highBytes_u8;
uint8 lowBytes_u8;
uint16 frameLength_u16 = 0u;
uint16 counter_u16 = 0u;
uint8 i2cBuffer_tu8[GPSRECEIVER_MAXFRAMESIZE] = {0u};
i2cBuffer_tu8[0] = 0xFDu; /* The address 0xFD is containing the higher byte of the frame length */
HalI2cWrite(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u); /* Setting the pointer to the address */
os_delay_us(500u);
HalI2cRead(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u); /* Reading register 0xFD */
highBytes_u8 = i2cBuffer_tu8[0];
i2cBuffer_tu8[0] = 0xFEu; /* The address 0xFE is containing the lower byte of the frame length */
HalI2cWrite(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u); /* Setting the pointer to the address */
os_delay_us(500u);
HalI2cRead(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u); /* Reading register 0xFE */
lowBytes_u8 = i2cBuffer_tu8[0];
frameLength_u16 = (uint16)((highBytes_u8 << 8u) + lowBytes_u8);
if(frameLength_u16 != 0xFFFFu)
{
i2cBuffer_tu8[0] = 0xFFu;
HalI2cWrite(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u); /* Setting the pointer to the address */
os_delay_us(500u);
HalI2cRead(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u); /* Reading register 0xFF and so on, to see the frame */
while((i2cBuffer_tu8[0] != '$') && (counter_u16 < frameLength_u16)) /* We have to read all the buffer to try to find the '$' */
{
HalI2cRead(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u);
counter_u16++;
}
if(counter_u16 < frameLength_u16) /* We don't want to read anything more if we haven't found the '$' in frameLength_u16 tries */
{
counter_u16 = 0u;
gnrmcFrame_tu8[counter_u16] = i2cBuffer_tu8[0];
while((i2cBuffer_tu8[0] != '*') && (counter_u16 < (maxFrameLength_u8 - 2u))) /* Reading and saving all the bytes until we found the "*" */
{
counter_u16++;
HalI2cRead(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u);
gnrmcFrame_tu8[counter_u16] = i2cBuffer_tu8[0u];
system_soft_wdt_feed();
}
HalI2cRead(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u); /* First byte of the checksum */
counter_u16++;
gnrmcFrame_tu8[counter_u16] = i2cBuffer_tu8[0u];
counter_u16++;
HalI2cRead(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u); /* Second byte of the checksum */
gnrmcFrame_tu8[counter_u16] = i2cBuffer_tu8[0u];
counter_u16++;
}
else
{
counter_u16 = GPSRECEIVER_MAXFRAMESIZE; /* Setting the length of the frame to its max frame
otherwise we have counter_u16 = frameLength_u16 */
}
}
else
{
counter_u16 = GPSRECEIVER_MAXFRAMESIZE; /* Setting the length of the frame to its max frame
otherwise we have counter_u16 = 0u */
}
return counter_u16;
}
在这一点上,我是否可以做些什么来使 Esp 100% 可行,或者
在这段时间里,我做错了什么吗?