你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32的硬件和软件IIC区别经验分享

[复制链接]
攻城狮Melo 发布时间:2024-5-29 19:23
IIC(Inter-Integrated Circuit)是一种常见的串行通信协议,广泛应用于各种嵌入式系统中,包括STM32单片机。在STM32中,IIC通信可以通过硬件IIC和软件IIC两种方式实现。本文将介绍IIC的基本原理,然后重点探讨STM32中硬件IIC和软件IIC的区别。

微信图片_20240529192252.png

IIC基本原理:IIC是由飞利浦(Philips)公司提出的一种串行通信协议,适用于在同一电缆上连接多个设备。它采用两根线进行通信,即SDA(数据线)和SCL(时钟线)。设备之间通过这两根线实现数据传输,其中SDA用于传输数据,SCL用于同步时钟。

微信图片_20240529192248.png

一对IIC总线上面可以挂载多个设备并且多个设备之间有不同的地址,所以我们可以根据不同设备的地址来实现不同设备之间的通信。

软件IIC
在STM32中,软件IIC是一种通过程序控制GPIO口模拟实现IIC通信的方法。这种实现方式常用于一些资源有限的应用场景,或者在需要更灵活控制IIC通信时使用。

微信图片_20240529192245.png

总而言之,软件IIC是利用GPIO的翻转,一个IO模拟SCL线,一个IO模拟SDA线实现IIC通信协议的实现。

软件IIC不需要对IO有特殊的要求,只需要两个普通的GPIO即可实现,因此较为方便也方便移植,不同设备只需要重写IIC的基本通讯即可。
  1. // 定义IIC的GPIO口和引脚
  2. #define IIC_SCL_PIN GPIO_PIN_6
  3. #define IIC_SCL_PORT GPIOB


  4. #define IIC_SDA_PIN GPIO_PIN_9
  5. #define IIC_SDA_PORT GPIOB


  6. // 定义读写控制位
  7. #define IIC_READ  1
  8. #define IIC_WRITE 0


  9. // 定义函数
  10. void IIC_Start(void);
  11. void IIC_Stop(void);
  12. void IIC_SendByte(uint8_t byte);
  13. uint8_t IIC_ReadByte(uint8_t ack);




  14. // 启动IIC总线
  15. void IIC_Start(void)
  16. {
  17.     HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_SET);
  18.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET);
  19.     HAL_Delay(2);  // 稍微延时,确保时序正确
  20.     HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_RESET);
  21.     HAL_Delay(2);
  22.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET);
  23. }


  24. // 结束IIC总线
  25. void IIC_Stop(void)
  26. {
  27.     HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_RESET);
  28.     HAL_Delay(2);
  29.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET);
  30.     HAL_Delay(2);
  31.     HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_SET);
  32.     HAL_Delay(2);
  33. }


  34. // 发送一个字节
  35. void IIC_SendByte(uint8_t byte)
  36. {
  37.     for (int8_t i = 7; i >= 0; i--)
  38.     {
  39.         HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET);
  40.         HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, (byte & (1 << i)) ? GPIO_PIN_SET : GPIO_PIN_RESET);
  41.         HAL_Delay(1); // 稍微延时,确保时序正确
  42.         HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET);
  43.         HAL_Delay(1);
  44.     }
  45.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET);
  46. }


  47. // 读取一个字节
  48. uint8_t IIC_ReadByte(uint8_t ack)
  49. {
  50.     uint8_t byte = 0;
  51.    
  52.     HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_SET);
  53.     for (int8_t i = 7; i >= 0; i--)
  54.     {
  55.         HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET);
  56.         HAL_Delay(1); // 稍微延时,确保时序正确
  57.         HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET);
  58.         HAL_Delay(1);
  59.         byte |= (HAL_GPIO_ReadPin(IIC_SDA_PORT, IIC_SDA_PIN) << i);
  60.     }
  61.    
  62.     if (ack)
  63.         HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_RESET); // 发送应答
  64.     else
  65.         HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_SET);   // 不发送应答
  66.    
  67.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET);
  68.     HAL_Delay(1); // 稍微延时,确保时序正确
  69.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET);
  70.     HAL_Delay(1);
  71.    
  72.     return byte;
  73. }
复制代码

例如IIC的启动信号为:SCL为高电平的时候,SDA从高电平转为低电平。

IIC的结束信号为:在SCL线是高电平时,SDA线从低到高的跳变。

因此使用这种方法可以模拟IIC时序完成通讯。

但是这种方法的弊端也是非常明显的,需要占用CPU,其次这样子并不能确保I2C时序的正确性。所以无论是稳定性还是可移植性还是IIC的效率都欠妥。

STM32中的硬件IIC   
STM32系列单片机提供了硬件IIC(Inter-Integrated Circuit)模块,用于支持IIC通信协议。硬件IIC通过专门的硬件模块实现了IIC协议的基本功能,包括起始信号、停止信号、时钟同步等,无需用户通过软件模拟实现。

STM32硬件IIC优势:
1.高效性: 硬件IIC使用专用硬件模块处理通信,不需要CPU直接参与,提高了通信效率,降低了对CPU的负担。
2.时序精确控制: 硬件IIC模块能够精确控制时序,确保通信的稳定性,避免了由于软件执行时间不确定性而引起的时序问题。
3.多主机模式支持: 硬件IIC模块通常支持多主机模式,能够轻松处理多个设备同时访问总线的情况。
4.易用性: 由于硬件IIC是芯片内置模块,使用起来相对简单,只需配置相应的寄存器和引脚即可。
5.占用资源少: 硬件IIC模块通常占用较少的资源,对于资源有限的嵌入式系统来说,是一种较为理想的选择。

微信图片_20240529192242.png

在CubeMX中配置好硬件IIC即可利用HAL库函数进行IIC通讯。
  1. static void MX_I2C1_Init(void)
  2. {
  3.   hi2c1.Instance = I2C1;
  4.   hi2c1.Init.ClockSpeed = 100000;
  5.   hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  6.   hi2c1.Init.OwnAddress1 = 0;
  7.   hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  8.   hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  9.   hi2c1.Init.OwnAddress2 = 0;
  10.   hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  11.   hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  12.   HAL_I2C_Init(&hi2c1);
  13. }


  14. uint8_t deviceAddress = 0x50;//设备地址
  15. uint8_t registerAddress = 0x00;//寄存器地址
  16. HAL_I2C_Master_Transmit(&hi2c1, deviceAddress, &registerAddress, 1, HAL_MAX_DELAY);
复制代码

调用CubeMX的初始化函数,之后就可以使用例如HAL_I2C_Master_Transmit,HAL_I2C_Master_Receive等函数来实现IIC通讯。


STM32硬件IIC缺点:
1.资源占用: 相比软件IIC,硬件IIC模块可能会占用一定的硬件资源,因此在资源受限的系统中需要谨慎选择。
2.灵活性: 硬件IIC通常由芯片内部硬件模块实现,因此在一些特殊场景下可能缺乏一些灵活性,例如无法更改时序。
3.部分限制: 不同型号的STM32芯片的硬件IIC模块可能存在一些差异,不同芯片的IO不一样,所以设计时需要谨慎检查。

总体而言,STM32的硬件IIC是一种高效、稳定的IIC通信方式,特别适用于对性能要求较高的应用场景,同时在易用性和可靠性上有较大优势。在选择IIC通信方式时,可以根据具体需求权衡硬件IIC和软件IIC的优缺点。



转载自:电路小白
如有侵权请联系删除

收藏 评论0 发布时间:2024-5-29 19:23

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版