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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 19:23
IIC(Inter-Integrated Circuit)是一种常见的串行通信协议,广泛应用于各种嵌入式系统中,包括STM32单片机。在STM32中,IIC通信可以通过硬件IIC和软件IIC两种方式实现。本文将介绍IIC的基本原理,然后重点探讨STM32中硬件IIC和软件IIC的区别。5 Z4 F4 G& \7 `( G/ I5 r0 z+ G4 Z
! `+ r. Y. x1 C* H" T, J
微信图片_20240529192252.png 7 p( G- P) a3 \, E
' R, i. [$ q  L8 q+ B  [
IIC基本原理:IIC是由飞利浦(Philips)公司提出的一种串行通信协议,适用于在同一电缆上连接多个设备。它采用两根线进行通信,即SDA(数据线)和SCL(时钟线)。设备之间通过这两根线实现数据传输,其中SDA用于传输数据,SCL用于同步时钟。+ A+ s: v: y  B: ]. _. M6 h8 n
5 S- m7 s" ^( K# N
微信图片_20240529192248.png 3 w4 d4 ^/ J/ _  Z: s' `4 n

% L' p6 Q# S8 b; X' K" H一对IIC总线上面可以挂载多个设备并且多个设备之间有不同的地址,所以我们可以根据不同设备的地址来实现不同设备之间的通信。# U/ ~; v: k( }. L6 m5 u; x/ g( b
2 b, Z' F6 o- m' U% b: v$ I
软件IIC
& [( |, I! d2 a! p在STM32中,软件IIC是一种通过程序控制GPIO口模拟实现IIC通信的方法。这种实现方式常用于一些资源有限的应用场景,或者在需要更灵活控制IIC通信时使用。3 t4 y) w% y" p4 a0 l- h9 x
$ J& N, N4 ^' r: X7 F% u0 h
微信图片_20240529192245.png
8 Z. f6 b) _: u7 ~+ M: ^) K

