STM32 HAL库IIC驱动

1. STM32上IIC的一些争议

关于STM32的IIC驱动,网上有很多争论,究竟是使用STM32自带的硬件IIC还是用IO口和软件模拟IIC呢?下面这个图形象展示了这些争论。总结一些:ST为了规避IIC硬件的专利问题,将其设计地有点复杂,但是其提供的标准驱动库并没有很好地适配,导致出现一些BUG。但是下图中那位叫theuit的网友指出了:**“难道ST不知道吗?到底有没有改呢?”**目前,至少从我测试的结果来看,可以得到结论:用HAL库来驱动ST的IIC没问题!
STM32 HAL库IIC驱动_第1张图片

2. 两种类型的IIC器件与相应的HAL库驱动

首先,我们给出两种IIC器件。

  • 第一种是带器件中带有寄存器的一类,对这一类设备进行读写的时候往往还要指定寄存器地址。如下图是EEPROM器件AT24C02的IIC操作时序,可以看到除了需要DEVICE ADDRESS外,还需要WORD ADDRESS,即前面说的寄存器地址。
    STM32 HAL库IIC驱动_第2张图片STM32 HAL库IIC驱动_第3张图片
    对于这一类器件,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使用过程中容易出错的一些点,供参考:

  1. IIC的IO口应该配置为开漏输出,且硬件上应该上拉。
    如果你使用的是STM32CubeMx来生成初始化代码,那么你不必担心这个配置,如下所示,初始化代码中会调用HAL_I2C_MspInit对IO进行初始化。
    STM32 HAL库IIC驱动_第4张图片
    硬件的上拉也是很关键的,IIC的IDLE状态应该是SCL和SDA都是高电平的。不上拉就会导致IIC检测总线一直在busy的状态。
    STM32 HAL库IIC驱动_第5张图片
  2. IIC的slave address设置。通常的IIC设备采用7bit地址模式,“7bit地址+读写标志位” 构成8bit的地址字节,在使用HAL库驱动IIC的时候,注意入参的DevAddress都是**7bit地址左移一位后作为输入!**当然,有一个例外,STM32CubeMx里的地址设置直接写原值就可以了,该软件会帮你左移一位后生成驱动。
    STM32 HAL库IIC驱动_第6张图片

4. 参考

  1. STM32的硬件I2C有BUG?看我如何为它正名: http://sa.sogou.com/sgsearch/sgs_tc_news.php?req=6PoO2W_QCKVb8jArz1BgEWLNbmwv7FRLBXjzyzcA5T8WUyvRBQOwNGH9pBchWmTo&user_type=1
  2. STM32F103硬件IIC在HAL库下入坑指南: https://blog.csdn.net/niushijia007/article/details/99671761
  3. STM32CubeIDE HAL库操作IIC (一)配置篇: https://www.it610.com/article/1279687097564807168.htm

你可能感兴趣的:(ARM裸机,STM32,IIC,HAL库)