STM32 硬件IIC 锁死及复位问题

这里不准备深入讨论stm32硬件IIC的锁死的原因,大概意思是应为IIC为“响应”式的通讯,通讯一方无响应则导致另一方等待或者出错。STM32的硬件IIC一直传说是有问题的,从最开始的初始化之后立刻锁死开始,一直被大家所诟病,后来官方经过多次的驱动修改或者硬件迭代,目前至少在新的mcu上,IIC可以在正常情况下正常工作了,但从设备无响应是时,可能导致整个IIC的HAL库函数处于busy或error状态,从而无法恢复。如果使用硬件模拟IIC则比较灵活,可以自行处理各种问题(如状态复位,或者使用9个脉冲复位总线等)。

但是,由于当前项目不得已使用了的fcubeMx自带的rtos,硬件上使用模拟IIC的话有诸多不便(如使用osdelay只能为ms级,使用自定义微秒延时函数时需要禁用任务调度,否则可能出现延时过长等问题),只能使用硬件IIC,从设备为SHT35。此时过程中,通过拔插从设备电源及通讯线,偶尔会出现无法恢复通通讯的情况,通过采用一下方式处理这个问题,目前经过一段时间测试还算正常,如果方便,也请各位帮忙测试或者分析下是否会有问题:

调用代码:
 while(1)
    {
        if(SHT35Op()!=0)
        {
            UnlockI2C2();
        }

        osDelay(500);
    }

函数SHT35OP中,如果出现IIC发送或者接受错误则会返回非0值,然后会调用UnlockI2C2();试图恢复总线。UnlockI2C2()代码如下:
void UnlockI2C2(void)
{
    hi2c2.Instance->CR1=hi2c2.Instance->CR1&0xFFFE; //复位IIC软件
    GPIOB->AFR[1]=GPIOB->AFR[1]&0xFFFF00FF;   
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11|GPIO_PIN_10,GPIO_PIN_SET);
    osDelay(1);
    for(uint8_t i=0;i<9;i++)
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_RESET);
        osDelay(1);
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_SET);
        osDelay(1);
    }   
    GPIOB->AFR[1]=(GPIOB->AFR[1]&0xFFFF00FF)|0x00004400;
    hi2c2.Instance->CR1=(hi2c2.Instance->CR1|0x01); 
    osDelay(1);
}
解释如下:
1. 通过直接修改寄存器值,复位IIC的各个状态(以IIC2为例参加手册的寄存器解释,不同的MCU可能不一样,当前是STM32L4xx)
2. 通过修改AFR寄存器,将所用的SCL和SDA端口变为普通IO输出。不同IIC的AFR操作数据和GPIO端口可能不一样。
3. 使用直接操作的GPIO的方式操作输出端口,发送9个脉冲使得总线复位。
4. 将SCL和SDA端口恢复为受外设控制。
5. 取消IIC的复位,回复IIC功能。

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在STM32中,防止I2C总线锁死有几种方法。 首先,确保总线配置正确。首先,设置I2C的时钟频率,需要根据所连接的外设和总线负载来选择合适的频率。过高的频率可能导致通信错误,而过低的频率可能导致通信速度过慢。其次,确保总线上没有冲突的地址。每个I2C设备应该有一个独一无二的地址,确保没有地址冲突可以避免通信的错误。 其次,使用适当的超时机制。在进行I2C通信时,可以设置一个超时时间,如果超过这个时间还没有接收到回应信号,就可以中断通信,重新初始化总线,避免总线锁死。超时时间需要根据具体应用场景和通信速率来调整。 另外,保持总线始终处于正确的状态。在进行I2C通信过程中,需要根据具体情况来确认并处理可能出现的错误,如丢失ACK信号、总线冲突等。可以通过编写适当的错误处理代码,在出现错误时及时处理,避免导致总线锁死。 最后,合理设计系统中的并发操作。如果系统中存在多个任务同时使用I2C总线进行通信,需要合理设计任务的优先级和调度机制,避免出现同时访问总线的情况,从而避免总线锁死。可以使用信号量或互斥锁机制来进行任务的同步和互斥访问。 通过以上的方法,可以有效地防止STM32中的I2C总线锁死问题,保证系统的稳定性和可靠性。 ### 回答2: STM32IIC总线锁死是指在使用IIC通信时出现的一种现象,即当IIC总线的通信协议发生异常或通信线路出现问题时,导致IIC总线无法正常通信。 防止STM32IIC总线锁死,可以采取以下措施: 1. 总线复位:当发现IIC总线出现异常时,可以通过对总线进行复位来恢复通信。具体方法是通过对IIC控制器进行硬件复位或对总线引脚进行切换操作,使IIC总线重新初始化。 2. 超时机制:可以在IIC通信过程中设置超时机制,即设定一个最大的等待时间。如果在超过该时间后对方没有发送应答信号,就认为出现了异常,重新初始化IIC总线。 3. 错误处理:可以通过判断IIC通信过程中返回的错误标志位来处理异常情况。当发现错误标志位被置位时,可以进行相应的错误处理,例如重新初始化IIC总线。 4. 异常处理:当IIC总线出现锁死时,可以通过加入异常处理函数来进行处理。异常处理函数可以在IIC总线出现异常时进行复位操作,重新初始化IIC总线,并进行相应的错误处理。 5. 电源滤波和信号线布局:对于IIC总线来说,电源质量和信号线的布局都会影响通信的稳定性。因此,在设计电路板时应注重电源滤波和信号线的布局,以减小可能出现的通信故障。 综上所述,通过合理设置超时机制、错误处理、异常处理等方法,以及在硬件设计中注意电源滤波和信号线布局,可以有效地防止STM32IIC总线锁死。 ### 回答3: 在STM32中,为了防止IIC总线锁死,我们可以采取以下措施: 1. 确保电源正常供应:IIC总线的正常工作需要稳定的电源供应。因此,我们需要确保电源电压在规定的范围内,并且电源稳定性良好,以避免造成IIC总线锁死。 2. 适当设置IIC总线时钟速度:IIC总线的通信速度需要根据实际应用需求进行适当设置。如果时钟速度过高,可能会导致总线锁死。因此,我们需要根据实际情况选取合适的时钟速度,避免过高或过低的速度。 3. 优化软件程序:在软件程序的设计和编写中,需要遵循一些原则来防止IIC总线锁死。例如,使用适当的延时函数,以确保总线上的数据能够正确传输和处理。此外,还需要处理错误状态和异常情况,及时采取相应的措施,避免总线锁死。 4. 使用适当的阻尼电路:在实际应用中,我们可以通过添加适当的阻尼电路来消除IIC总线上的反射和干扰。这样可以提高总线的稳定性,降低总线锁死的风险。 综上所述,为了防止STM32中的IIC总线锁死,我们需要确保电源供应正常,设置合适的时钟速度,优化软件程序,以及使用适当的阻尼电路等措施。通过这些方法可以提高总线的稳定性,从而减少IIC总线锁死的发生。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值