### 硬件IIC与软件IIC的对比
在IIC通信中,硬件IIC与软件IIC各有特点。软件IIC使用IO口模拟IIC时序进行通信,流程清晰,如果出现问题,可以快速定位和修复。但软件IIC的缺点是,它需要占用CPU资源,而且时序控制较为复杂。
相比之下,硬件IIC不需要关心时序问题,配置完成后,IIC外设会自动产生时序。虽然STM32的硬件IIC性能有时被批评,但在某些应用场景下,它仍然比软件模拟IIC有一些优势。
### 硬件IIC的配置
首先,我们需要了解IIC初始化结构体,这是配置硬件IIC的关键。以下是初始化结构体中的一些重要参数:
- **ClockSpeed**:IIC的传输速率,通常取决于从机的最大支持速率。 - **DutyCycle**:SCL线时钟的占空比,影响低电平和高电平的持续时间。 - **OwnAddress1**:STM32设备的自身IIC地址,每个挂载在总线上的设备都需要有一个唯一地址。 - **AddressingMode**:地址位数,通常使用7位或10位,取决于从机的要求。
配置完这些参数后,就可以使用HAL库的I2C_Init函数对IIC进行初始化。在初始化过程中,还需要配置GPIO口的模式,通常是复用开漏输出。
### 使用硬件IIC进行通信
初始化完成后,可以使用HAL库提供的IIC发送和接收函数进行数据传输。这些函数包括:
- **HAL_I2C_Mem_Write**:向从机写入数据。 - **HAL_I2C_Mem_Read**:从从机读取数据。
这些函数简化了数据的写入和读取过程,使得代码更加简洁。
### 实际应用中的考量
在嵌入式开发中,选择使用软件IIC还是硬件IIC,通常取决于具体的应用场景和资源限制。例如,如果对时序要求较高或者需要频繁通信,硬件IIC可能是更好的选择。而如果资源有限,或者需要灵活控制时序,软件IIC可能更合适。
例如,在使用OLED屏幕时,使用硬件IIC可以提高刷新率,从而获得更好的显示效果。而对于AT24C02这类简单的存储设备,连续写入数据时,使用硬件IIC可以避免页写限制,提高效率。
总之,硬件IIC和软件IIC各有千秋,选择合适的IIC通信方式,可以使得嵌入式系统的开发更加高效和稳定。
如何配置硬件IIC
IIC英文全称:Inter Integrated Circuit,集成电路总线,是飞利浦公司在八十年代开发的一种串行、同步、半双工总线。
IIC总线协议无非就是几样东西:起始信号、停止信号、应答信号、以及数据有效性。大家学习了正点原子的IIC实验,应该很了解IIC时序。正点原子使用的是软件模拟IIC,也就是用IO口模拟出IIC时序去通信。使用硬件IIC,就可以不用管时序信号,配置好之后就可以产生时序。虽说ST的硬件IIC很鸡肋,但是某些方面还是比软件模拟IIC稍微强一点。
下面列出一个硬件IIC和软件IIC的对比表

软件IIC整个流程很清晰,假如出了bug,你能很快找到问题,硬件IIC就需要动用DS100示波器去看波形,波形的查看教程可以参考以下推文
《嵌入式工程师必备技能—如何使用示波器查看IIC波形》
HTTPS://mp.weixin.qq.com/s/lnSORSbXeNJe-QVwW0EVbg
其实很多时候是在管脚上考量使用软件IIC。硬件IIC虽然被听说吐槽过千百遍,但是有些人还是有兴趣想使用STM32的IIC外设的,那么本文就教一下大家使用硬件IIC,侧重于使用(这里使用的是F1 HAL库)。
首先,先看HAL库给IIC定义好的结构体,这里主要讲解IIC初始化结构体

ClockSpeed:IIC的传输速率,主要看从机,从机AT24C02是最大为400kHz,低于400kHz即可。
DutyCycle:SCL线时钟占空比,就是低电平与高电平的比值,没有严格限制,选择2:1或者16:9即可。
OwnAddress1:STM32的IIC设备的自身地址,挂载在IIC总线上的器件每一个都有自己唯一地址,作为主机也不例外。特别注意:这里地址的设置不要跟从机一样即可。
AddressingMode:地址的位数是使用7位还是10位,这要看从机了。对于AT24C02来说,直接使用7位。
DualAddressMode:用来配置是否支持双设备地址,没有用到可以不配置。
OwnAddress2:STM32的IIC设备的自身地址,是否有效取决于DualAddressMode成员的设置。
GeneralCallMode:广播呼叫模式,作为从机时使用,通常用不上。
NoStrethMode:时钟线延长,也是作为从机时使用的,通常用不上。
在IIC实验例程中,编写hwiic_init如下:

这里是调用HAL_I2C_Init函数对IIC进行初始化,在IIC的初始化回调函数中就要使能I2C1时钟以及对相关引脚进行初始化,特别注意GPIO口的模式(复用开漏输出),这部分代码比较简单就不列出来了。
初始化完成后,使用HAL库提供的IIC发送和接收函数,函数如下:

hi2c:IIC的句柄结构体地址。
DevAddress:从机的设备地址,这里并不是通讯地址。
MemAddress:要写入的地址。
MemAddSize:地址的长度。
pData:要写入的数据的地址。
Size:写入数据的个数
Timeout:函数执行的超时时间。
以往的AT24C02的写操作函数和读操作函数,函数体内一堆代码,现在只是几行代码。
at24c02写一字节函数代码如下:

at24c02读一字节函数代码如下:

假如说直接用HAL_I2C_Mem_Write来编写连续写函数,就有页写限制,也就是最多8字节,当你写入的数据大于8字节时,就会出现错误了。
所以编写at24c02的连续写函数最好就是调用at24c02_write_one_Byte这个函数接口。
最终可以比对一下相同数据量的传输下,软件模拟IIC和硬件IIC的速度对比。
硬件IIC的配置使用还是挺简单的,速度上面还是比模拟IIC快,假如说是驱动OLED屏幕的话,可以试用一下硬件IIC提高一下刷新率,得到更好的显示效果。

END
