乐鑫技术交流
直播中

刘满贵

7年用户 1460经验值
私信 关注
[问答]

ESP8266 I2C通信故障怎么解决?

我在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 functions 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% 可行,或者
在这段时间里,我做错了什么吗?

回帖(1)

切克切克闹

2024-7-19 17:25:22
要解决ESP8266 I2C通信故障,我们可以按照以下步骤进行排查和修复:

1. 检查硬件连接:确保ESP8266的GPIO2(SDA)和GPIO14(SCL)与GPS模块的相应引脚正确连接。同时,确保连接线路没有松动或损坏。

2. 检查电源:确保ESP8266和GPS模块的电源供应稳定,电压在规定的范围内。

3. 检查I2C地址:确保ESP8266和GPS模块的I2C地址设置正确。根据GPS模块的数据手册,设置正确的I2C地址。

4. 检查I2C速率:确保ESP8266和GPS模块的I2C速率匹配。如果速率不匹配,可能会导致通信故障。

5. 检查ESP8266的I2C驱动:确保ESP8266的I2C驱动程序已正确安装并配置。如果需要,可以尝试更新或重新安装驱动程序。

6. 检查C语言代码:检查你的C语言代码,确保I2C通信的相关函数(如初始化、读取、写入等)已正确实现。可以参考ESP8266的官方文档或示例代码。

7. 使用调试工具:使用逻辑分析仪(如Saleae)或其他调试工具,观察I2C通信过程中的信号波形,以便更好地了解问题所在。

8. 检查GPS模块的初始化:确保GPS模块已正确初始化并处于工作状态。根据GPS模块的数据手册,检查初始化过程中的参数设置。

9. 尝试其他I2C设备:如果可能,尝试使用其他I2C设备与ESP8266进行通信,以排除ESP8266本身的问题。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分