OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4827|回复: 4

关于高波特率串口中断导致IIC死锁,主函数代码不执行的问题

[复制链接]

17

主题

97

帖子

0

精华

高级会员

Rank: 4

积分
822
金钱
822
注册时间
2020-7-21
在线时间
85 小时
发表于 2021-8-7 16:24:42 | 显示全部楼层 |阅读模式
1金钱
        近日在做项目的时候,遇到了一个问题让我百思不得其解。为了尽可能复现问题,我说的尽量详细一些,并附上一些尝试。
        IIC协议是一种很常用的通信协议,一般分为硬件IIC和软件IIC两种实现方式。在实际使用过程中可能会出现IIC锁死[1]的问题。其具体表现为:SCL始终为高,SDA始终为低。但这种现象往往出现在硬件IIC,软件IIC并不会出现。但我在使用过程中却意外发现了,软件IIC也会出现IIC死锁的现象。

我使用的板子是STM32F103RCT6。资源配置如下:

         NVIC分组为2bits抢占2bits响应
        串口:①USART1用于红外,串口波特率为9600,使用DMA接受数据。②USART2用于语音芯片,波特率9600,使用DMA发送数据。③USART3用于陀螺仪模块,波特率为57600,陀螺仪的采样率为50Hz,采用中断处理数据,抢占2,响应0。④UART4、UART5用于两个激光测距模块,波特率为115200,采样率100Hz,采用中断处理数据,抢占2响应2.
       定时器:①TIM4,CH1-CH4均用于PWM输出驱动电机。②TIM2、TIM3采用了编码器模式,用于采集电机编码器的值 ③TIM6为抢占0响应1的10ms中断,用于处理当前电机的编码器的值通过PID运算得出PWM输出值作用于TIM4   ④TIM7为抢占1响应0的中断,用于刷新处理陀螺仪的数据。
       主函数:①硬件初始化,初始化OLED以及上述定时器串口。OLED采用软件IIC,运用延时函数delay_us处理IIC时序。 ②死循环里是:
  1. LED1 = ~LED1;

  2. OLED_ShowNum(0,18,flag_water_cd,8,12);
  3. OLED_FloatShow(0,36,speed_L,12);
  4. OLED_FloatShow(0,52,speed_R,12);
  5. OLED_Refresh_Gram();
复制代码
       即跑马灯和OLED数据更新。由于OLED刷新需要一定时间,虽然没有delay但可以看到灯是在闪的。


       问题描述:当系统运行一段时间后,会出现OLED数据不更新,灯不再闪烁,SCL为高,SDA为低的现象。可以判定为是IIC死锁的问题。但经过查阅资料,IIC死锁只会在硬件IIC出现,软件IIC不出现。

        一些尝试:
        由于用到了软件IIC,JLINK调试并不好用,只能一点一点注释掉代码找原因。
        ①注释掉UART4, UART5初始化后运行五分钟,测试三次均未出现死锁问题。 ②注释掉定时器6的初始化,运行五分钟,三次测试均不出现死锁。  ③不注释任何代码,系统运行7s后IIC死锁,灯不再闪烁,OLED不更新。 ④注释掉UART4,UART5后,修改与陀螺仪的波特率为115200,运行数十秒后死锁。⑤注释掉陀螺仪的初始化代码,运行约3min后出现死锁问题。

        猜测:高波特率的中断会打断IIC时序使主机不能收到IIC的Ack信号。

        想过的解决方案:
        ①采用输入捕获和定时器对SCL进行检测,当长时间为高电平时再给SCL一个脉冲。实测可以解决但在此系统不能实装。因为TIM6要进行PID运算,如果有比他优先级更高的中断会导致PID更新不稳定,电机转动不顺畅。②目前临时办法是不使用OLED,或者不使用激光测距模块。不知道论坛的大神有没有遇到过类似的问题,希望能有所指点。









[1] I2C死锁原因及解决方法_fengel_cs的专栏-CSDN博客_i2c死锁

最佳答案

查看完整内容[请看2#楼]

按理软件IIC不该出现死锁,因为软件的每一步都由程序控制,IIC又是同步通讯只要正确设计好IIC时序无论怎么被中断都没事。出现死锁可以考虑信号电平有无被干扰导致从机和主机不在同一步调。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

56

主题

343

帖子

0

精华

高级会员

Rank: 4

积分
977
金钱
977
注册时间
2016-3-8
在线时间
267 小时
发表于 2021-8-7 16:24:43 | 显示全部楼层
按理软件IIC不该出现死锁,因为软件的每一步都由程序控制,IIC又是同步通讯只要正确设计好IIC时序无论怎么被中断都没事。出现死锁可以考虑信号电平有无被干扰导致从机和主机不在同一步调。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2021-8-8 00:28:17 | 显示全部楼层
你这个可以仿真解决啊,用硬件IIC才不好仿真。。。
回复

使用道具 举报

4

主题

456

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1072
金钱
1072
注册时间
2021-4-26
在线时间
352 小时
发表于 2021-8-9 10:41:20 | 显示全部楼层
帮顶  
回复

使用道具 举报

3

主题

44

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2018-8-5
在线时间
11 小时
发表于 2021-8-10 11:53:39 | 显示全部楼层
检测ACK的时钟刚刚变化,接下来应该检测ACK是否应答,然而被打断了,但是从机已经给过信号了。所以当退出中断服务回来继续检测的时候就检测不到ack了。两种解决方案,1,中断时间要短 2,IIC加上timeout机制。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-26 11:31

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表