【STM32硬件IIC调试】硬件IIC驱动0.96OLED调试过程记录

一、引言

自己画了一个FOC的板子,驱动OLED的GPIO正好可以复用为硬件IIC。
之前使用OLED时,一直使用软件模拟IIC。效果也可以。
于是想在软件模拟IIC的基础上,调试一下,转为使用硬件IIC。
仔细看了一下软件的逻辑,感觉修改起来比较简单,有把握很快的修改好。
但是修改后,驱动OLED之后,没有显示。

二、现象

最直观的现象是,执行下面的函数之后,屏幕没有显示。
细节的现象是:在debug中运行,执行OLED_Init();函数内部的单个命令,逻辑分析仪都能抓到数据,且数据是正常的。
一次执行整个OLED_Init();函数,逻辑分析仪看到协议也是正常的。(因为发送的数据比较多,所以前面几帧数据正常,没有看到最后面,这也是最后找到问题原因的线索)

但是后面在OLED_Refresh();函数内部单步执行函数时,发现OLED_WR_Byte();函数执行后,逻辑分析仪没有抓到数据。
真是奇怪了,执行过函数,但是没有抓到数据。
但是前面初始化函数内部,单步执行时,却抓到了数据。
实在想不明白。

但是这个OLED驱动,在软件IIC上是正常的,说明指令等操作是没有问题的。
唯一可能出错的地方就是硬件IIC。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

三、解决

后来将逻辑分析仪的时间改为20ms,执行OLED_Init();函数,发现前面的指令都是正常的。
在下面执行OLED_Refresh();时,需要一次发送128个字节的数据,加上从机地址,寄存器地址,一共是130个字节。
逻辑分析仪中看到,后面设备ACK之后,主机再没有发送数据。后面执行OLED_Refresh();内部读写时,就会出现执行发送函数之后,逻辑分析仪抓不到数据的情况了。但是程序并不会卡住,而是会正常执行到主循环。
这可能就是问题的原因。
于是去晚上查,硬件IIC为什么会卡住,为什么会发送一部分数据。
看到一句话,可能是IIC频率太快,设备的反应速度跟不上。
顺着这个线索,将硬件IIC的频率由100k降低,再次执行,还是会发送一部分数据,但现象是频率降低后,发送的数据更少了。
然后很容易想到,把IIC时钟频率提高试试。
果然,时钟频率提高之后,逻辑分析仪抓取到,发送了130个数据。

四、根本原因

硬件IIC使用HAL_I2C_Mem_Write()这个发送函数。
这个函数有一个形参是超时时间。
看到第一眼,以为是从机响应的超时时间。
实际上是一次完整的IIC数据帧的持续时间。
在本次使用时,此时间设置为10,也就是10ms。
当硬件IIC一次数据传输发送的数据量较少时,一点问题也没有。
一旦发送的数据量变多,一次IIC传输的时间超过了10ms,则就会出现从机有ACK,但是主机不会再发数据了。
同时IIC总线应该也处于异常状态(具体没有深入查看)

所以解决这个问题,有两个方法:
1 提高超时时间(一次IIC传输的持续时间)。
OLED驱动中,最多一次发送130个字节,将时间提高,能够满足在此时间内发送130个字节。
2 提高硬件IIC的频率。
最开始没有仔细设置IIC频率,使用了默认的100k,改为400k,使硬件IIC发送速度提高,能够在持续时间内发送完成。

最近工作中使用双核DSP比较多,STM32用的比较少了,不那么熟了。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