You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM8S单片机C语言开发I2C数据发送故障排查求助

STM8S105K4与PCA8575 I2C通信卡主发送模式事件的问题排查

问题背景

本人为工科本科生,毕设中使用16通道IO扩展器PCA8575与STM8S105K4单片机通过I2C通信。开发环境为STVD(已正确设置ARF6字节),同款单片机的SPI通信功能正常。

当前程序卡在I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED宏的循环中,无法进入后续数据发送步骤。代码中@标记部分为已验证的可靠代码,硬件因集成在PCB上导致调试难度较大。

已尝试反转事件与标志判断、简化I2C通信流程等方法,均未解决问题,现请教:

  • a) 是否遇到过类似问题及对应的解决方法;
  • b) 该故障更可能源于软件还是硬件;
  • c) 提供故障排查的切入点。

核心代码

// @inclusion of "stm8s.h", "stm8s_gpio.h", "stm8s_delay.h" and "stm8s_i2c.h"

// @defining of C and D port

// @defining P1,P2,... Pin macros

// @defining I2C_SLAVE_ADDRESS, I2C_OUTPUT_CLK_FREQ, I2C_OWN_ADDRESS, I2C_INTERNAL_CLK_FREQ   
// @defining BLINK_LED_A,... macros

// @defining I2C flag checking macros

#define wait ;

void I2C_Setup(void);

void main()
{
    uint8_t rgbMSB, rgbLSB;

    // @initiating GPIO

    I2C_DeInit();
    I2C_Setup(); // see below this main function

    while (1)
    {
        DEBUG_LED_B();

        while (I2C_BUS_IS_BUSY) // ok
            wait
            DEBUG_LED_A();

        I2C_GenerateSTART(ENABLE);
        while (I2C_MASTER_MODE_NOT_SELECTED) // ok
            wait
            DEBUG_LED_B();

        I2C_Send7bitAddress(I2C_SLAVE_ADDRESS, I2C_DIRECTION_TX);
        while(I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCES); // 程序卡在此循环

        DEBUG_LED_A();

        I2C_SendData(rgbLSB);

        while (I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS)
            ;
        DEBUG_LED_B();
        I2C_SendData(rgbMSB);
        I2C_AcknowledgeConfig(I2C_ACK_NONE);
        I2C_GenerateSTOP(ENABLE);
        delay_ms(500);
    }
}

void I2C_Setup(void)
{
    u8 Input_Clock = 0;
    Input_Clock = CLK_GetClockFreq() / 1000000;
    I2C_Init(I2C_OUTPUT_CLK_FREQ, I2C_OWN_ADDRESS, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, Input_Clock);
}

尝试过的简化代码

// previous code
while(1){
I2C_GenerateSTART(ENABLE);
I2C_Send7bitAddress(I2C_SLAVE_ADDRESS, I2C_DIRECTION_TX);
I2C_SendData(rgbLSB);
I2C_SendData(rgbMSB);
I2C_AcknowledgeConfig(I2C_ACK_NONE);
I2C_GenerateSTOP(ENABLE);
delay_ms(500);
}

问题解答

a) 类似问题的解决方法

  • 从机地址错误:PCA8575的7位基础地址为0x20,实际地址由A0/A1/A2引脚电平决定(每接高电平对应位加1),比如A0/A1/A2全接地时地址为0x20。注意I2C_Send7bitAddress传入的是7位地址,库函数会自动拼接读写位,若误传8位地址(如0x40)会导致从机无响应。
  • 初始化参数错误:STM8S105的I2C标准模式最高速率为100kHz,若I2C_OUTPUT_CLK_FREQ设为400kHz可能时序异常;另外Input_Clock需与系统时钟匹配(如HSI 16MHz时应为16),分频错误会导致总线时序紊乱。
  • ACK配置异常:发送地址前需确保I2C处于ACK使能状态,若之前操作关闭了ACK,会无法接收从机的应答信号,卡主模式判断。
  • 总线锁定修复:I2C总线可能因异常通信处于锁定状态,初始化前可通过GPIO手动拉低再拉高SDA、SCL引脚几次,释放总线。

b) 故障原因倾向

软件优先排查,再确认硬件:

  • 软件端:最易忽略的是代码笔误——核心代码中SUCCES少写了一个S,而标准库返回值为SUCCESS,会导致循环永远成立;其次是地址、初始化参数错误。
  • 硬件端:SDA/SCL引脚缺失4.7kΩ上拉电阻、引脚虚焊、PCA8575供电异常(需2.5V-5.5V)、设备损坏等都可能导致无应答。

c) 故障排查切入点

  1. 检查代码笔误:优先确认SUCCES是否为SUCCESS的拼写错误,这是最常见的低级问题。
  2. 验证从机地址:若有逻辑分析仪/示波器,抓取总线地址帧确认是否匹配;无仪器可尝试发送广播地址0x00,看能否跳出循环。
  3. 核对初始化参数:手动计算Input_Clock值(如系统时钟16MHz时应为16),将I2C_OUTPUT_CLK_FREQ改为100kHz标准速率测试。
  4. GPIO模拟I2C测试:暂时替换硬件I2C为GPIO模拟时序,验证PCA8575是否能响应,排除硬件问题。
  5. 硬件信号检测:用万用表测SDA/SCL静态电平,正常应为上拉后的高电平;若为低电平,说明总线被拉死,需排查短路问题。
  6. 添加总线释放步骤:在I2C_DeInit()后添加GPIO操作,将SDA、SCL设为推挽输出,拉低再拉高3-5次,再初始化I2C。

内容的提问来源于stack exchange,提问作者Joerie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 07:45:04