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

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

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

8 e+ {+ y0 l% O7 m9 y8 N 微信图片_20240529192252.png % x) O* E7 v( |, h' C4 Q' b
. [* D- U* o3 B8 U* U% B
IIC基本原理:IIC是由飞利浦(Philips)公司提出的一种串行通信协议,适用于在同一电缆上连接多个设备。它采用两根线进行通信,即SDA(数据线)和SCL(时钟线)。设备之间通过这两根线实现数据传输,其中SDA用于传输数据,SCL用于同步时钟。
* _8 i$ F) O3 U5 M2 E, i+ j2 o3 |4 J+ j& f0 B5 J0 x; v3 H
微信图片_20240529192248.png
6 g! a' ]2 S- P" L8 \" E! G

9 R0 E5 |& Z- G- Q6 J; @$ w1 l/ L一对IIC总线上面可以挂载多个设备并且多个设备之间有不同的地址,所以我们可以根据不同设备的地址来实现不同设备之间的通信。" T- k+ w) V' p* l
& N/ B0 Q, l% ^% |
软件IIC, m: k5 v2 r3 w7 o0 w% w1 g
在STM32中,软件IIC是一种通过程序控制GPIO口模拟实现IIC通信的方法。这种实现方式常用于一些资源有限的应用场景,或者在需要更灵活控制IIC通信时使用。+ d2 P8 W: f$ c" _8 K

$ ^9 J% c% J; ~/ ?  `# y, ` 微信图片_20240529192245.png
  F1 t: L0 P. Z1 \1 G' I1 K  b* r
! n/ J" c- V* u9 }
总而言之,软件IIC是利用GPIO的翻转,一个IO模拟SCL线,一个IO模拟SDA线实现IIC通信协议的实现。' ^& M1 q+ {, Q
1 H" z5 q3 }" f  r/ f) d8 o8 ]
软件IIC不需要对IO有特殊的要求,只需要两个普通的GPIO即可实现,因此较为方便也方便移植,不同设备只需要重写IIC的基本通讯即可。
. M2 I9 O$ w( S+ m/ ~2 M
  1. // 定义IIC的GPIO口和引脚. h4 c# ^& D% g( T
  2. #define IIC_SCL_PIN GPIO_PIN_6- Z* w) y; D( R) j/ K
  3. #define IIC_SCL_PORT GPIOB
    ' v9 M( p0 I1 ~' P- X

  4. ' k4 i9 i  z! E1 _# F; @7 @7 _
  5. / P7 k7 m+ {% h) ~; d0 N+ d& `. f
  6. #define IIC_SDA_PIN GPIO_PIN_9
    ( p8 I2 V8 c. v, H2 V8 F
  7. #define IIC_SDA_PORT GPIOB6 [$ i8 {1 O& r; j3 k" n
  8. 4 Q& n9 p' d- L- p- K9 |

  9. / g8 w5 K9 W2 F, o
  10. // 定义读写控制位
    % v2 g2 d! L2 p4 l& T  B9 y! X
  11. #define IIC_READ  1
    ( t) t0 S' r1 D8 j/ t. l$ D, [
  12. #define IIC_WRITE 0) J3 k0 M& b1 U% s7 c# `% Z
  13. 6 T/ w& J* J: }, h6 f. i+ {. j; @
  14. ' I5 \* g5 Y& @: |1 {9 i1 U
  15. // 定义函数6 D% G9 Z& v0 `+ b1 q  L
  16. void IIC_Start(void);
    # ?/ u3 r6 v9 j+ T# A+ F) g( R
  17. void IIC_Stop(void);
    : @9 O! v, c* ^' V4 T
  18. void IIC_SendByte(uint8_t byte);% y; H$ T$ n0 t9 f: P
  19. uint8_t IIC_ReadByte(uint8_t ack);4 _& D: J4 _+ v) V$ O

  20. $ i. M2 |( T) K2 P9 e$ N# c

  21. 4 o! d6 ], ^/ b7 y- S
  22. " Q2 e9 W, v! ^$ L0 y/ z; J7 T
  23. 2 b* {4 R2 p3 O. w6 H! ^
  24. // 启动IIC总线1 n0 t1 b+ b6 S
  25. void IIC_Start(void)/ F& @4 o# j2 U
  26. {8 Q6 z7 v- W+ r+ C
  27.     HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_SET);* g' l# @. y5 B  E# _& ~% Q9 G
  28.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET);
    0 k9 r1 M7 i/ m; g% i! _' B: g
  29.     HAL_Delay(2);  // 稍微延时,确保时序正确; i# {. m' D  O
  30.     HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_RESET);8 p7 M6 U2 c6 _9 M& h
  31.     HAL_Delay(2);
    9 Y" {8 T- z+ K" N
  32.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET);
    / n$ R: C$ u1 B( _  |, \
  33. }, v8 ]5 ~/ x7 B5 T  O7 I

  34. : ^$ o, |+ R6 h

  35. 7 u( H! V9 i: ^
  36. // 结束IIC总线! e+ a% `. Q/ u$ A0 N; {0 b! n  W/ I
  37. void IIC_Stop(void)! d; i8 O* u8 P( D/ @5 w
  38. {- A2 H: F: m* N1 c; T" o% T+ H
  39.     HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_RESET);
    ) H, ^- L" F2 S1 o+ R- L- v7 D
  40.     HAL_Delay(2);7 c' l/ R/ m& W3 E* a1 o# ]+ F- D
  41.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET);& N$ s1 F, A( j  K
  42.     HAL_Delay(2);
    6 ]8 J% x' h# j. E
  43.     HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_SET);2 e: x6 K3 l" H
  44.     HAL_Delay(2);
    8 ^* b; b6 \0 b* v0 Q- y
  45. }9 }" r& A9 n( S3 \* `2 M) j! i
  46. ) p8 z, G9 n, d. C: G$ Y- p) n/ ^. e

  47. - s! c* n8 \- o
  48. // 发送一个字节
    " W  d; y8 r" t( k8 o
  49. void IIC_SendByte(uint8_t byte): ?- C' b% r8 j5 [) D! X
  50. {3 S& v# G0 _- |7 E, s# x, x- @
  51.     for (int8_t i = 7; i >= 0; i--)
    + L, h5 B+ n5 l: H8 l$ A
  52.     {
      X2 `! T6 t2 _3 c
  53.         HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET);7 b8 c. o" g7 w
  54.         HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, (byte & (1 << i)) ? GPIO_PIN_SET : GPIO_PIN_RESET);& W3 u' c& N' K/ R: i' s
  55.         HAL_Delay(1); // 稍微延时,确保时序正确) L- `$ L+ I% T
  56.         HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET);
    9 C0 z  j" l- Y( P
  57.         HAL_Delay(1);
    ) e2 J: K6 z2 k7 c1 _. b2 W2 c/ y8 R
  58.     }
    ! B4 {* d( U% S: W% l
  59.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET);$ {4 t% `3 E8 R+ b6 y; E9 j
  60. }7 k* j: i/ |( v

  61. ' _& w) y$ ~% p. Q! a9 X
  62. 3 h: Z- u  f% Q5 g  I' v$ h
  63. // 读取一个字节
    + U: s/ N7 k. M! N: x4 Z9 C0 d6 Z
  64. uint8_t IIC_ReadByte(uint8_t ack)! _! l3 _' @' r
  65. {% W3 I# K2 l4 ]4 ?+ H
  66.     uint8_t byte = 0;' P1 Z& j. o9 B& a* ^4 }; {1 w
  67.    
    * ~* w  F3 ^7 i0 E+ [6 e- p
  68.     HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_SET);4 W. B  B8 P' d( r
  69.     for (int8_t i = 7; i >= 0; i--)+ E5 y7 h5 S; B, M
  70.     {
    3 |: y6 M" G9 T' K
  71.         HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET);
    # w) X/ d) u& I8 J% b8 \
  72.         HAL_Delay(1); // 稍微延时,确保时序正确
    " a& Z7 N% z, G
  73.         HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET);4 G& r  X" @. `( L
  74.         HAL_Delay(1);
    9 l$ a) r5 [! y8 H* A
  75.         byte |= (HAL_GPIO_ReadPin(IIC_SDA_PORT, IIC_SDA_PIN) << i);
    ' {; ?  y7 i* ~/ t" b5 l/ p9 O% d
  76.     }6 R4 E6 K8 @0 L' T1 n( {
  77.    
    / S" A% X2 w! s, Z
  78.     if (ack)/ B+ `9 n8 w; X  K' t& Q, w- l
  79.         HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_RESET); // 发送应答4 W, Z/ w, j5 x5 R
  80.     else
    + }( q/ {) `. Q" E- F. v! s
  81.         HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_SET);   // 不发送应答
    6 ?; K9 u1 }1 _% f: G* F
  82.    
    2 [$ }3 \' t/ G. B% J# g
  83.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET);
    # v) S4 w- C( [+ |# y
  84.     HAL_Delay(1); // 稍微延时,确保时序正确7 k4 W: `; d- U2 N
  85.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET);
    ; ~& x; [% J! M5 w! L2 `8 K
  86.     HAL_Delay(1);
    ' P* g! F9 O$ f( r  d* ~0 b
  87.    
    . s  i+ j- K7 C5 t0 U, a8 a
  88.     return byte;
    ) x4 ~9 l/ f0 ^- b  b( o
  89. }
复制代码

: D/ i7 ?, K0 ?# o例如IIC的启动信号为:SCL为高电平的时候,SDA从高电平转为低电平。
; B2 h! L  i1 N/ U3 X6 b2 {# t, X) e  d2 E" b( Q" F7 v
IIC的结束信号为:在SCL线是高电平时,SDA线从低到高的跳变。
8 p" G# b. N; ~  M4 `: K" B
5 Y% l5 W: m. K- r
因此使用这种方法可以模拟IIC时序完成通讯。" U+ f9 R5 |9 c+ u# y+ l9 d  O
$ l! [2 Y. B! r2 [( Q/ y
但是这种方法的弊端也是非常明显的,需要占用CPU,其次这样子并不能确保I2C时序的正确性。所以无论是稳定性还是可移植性还是IIC的效率都欠妥。& C$ o, |7 u; ^( M7 B) O0 o, e3 |
7 Z* E5 R  S$ t3 M! }
STM32中的硬件IIC    ) V& I1 G) ^* G  n( r% S
STM32系列单片机提供了硬件IIC(Inter-Integrated Circuit)模块,用于支持IIC通信协议。硬件IIC通过专门的硬件模块实现了IIC协议的基本功能,包括起始信号、停止信号、时钟同步等,无需用户通过软件模拟实现。
1 _$ g2 S, ?, d$ `/ _" z9 U
: u, ]1 o, K+ k
STM32硬件IIC优势:
, q% K8 S3 ?, n, |+ y' L  `/ J1.高效性: 硬件IIC使用专用硬件模块处理通信,不需要CPU直接参与,提高了通信效率,降低了对CPU的负担。
- ]' q" {- g' i7 T& b5 _* `9 O
2.时序精确控制: 硬件IIC模块能够精确控制时序,确保通信的稳定性,避免了由于软件执行时间不确定性而引起的时序问题。
2 `$ H- J8 W# X) o9 d! r$ s3.多主机模式支持: 硬件IIC模块通常支持多主机模式,能够轻松处理多个设备同时访问总线的情况。
  j4 L7 P! I8 D' Q) l. `4.易用性: 由于硬件IIC是芯片内置模块,使用起来相对简单,只需配置相应的寄存器和引脚即可。8 S' C* {) b0 `; o/ W. |; _
5.占用资源少: 硬件IIC模块通常占用较少的资源,对于资源有限的嵌入式系统来说,是一种较为理想的选择。1 }3 q: J0 ~/ }( w

3 Z( q6 ]; b& }  r; y* Q
微信图片_20240529192242.png 3 y2 Q) r5 J" C8 h" b3 F9 T2 {

/ O  Z8 g* f! D! r9 \: _在CubeMX中配置好硬件IIC即可利用HAL库函数进行IIC通讯。
  1. static void MX_I2C1_Init(void)5 y3 ?, Z1 N0 V
  2. {. @6 M: f. F5 H! ]: ^
  3.   hi2c1.Instance = I2C1;
    # E, {! W4 ~! c3 @) t
  4.   hi2c1.Init.ClockSpeed = 100000;
    * T+ Q' ]  e/ k% w- a" x. J0 Q/ J2 y: h
  5.   hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
      r4 f0 f% b: c
  6.   hi2c1.Init.OwnAddress1 = 0;, `; d- s+ L' r/ U
  7.   hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    , T0 j8 }) f: k4 N- n7 |- }
  8.   hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;1 W# q- t. g7 K  g8 F! n7 c3 ~
  9.   hi2c1.Init.OwnAddress2 = 0;* a7 x  f) t/ s# n& s) I' c* W
  10.   hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;7 f3 U9 ?" B0 M; u! O2 ]
  11.   hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    5 D3 v4 ]& H* f; j" p) y$ Q8 d
  12.   HAL_I2C_Init(&hi2c1);, r" e+ Y$ o  I( g4 w+ e
  13. }
    $ K* a# c8 }& f! C# U

  14. , j/ d/ F2 @" T, b# W2 @- J4 s& S- O

  15. * Z) b* i% Q  a  f$ t- I& Q
  16. uint8_t deviceAddress = 0x50;//设备地址: {9 X3 q0 i% m% K) F) B
  17. uint8_t registerAddress = 0x00;//寄存器地址
    % [* u" \6 R( ]
  18. HAL_I2C_Master_Transmit(&hi2c1, deviceAddress, &registerAddress, 1, HAL_MAX_DELAY);
复制代码
6 R$ p) u- ?4 ]+ ]
调用CubeMX的初始化函数,之后就可以使用例如HAL_I2C_Master_Transmit,HAL_I2C_Master_Receive等函数来实现IIC通讯。
% M) D$ H5 r7 T2 P9 c5 D6 F/ U  f8 B: n% B6 P
/ y1 O- m& p9 a  G4 X
STM32硬件IIC缺点:
! X$ v% M% ?1 Q* v1.资源占用: 相比软件IIC,硬件IIC模块可能会占用一定的硬件资源,因此在资源受限的系统中需要谨慎选择。( R: U' }5 k& a' D- U
2.灵活性: 硬件IIC通常由芯片内部硬件模块实现,因此在一些特殊场景下可能缺乏一些灵活性,例如无法更改时序。
7 ^. v) [: _* b; l3.部分限制: 不同型号的STM32芯片的硬件IIC模块可能存在一些差异,不同芯片的IO不一样,所以设计时需要谨慎检查。, z! l/ c3 o0 H! I* j) l3 r4 M
6 \1 J' S! a; b7 |) l) z! p# O
总体而言,STM32的硬件IIC是一种高效、稳定的IIC通信方式,特别适用于对性能要求较高的应用场景,同时在易用性和可靠性上有较大优势。在选择IIC通信方式时,可以根据具体需求权衡硬件IIC和软件IIC的优缺点。
9 w+ B3 k9 l  v: |6 z. S* ~- O' M+ s' J4 h
7 b, {: U& W3 U# S# E+ c, ]
+ h1 ~9 D, p. U' u- X& |
转载自:电路小白
8 g6 `6 w) E; I! O9 q如有侵权请联系删除
' W7 s: E# `  b; w' x1 _3 G9 e* f; {! k
赞 收藏 评论0 发布时间:2024-5-29 19:23

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版