# P9 Q5 h% R0 Q& H1 K4 l9 h- z总而言之,软件IIC是利用GPIO的翻转,一个IO模拟SCL线,一个IO模拟SDA线实现IIC通信协议的实现。
4 W, I' f& z9 h4 n4 K0 N
. ]) N, ^0 r& q2 e
软件IIC不需要对IO有特殊的要求,只需要两个普通的GPIO即可实现,因此较为方便也方便移植,不同设备只需要重写IIC的基本通讯即可。
( _1 v/ |! m! h$ E$ b! e
  1. // 定义IIC的GPIO口和引脚
      H8 _, }6 Y5 o
  2. #define IIC_SCL_PIN GPIO_PIN_69 V% }. v: t- |* O" F  ^- l2 b; `
  3. #define IIC_SCL_PORT GPIOB
    & m) m3 Z: y% L' u
  4. , F3 x  Q5 V; ^+ R% S# z
  5. 5 Z8 s4 T$ y) T7 ^/ ?
  6. #define IIC_SDA_PIN GPIO_PIN_9
    ; `2 e+ a6 Q3 b; }1 h
  7. #define IIC_SDA_PORT GPIOB& d8 c+ e9 x7 Z% ]/ ?, j
  8. : K/ W* S  m$ @- b/ x! y
  9. 8 D; V3 o# C, |+ r9 m
  10. // 定义读写控制位9 s. }/ r5 n* B' {
  11. #define IIC_READ  1# ]+ r, b3 f1 Z8 y/ ]% o  z! S
  12. #define IIC_WRITE 02 h: d5 @/ R. q& j

  13. ) x/ [, u+ r1 r; a

  14. - Q5 Y* F, @- F
  15. // 定义函数
    5 ]! J9 _' I/ c% b0 w$ m, x/ m
  16. void IIC_Start(void);! _$ ]% H7 B6 G4 Z- H7 ^
  17. void IIC_Stop(void);
    . Y6 x3 Y) p! o0 B5 P$ o7 \! ?3 t3 n- V
  18. void IIC_SendByte(uint8_t byte);
    0 }3 u; m( D" w, N7 h* |
  19. uint8_t IIC_ReadByte(uint8_t ack);
    / X+ X* b1 M: E+ h  t( b
  20. & `( [' r" c9 T& h9 D

  21. ) P$ F9 u( v: m3 _9 b! I

  22. 4 |( V9 o' G1 N0 W, ~& O* O: }

  23. - z# ~5 y4 @4 m1 G
  24. // 启动IIC总线
    0 d$ i% e, X1 C4 g8 ?2 e
  25. void IIC_Start(void)* n- j. t7 p& c9 g
  26. {
    $ y  ~( O# y2 U- L/ |: j
  27.     HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_SET);
    % [( l' ]0 P$ E( j0 h' n; k
  28.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET);
    1 R0 l8 ^, O) i3 ]5 |" t$ i* `- N5 t
  29.     HAL_Delay(2);  // 稍微延时,确保时序正确( p" {7 I7 Q. s6 q% L. ?  P
  30.     HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_RESET);" E2 U3 _& h0 T8 a
  31.     HAL_Delay(2);
    % u6 Q' g4 Q& m" h' C
  32.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET);" n% a! \! l4 v
  33. }
    * H7 w* O' H" C8 ?

  34. - V. F+ H4 O. J( V* q* W
  35. 4 G- [/ E9 ?0 l  i
  36. // 结束IIC总线% c7 S! m6 P  q) v3 g0 w2 F
  37. void IIC_Stop(void)
    8 C$ d7 g/ d; U. F/ ]: T& g
  38. {* c0 x" Z3 l! x- N& M2 i
  39.     HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_RESET);
    6 Z, m$ h/ ~2 ~- R5 a
  40.     HAL_Delay(2);
    6 U6 _4 v# a- i( P# p* a/ K- t
  41.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET);! g3 K' `; K3 D* h" ?+ v! ]7 p
  42.     HAL_Delay(2);
    : Z4 G4 f7 k7 a# Y. B
  43.     HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_SET);! T: A5 u% s& q7 o- L% v0 l* d
  44.     HAL_Delay(2);
    1 w4 z& V. D+ z6 [2 C& m
  45. }
    , a- j& e6 b; z: w1 [# M
  46. / Z" Q2 a5 p) m/ E# H

  47. 9 E/ }9 V2 c5 W
  48. // 发送一个字节
    : i# e) p2 H5 V! Y+ H- O1 R4 }
  49. void IIC_SendByte(uint8_t byte)
    & v' b7 @" B  A8 J; F6 l; d
  50. {
    0 e; o: u! S7 p+ K. v, x
  51.     for (int8_t i = 7; i >= 0; i--)
    ) e: K2 d' \3 L
  52.     {
    & \' Y' I  U! ]8 Z( y+ x; X5 U4 L
  53.         HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET);
    5 `- @1 i9 X1 e4 `. I4 H- B2 j
  54.         HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, (byte & (1 << i)) ? GPIO_PIN_SET : GPIO_PIN_RESET);
    2 {9 x' U# o! n4 A  a4 n
  55.         HAL_Delay(1); // 稍微延时,确保时序正确
    ! o7 D: J  C* X9 Y' E, Y# ^
  56.         HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET);
    # @$ m* W/ e! h, v, M( \
  57.         HAL_Delay(1);
    ; k9 K! k5 o$ Q: A9 F3 F1 R
  58.     }' O% t! V& L/ G& a7 ~1 p2 p
  59.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET);8 Q2 ^8 M% h9 x* Y& j: H7 Z
  60. }
    ( ^+ g6 p# O7 g8 `8 R9 U
  61. # T: t9 m6 m  j( D9 X% Z
  62. % `8 q5 c7 r# O4 b6 t  }
  63. // 读取一个字节1 @# g: i) K" Z7 U% k2 i
  64. uint8_t IIC_ReadByte(uint8_t ack); @0 E7 Q& q2 b
  65. {
    . L! c8 q9 L% S# y
  66.     uint8_t byte = 0;" H$ y& c' X( O- W1 c$ v( _
  67.    5 b5 C% R* S' x) H3 e0 L4 m
  68.     HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_SET);4 `3 r2 K/ X- N4 P6 V1 n. _
  69.     for (int8_t i = 7; i >= 0; i--)/ B/ |9 Z0 K/ @( p
  70.     {/ e5 R5 ~! ~; x
  71.         HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET);& s4 K  U3 h5 _0 o% S6 t
  72.         HAL_Delay(1); // 稍微延时,确保时序正确
    * L/ T1 G5 A% P7 i$ F: `! u5 r
  73.         HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET);8 V+ x; _& m! d  X! \0 M
  74.         HAL_Delay(1);
    ( H) L% k2 k; @( g
  75.         byte |= (HAL_GPIO_ReadPin(IIC_SDA_PORT, IIC_SDA_PIN) << i);
    ( Z( _) o* Q2 H4 q' K1 t
  76.     }/ d0 L* ~# m2 J' O' D3 f
  77.    
    * e0 j% M, y' Y( n
  78.     if (ack): k$ K7 m3 F* {  E7 B  _
  79.         HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_RESET); // 发送应答
    % l- F$ R3 g$ D* m
  80.     else, q4 _3 \  l) E/ g$ f
  81.         HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_SET);   // 不发送应答; j" p, {4 E1 v1 S9 L
  82.    ) p7 P5 {& w" p) |5 t
  83.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_RESET);# A& d% d$ b, {" s2 |) D) P7 d
  84.     HAL_Delay(1); // 稍微延时,确保时序正确) Y  }1 j+ G+ A/ f! `6 y" K4 U
  85.     HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET);
    * E* a8 w! {3 V
  86.     HAL_Delay(1);( Q: h+ {5 G( {2 |
  87.    - t9 h* ]0 D3 l  ^
  88.     return byte;
    8 z' B; i" l" O5 f
  89. }
复制代码

, e! Q% ]" [* ]; ]: |- \例如IIC的启动信号为:SCL为高电平的时候,SDA从高电平转为低电平。) ?& _" T; a- T. n

$ T+ u/ s$ f0 K# G8 B$ J
IIC的结束信号为:在SCL线是高电平时,SDA线从低到高的跳变。. ]7 A/ f/ P) P& J. ?6 k$ B$ s

; c5 D. G6 o8 |9 i) Q; `) S& ]
因此使用这种方法可以模拟IIC时序完成通讯。2 H" F8 L" }  P4 C. g
7 s" [. k; t# P0 s$ [( f
但是这种方法的弊端也是非常明显的,需要占用CPU,其次这样子并不能确保I2C时序的正确性。所以无论是稳定性还是可移植性还是IIC的效率都欠妥。7 I4 P5 _8 y3 L, Z+ S" c7 ?

* ^3 r- X* H/ e! `6 `6 s7 _7 ]
STM32中的硬件IIC    - N' W$ @9 a& Q, \/ L
STM32系列单片机提供了硬件IIC(Inter-Integrated Circuit)模块,用于支持IIC通信协议。硬件IIC通过专门的硬件模块实现了IIC协议的基本功能,包括起始信号、停止信号、时钟同步等,无需用户通过软件模拟实现。
& k2 m1 _* v0 S  k+ C
: @: J. \2 v' J, g% ?" E
STM32硬件IIC优势:
0 z. f' W6 I8 c  @# a1.高效性: 硬件IIC使用专用硬件模块处理通信,不需要CPU直接参与,提高了通信效率,降低了对CPU的负担。
& a7 y8 n% b: ~. ^1 ~
2.时序精确控制: 硬件IIC模块能够精确控制时序,确保通信的稳定性,避免了由于软件执行时间不确定性而引起的时序问题。% h! `% R, G/ n! Y" W' a% u
3.多主机模式支持: 硬件IIC模块通常支持多主机模式,能够轻松处理多个设备同时访问总线的情况。
, Q) B0 X8 `/ w1 B% V  ]0 P+ o4.易用性: 由于硬件IIC是芯片内置模块,使用起来相对简单,只需配置相应的寄存器和引脚即可。
9 J0 i; ?) t( c5.占用资源少: 硬件IIC模块通常占用较少的资源,对于资源有限的嵌入式系统来说,是一种较为理想的选择。
" k3 C8 K- Z% w* }; V  o# j" \. H
5 @4 z; ?3 I5 \; D
微信图片_20240529192242.png
# H% d* i. H$ I  G
: h7 p+ @- a( @3 G$ a6 W% T在CubeMX中配置好硬件IIC即可利用HAL库函数进行IIC通讯。
  1. static void MX_I2C1_Init(void)( M# s/ T0 W3 X. s0 ^/ y6 R
  2. {
    & z& ?3 {% M% m; s7 t* _; E% @
  3.   hi2c1.Instance = I2C1;
    6 A  z1 o& z. m$ X. ]
  4.   hi2c1.Init.ClockSpeed = 100000;, [% N+ ^7 K/ p& V7 I5 G6 W
  5.   hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;5 q2 I- i. j% @5 N# D8 _- W% k
  6.   hi2c1.Init.OwnAddress1 = 0;9 N1 h4 w. @' n9 V5 f
  7.   hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;: C9 ]2 r$ B( n6 i
  8.   hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;- E9 I' A  s* V5 r
  9.   hi2c1.Init.OwnAddress2 = 0;* \" M, G% L& E' q/ f% |! N
  10.   hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    % z8 o0 s- {. d* ^# R- |/ E) N7 s7 ~
  11.   hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    4 z5 c/ t6 y9 C( d  x
  12.   HAL_I2C_Init(&hi2c1);
    6 F7 e/ E1 A$ x8 ?  `
  13. }
    3 x' D4 d  H: ^5 d6 f$ N

  14. 3 s+ W+ \3 _$ f
  15. + K8 t( @4 P! |1 p+ v' H
  16. uint8_t deviceAddress = 0x50;//设备地址
    : Y9 Y7 J5 P% h5 a/ B& I
  17. uint8_t registerAddress = 0x00;//寄存器地址
    ! _) \( O; Y. g/ i, D! v' m! Q+ F/ ?* J
  18. HAL_I2C_Master_Transmit(&hi2c1, deviceAddress, &registerAddress, 1, HAL_MAX_DELAY);
复制代码
% }6 f! J7 T3 C0 k4 w; m7 T1 B
调用CubeMX的初始化函数,之后就可以使用例如HAL_I2C_Master_Transmit,HAL_I2C_Master_Receive等函数来实现IIC通讯。3 T/ H- Y5 u8 O' g3 `9 d6 e

