STM32 HAL库IIC驱动

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使用过程中容易出错的一些点,供参考:

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

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
  • 5
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在使用STM32 HAL进行IIC驱动MPU6050时,可以按照以下步骤进行配置和初始化: 1. 首先,添加所需的头文件,包括"oled.h"、"mpu6050.h"、"control.h"、"inv_mpu.h"和"inv_mpu_dmp_motion_driver.h"。\[1\] 2. 在初始化函数中,调用MX_I2C1_Init()函数来初始化IIC总线。\[2\] 3. 调用mpu_init()函数来初始化MPU6050。如果返回值为0,则表示初始化成功。\[2\] 4. 使用mpu_set_sensors()函数设置所需的传感器,例如陀螺仪和加速度计。\[2\] 5. 使用mpu_configure_fifo()函数设置FIFO,以确定传感器数据的存储方式。\[2\] 6. 使用mpu_set_sample_rate()函数设置采样率。\[2\] 7. 调用dmp_load_motion_driver_firmware()函数加载DMP固件。\[2\] 8. 使用dmp_set_orientation()函数设置陀螺仪方向。\[2\] 9. 使用dmp_enable_feature()函数设置DMP功能,例如姿态、敲击和原始数据的发送。\[2\] 10. 使用dmp_set_fifo_rate()函数设置DMP输出速率。\[2\] 11. 调用run_self_test()函数进行自检。\[2\] 12. 使用mpu_set_dmp_state()函数使能DMP。\[2\] 13. 在相关初始化函数定义之后,添加循环代码,通过mpu_dmp_get_data()函数获取角度数据,并进行相应的处理和输出。\[3\] 14. 最后,根据需要添加延时函数,以控制数据的采样频率。\[3\] 以上是使用STM32 HAL进行IIC驱动MPU6050的基本步骤。根据具体的应用需求,你可能需要进行一些额外的配置和修改。 #### 引用[.reference_title] - *1* *2* *3* [HAL STM32CubeMX----SPI驱动OLED 与 IIC驱动MPU6050](https://blog.csdn.net/weixin_62213694/article/details/125018662)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值