ST意法半导体
直播中

陈勇

8年用户 1341经验值
私信 关注
[问答]

STM32H503 I3C从机复位成主机,无法发出波形是为什么?

I3C先初始化成目标设备,然后调用deinit i3C的接口,再调用I3C INIT 初始化成控制器,但是这种情况下, I3C总线上是不会出现波形的。
如果我不调用第一个接口初始化成目标设备,直接掉后边的接口初始化成控制器,这个波形是正常出的。
请问这是什么原因。
我对比过初始化要配置的CFGR 和tiMING1 寄存器,当初始化成控制器的时候,上述两者情况中,这两个寄存器的值都是一致的.....

回帖(1)

卞轮辉

2025-3-21 17:55:21

针对STM32H503的I3C模块在模式切换时无法正常生成波形的问题,以下是可能的原因和解决方案的分步说明:




问题根源分析




  1. 硬件状态残留

    I3C外设从从机模式切换为主机时,部分寄存器或内部状态可能未被完全复位(如总线仲裁状态、FIFO状态等)。即使CFGRTIMING1配置一致,其他关键寄存器(如CRISR)的残留状态可能阻止主机模式正常工作。




  2. 引脚配置冲突

    从机模式下I3C引脚可能配置为输入模式,而主机模式需要输出模式。若DeInit未彻底恢复GPIO状态,主机可能无法驱动总线。




  3. 时钟源切换问题

    从机和主机模式可能依赖不同的时钟源(如PLL、HSI)。切换时若未重新配置时钟树,主机模式时钟可能未就绪。




  4. 协议状态机冲突

    I3C总线协议要求主从切换前总线必须处于空闲状态。若从机未正确释放总线(如残留ACK/NACK信号),主机可能无法初始化。






解决方案


1. 彻底复位I3C外设




  • 手动复位外设

    调用DeInit后,强制复位I3C外设的时钟域:


    __HAL_RCC_I3C1_FORCE_RESET();  // 强制复位
    __HAL_RCC_I3C1_RELEASE_RESET(); // 释放复位

    确保外设所有寄存器恢复默认值。




  • 检查CR寄存器使能位

    主机初始化前确认CR.PE(外设使能位)已关闭,避免残留使能状态。




2. 重新配置GPIO引脚



  • 在主机初始化前重新初始化GPIO

    即使引脚复用为I3C功能,仍需显式配置输出模式、上拉电阻和速率:
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;  // SCL/SDA
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;          // 开漏输出
    GPIO_InitStruct.Pull = GPIO_PULLUP;              // 启用上拉
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_I3C1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


3. 确保时钟正确配置



  • 验证主机时钟源

    主机模式下I3C需要特定的时钟频率(如12MHz)。检查RCC配置,确保I3C_CLK源自正确的PLL分频:
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I3C1;
    PeriphClkInit.I3c1ClockSelection = RCC_I3C1CLKSOURCE_PLL3; // 示例配置
    HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);


4. 总线状态恢复



  • 等待总线空闲

    切换模式前,插入延时或轮询总线状态,确保SCL/SDA线为高电平:
    while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) != GPIO_PIN_SET); // 等待SCL高
    while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) != GPIO_PIN_SET); // 等待SDA高


5. 代码流程优化




  • 避免冗余从机初始化

    若无需先作为从机运行,直接初始化为主机即可。必须切换模式时,按以下顺序操作:


    // 1. 初始化为从机(可选)
    MX_I3C1_Init_Slave();

    // 2. 彻底DeInit
    HAL_I3C_DeInit(&hi3c1);

    // 3. 复位GPIO和时钟
    __HAL_RCC_I3C1_FORCE_RESET();
    __HAL_RCC_I3C1_RELEASE_RESET();
    MX_GPIO_Reinit(); // 重新配置GPIO

    // 4. 初始化为主机
    MX_I3C1_Init_Master();





验证步骤




  1. 示波器检测

    在SCL/SDA线路上添加探头,确认主机初始化后是否有时钟信号(SCL应有周期性脉冲)。




  2. 寄存器快照对比

    在两种初始化路径下,导出I3C所有寄存器的值(如CR, ISR, TXDATA等),比较差异点。




  3. HAL库调试

    Step-through调试模式,观察HAL_I3C_Init函数执行过程中是否有错误返回值。






总结


根本原因可能是硬件状态残留或GPIO配置未完全复位。通过强制复位外设、重新配置GPIO、确保时钟正确性,并遵循严格的初始化流程,可解决主机模式无法生成波形的问题。

举报

更多回帖

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