1. STM32上IIC的一些争议
关于STM32的IIC驱动,网上有很多争论,究竟是使用STM32自带的硬件IIC还是用IO口和软件模拟IIC呢?下面这个图形象展示了这些争论。总结一些:ST为了规避IIC硬件的专利问题,将其设计地有点复杂,但是其提供的标准驱动库并没有很好地适配,导致出现一些BUG。但是下图中那位叫theuit的网友指出了:**“难道ST不知道吗?到底有没有改呢?”**目前,至少从我测试的结果来看,可以得到结论:用HAL库来驱动ST的IIC没问题!
2. 两种类型的IIC器件与相应的HAL库驱动
首先,我们给出两种IIC器件。
-
第一种是带器件中带有寄存器的一类,对这一类设备进行读写的时候往往还要指定寄存器地址。如下图是EEPROM器件AT24C02的IIC操作时序,可以看到除了需要DEVICE ADDRESS外,还需要WORD ADDRESS,即前面说的寄存器地址。 对于这一类器件,HAL库提供了如下的驱动函数进行读写: // 轮询方式读写
HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
当然,除了轮询方式,还有中断和DMA方式,在此暂不写啦。在使用该函数的时候要注意,入参MemAddSize代表寄存器地址的字节长度,也就是有几个字节,而不是位宽!,其取值可以是 I2C_MEMADD_SIZE_8BIT 或 I2C_MEMADD_SIZE_16BIT,分别代表1和2。 其次,HAL库的这些驱动函数都提供了超时功能,timeout的单位是ms。 此外,在使用带有EEPROM的IIC器件时,一定要注意,由于写入之后EEPROM本身也需要一定的写入时间,在该写入时间内进行操作是没有响应,或者会出错的,因此在写完之后一定要延时,具体延时多久可以参考数据手册,比如AT24C02就是5ms。 -
第二类器件自然是不带有寄存器的。具体什么器件我还没找到QAQ。HAL库提供的驱动函数如下: HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
可以看到相比对带寄存器的函数版本,就是少了关于寄存器的一些入参啦。
3. 使用IIC的一些易出错点
采用上面的驱动代码实测是可以正常驱动STM32的硬件IIC的。下面给出IIC使用过程中容易出错的一些点,供参考:
- IIC的IO口应该配置为开漏输出,且硬件上应该上拉。
如果你使用的是STM32CubeMx来生成初始化代码,那么你不必担心这个配置,如下所示,初始化代码中会调用HAL_I2C_MspInit对IO进行初始化。 硬件的上拉也是很关键的,IIC的IDLE状态应该是SCL和SDA都是高电平的。不上拉就会导致IIC检测总线一直在busy的状态。 - IIC的slave address设置。通常的IIC设备采用7bit地址模式,“7bit地址+读写标志位” 构成8bit的地址字节,在使用HAL库驱动IIC的时候,注意入参的DevAddress都是**7bit地址左移一位后作为输入!**当然,有一个例外,STM32CubeMx里的地址设置直接写原值就可以了,该软件会帮你左移一位后生成驱动。
4. 参考
- STM32的硬件I2C有BUG?看我如何为它正名: http://sa.sogou.com/sgsearch/sgs_tc_news.php?req=6PoO2W_QCKVb8jArz1BgEWLNbmwv7FRLBXjzyzcA5T8WUyvRBQOwNGH9pBchWmTo&user_type=1
- STM32F103硬件IIC在HAL库下入坑指南: https://blog.csdn.net/niushijia007/article/details/99671761
- STM32CubeIDE HAL库操作IIC (一)配置篇: https://www.it610.com/article/1279687097564807168.htm
|