+ W7 p# _9 c( \1 w9 _3 t. D
2 _" D8 \$ U9 O2 U' o* tSTM32硬件IIC缺点:1 U8 B( e! g! L- x/ y. S, n/ a
1.资源占用: 相比软件IIC,硬件IIC模块可能会占用一定的硬件资源,因此在资源受限的系统中需要谨慎选择。/ o: J, W" f& g" x5 x4 j+ T7 |) }
2.灵活性: 硬件IIC通常由芯片内部硬件模块实现,因此在一些特殊场景下可能缺乏一些灵活性,例如无法更改时序。  X& V# a& J7 y6 B/ J2 H" V& s, ]
3.部分限制: 不同型号的STM32芯片的硬件IIC模块可能存在一些差异,不同芯片的IO不一样,所以设计时需要谨慎检查。$ }- I' e5 p1 d: {  y0 D. |  j
/ n- H/ E) g8 Z! |# ^5 f/ a: I  M
总体而言,STM32的硬件IIC是一种高效、稳定的IIC通信方式,特别适用于对性能要求较高的应用场景,同时在易用性和可靠性上有较大优势。在选择IIC通信方式时,可以根据具体需求权衡硬件IIC和软件IIC的优缺点。6 A1 y8 C0 g8 m2 A
! d1 p2 C6 a  Y' L5 l6 W- u
3 F/ R" B6 c6 b+ T
. ?3 @0 s4 K) M/ F6 O6 V: n
转载自:电路小白
2 ]# Y0 V( B+ k; ]* v& w; v- s$ j如有侵权请联系删除: G+ v' r: l' q; c& L

1 H5 k/ @- u) T  H
收藏 评论0 发布时间:2024-5-29 19:23

举报

0个回答

所属标签

相似分享

官网相关资源

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