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

【经验分享】STM32G031K LL库的使用 - IIC

[复制链接]
STMCU小助手 发布时间:2021-11-10 22:53
说明:驱动基于STm32G031K6,其他型号需自行做改动。
/ d$ e4 B* @: Z( v: {) |; l* q7 q- G
注:因为之前项目暂未用到LL库的IIC,所以此驱动未经过实机验证。欢迎反馈使用中的问题。
( m! u( m; R' V( Z0 H
5 y5 c* n" G' Z- @' ], yIIC的初始化: CubeMX生成
, H& _7 H9 q3 R5 e2 G; C5 U6 F( M5 |4 z- h  K! F
  1. void STM32LLI2C1_Init(void)3 h. T% k' r* d9 S
  2. {; k- U8 f+ d3 N8 f
  3.   LL_I2C_InitTypeDef I2C_InitStruct = {0};
    6 E3 E! C5 u& J

  4.   ~0 p( M: C  Z/ h
  5.   LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
    9 q: Q* Q+ B; V+ j
  6. % K4 s2 x- j, n; ^3 G$ W
  7.   LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);$ c2 d( P1 [' M$ Y2 E8 Q
  8.   /**I2C1 GPIO Configuration  6 C- A/ o5 K3 r* o) _+ x
  9.   PA9   ------> I2C1_SCL
    1 a- A6 F3 b1 n; c6 n! n2 G
  10.   PA10   ------> I2C1_SDA
    5 Y% h" }! `# h
  11.   */" f5 y% A, [6 @2 F8 N0 w- v
  12.   GPIO_InitStruct.Pin = LL_GPIO_PIN_9|LL_GPIO_PIN_10;
    ) D1 G# G$ O5 ?9 ?" a! z
  13.   GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
    * C! h+ J8 y" e" P0 `+ d6 }$ j
  14.   GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;  o7 {7 q& y. ^1 w; N# A
  15.   GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;* M- `8 M1 G& ~# a; Q; e
  16.   GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;6 t) U  G# p9 C% h  e" b! V# \
  17.   GPIO_InitStruct.Alternate = LL_GPIO_AF_6;
    " y+ K% [. v# ^7 n' x8 Q
  18.   LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    : E* D, L! i9 |7 l. O4 I
  19. ; k' ], G  E" g1 v( e3 u$ ^. [9 j
  20.   /* Peripheral clock enable */4 n" f) f. _5 ]1 h5 l; e
  21.   LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
    # h. l% e/ A1 F' L: U
  22. ) H' `1 P% a6 \. m# Y
  23.   /** I2C Initialization " m. C) K/ P) @' N
  24.   */5 [6 ~+ t8 R# a' Y1 A( ~; Q
  25.   I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
    0 o/ k, g& T0 L4 K$ @0 l
  26.   I2C_InitStruct.Timing = 0x00303D5B;
    1 K1 K8 K# A3 a1 ^
  27.   I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE;
    ! q. _" L# U- C0 q
  28.   I2C_InitStruct.DigitalFilter = 0;
    8 [, s# Q2 {# l) H% y
  29.   I2C_InitStruct.OwnAddress1 = 0;
    ; d; l: _6 W# G
  30.   I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;+ Y2 s2 l  ^* f5 Q( L
  31.   I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
    : b% N' {8 ]6 U+ u' F( T% `- {  q
  32.   LL_I2C_Init(I2C1, &I2C_InitStruct);: r4 _' G8 e1 D- v! S
  33.   LL_I2C_EnableAutoEndMode(I2C1);
    " t- W, n: H) B% N
  34.   LL_I2C_SetOwnAddress2(I2C1, 0, LL_I2C_OWNADDRESS2_NOMASK);* |9 C- d" f% D1 B9 J2 x! F: T
  35.   LL_I2C_DisableOwnAddress2(I2C1);
    + I" N, e, w# n9 D) o1 h1 T5 e
  36.   LL_I2C_DisableGeneralCall(I2C1);, [: o% A; b. w/ ^& v, l4 ~
  37.   LL_I2C_EnableClockStretching(I2C1);4 C4 L1 w7 g) A+ {- ]: n
  38.   LL_I2C_Enable(I2C1);& h" d) B. B. e, M
  39. }
复制代码
: F/ y* C; L7 r3 K9 s
由于LL库未提供与HAL类似的I2C多数据读取的函数接口,所以需要自行编写函数,我这里是参照HAL库内的HAL_I2C_Mem_Write和HAL_I2C_Mem_Read写的LL库可使用的相对应函数。
1 x4 \/ g2 W! o1 [6 P5 q: w+ a0 L+ s7 z4 c
I2C读多个数据:" @  t5 o/ k1 o  E, D  J1 p4 s
6 F4 r4 G, r, w( V  ]' L1 o7 N  w
  1. void STM32I2C1_MasterRead(uint8_t device_7BitAddr, uint16_t mem_address,uint16_t mem_size,uint8_t *pdata,uint8_t length)
    3 ~, J5 D0 q3 q8 l% j
  2. {3 _, D. t* r; \% I% l
  3.     //等待iic空闲
    & I$ C# \3 _+ y! K! @/ m+ Z7 h( p8 B" H
  4.     while(LL_I2C_IsActiveFlag_BUSY(I2C1));3 d; w# [, o1 Z* m8 A! V5 C
  5.     //确认iic是否使能/ j) ?8 ?- H3 [/ @
  6.     if(!LL_I2C_IsEnabled(I2C1))) a  X% @4 w" b. A/ v8 O2 u% d
  7.     {
    & \0 s, r# E2 K5 t4 j( c! g
  8.         LL_I2C_Enable(I2C1);
    ' N/ _+ l5 Z9 M) S  t
  9.     }
    * T* \4 ]/ |) o9 N3 u  n; P
  10.     //配置
    , N" T; m- ^5 M$ M! a
  11.     LL_I2C_HandleTransfer(I2C1,device_7BitAddr,LL_I2C_ADDRSLAVE_7BIT,mem_size,I2C_SOFTEND_MODE,I2C_GENERATE_START_WRITE);
    ) J' a0 p0 x1 Z5 o
  12.     while(!LL_I2C_IsActiveFlag_TXIS(I2C1));6 P6 j# c9 M! @( Y
  13. " A+ ~* A5 o% `; e
  14.     //写入从设备寄存器地址
    & m6 g3 L& ?& Y( a) T/ N( v. z6 S
  15.     ucBSP_I2C1_WriteMemAddr(mem_address,mem_size);
    , P  P' m$ w8 z, x! K, L
  16.     while(!LL_I2C_IsActiveFlag_TC(I2C1));
    0 A" V( E/ i( w/ l- t+ B+ R
  17. & g. I; F! ?0 R8 ?, q
  18.     //配置
    6 p+ N$ f- c- z! L# R" o
  19.     LL_I2C_HandleTransfer(I2C1,device_7BitAddr,LL_I2C_ADDRSLAVE_7BIT,length,I2C_AUTOEND_MODE,I2C_GENERATE_START_READ);6 D, _8 M! u/ S
  20. - z7 G* x, U& Z* w. x6 W$ ?! N
  21.     //读取数据
    " `% i/ X+ Y+ C, y6 J. L
  22.     ucBSP_I2C1_ReadMultipleData(pdata,length);
    1 ]0 l8 o( I! H
  23. : P4 k. E1 Z  a: b
  24.     //等待停止完成8 o' ~, R4 M) t+ p# V$ S
  25.     while(!LL_I2C_IsActiveFlag_STOP(I2C1));, _, r% e" S4 h8 R0 Y% d+ M9 R
  26.     LL_I2C_ClearFlag_STOP(I2C1);
    - l! Q+ G% u/ K& ^
  27. }
复制代码

( N% J$ A" `( E% L9 [I2C写多个数据:# x: Y& J- s" K0 L2 @

  C9 h* _0 L. q% B$ D) G
  1. void STM32I2C1_MasterWrite(uint8_t device_7BitAddr, uint16_t mem_address,uint16_t mem_size,uint8_t *pdata,uint8_t length)) [9 S# |4 G! C
  2. {3 j1 m% ^' A1 _  W  w
  3.     //等待iic空闲0 V$ d+ F# S0 d, v" p
  4.     while(LL_I2C_IsActiveFlag_BUSY(I2C1));* [! ]# r4 X9 Q% F  j
  5.     //确认iic是否使能% o, J5 G( b: b
  6.     if(!LL_I2C_IsEnabled(I2C1))0 T. c( h( w/ }% O% _
  7.     {8 X0 S. ^* _2 c- V8 z5 O
  8.         LL_I2C_Enable(I2C1);, U5 D2 W: u0 n# B
  9.     }
    + V- ]1 N5 W0 N" p6 x
  10.     //配置为写( Q& Y( q3 J5 ?. G) L7 m& g0 k8 y
  11.     LL_I2C_HandleTransfer(I2C1,device_7BitAddr,LL_I2C_ADDRSLAVE_7BIT,mem_size,I2C_RELOAD_MODE,I2C_GENERATE_START_WRITE);5 O3 L( i( \1 u' }& w
  12.     while(!LL_I2C_IsActiveFlag_TXIS(I2C1));) E- \6 J" H- n& Y8 c+ T
  13. ; E6 r: ?/ X  @$ T8 V
  14.     //写入从设备寄存器地址
    3 Q7 s5 r; H* X" M
  15.     ucBSP_I2C1_WriteMemAddr(mem_address,mem_size);# z/ D8 c! |' K' M5 o
  16.     while(!LL_I2C_IsActiveFlag_TCR(I2C1));) e. m* x, Q9 S4 D6 Y

  17. . q- \6 M/ G; z6 Z  _5 z
  18.     //重新配置为自动停止模式3 ]" ~! K9 h/ ]( Y; y+ L4 L8 M. ^
  19.     LL_I2C_HandleTransfer(I2C1,device_7BitAddr,LL_I2C_ADDRSLAVE_7BIT,length,I2C_AUTOEND_MODE,I2C_NO_STARTSTOP);
    & M. [9 ~  W( d( m! n5 n' i
  20. # q, ]4 ~# `8 R3 A3 N
  21.     //写数据( W( \+ @. z, F
  22.     ucBSP_I2C1_WriteMultipleData(pdata,length);( s  t4 A: I; J8 f4 Y
  23. 6 w: K* N- r; |# p
  24.     //等待停止完成& t* x" w$ a& @
  25.     while(!LL_I2C_IsActiveFlag_STOP(I2C1));) {  f& \7 n/ {, I
  26.     LL_I2C_ClearFlag_STOP(I2C1);
    * H5 m( d( `; x7 n
  27. }
复制代码

6 b  X  s& ]3 g+ \; K* o2 Z+ D为了减少代码重复和增加可读性,对读写的一些过程另作了函数;; V4 b8 Q/ W& |8 H- }1 I% U- J* c
+ ^; H' f$ d6 A
写寄存器地址:: ^$ z: n' H& y* M3 }6 F8 y
! T& {- g( q: c6 @9 }
  1. void STM32I2C1_WriteMemAddr(uint16_t mem_address,uint16_t mem_size)- `- p& K- v$ J: X' X
  2. {8 F3 I' d  r! t
  3.     uint8_t MemAddrLSB = I2C_MEM_ADD_LSB(mem_address);;
    8 B$ R4 c; N4 j  g9 h
  4.     uint8_t MemAddrMSB = I2C_MEM_ADD_MSB(mem_address);;
    ( z) k, m& @+ z: o
  5. 1 i. W6 x' D0 P& h" Q9 X4 f
  6.     //发送器件寄存器地址
    2 `$ b+ ?1 ?- m7 p# `
  7.     if(mem_size == I2C_MEMADD_SIZE_8BIT)
    8 E: y% h$ a7 |
  8.     {
    % C& @9 y/ ~( S* S; N# }( w; c3 X
  9.         LL_I2C_TransmitData8(I2C1, MemAddrLSB);
    4 L, S9 j; e" e" I$ K: r
  10.     }else{
    * g( t! t! r- O2 z2 Z6 m
  11.         LL_I2C_TransmitData8(I2C1, MemAddrMSB);7 r! ]7 _: f7 o1 {& ]' v( y/ A
  12.         //等待发送完成, O  M8 ]8 H* L( z
  13.         while(!LL_I2C_IsActiveFlag_TXIS(I2C1));
    1 d3 V1 s: u1 x$ J5 z
  14.         LL_I2C_TransmitData8(I2C1, MemAddrLSB);
    4 f8 W/ |% Y' p" T& Y  a
  15.     }
    . ]3 A/ T/ P3 o" @
  16. }
复制代码

. s& A) j/ J, d( U* C连续写入小于255个数据:' n8 V) K1 q: f1 I

9 m& \5 Z& M) {! N% R! j) \
  1. void STM32I2C1_WriteMultipleData(uint8_t *pdata,uint8_t length)8 b" L* O9 B1 O2 n0 U( W
  2. {
    - k& q5 X7 U( I  ?
  3.     uint8_t count;# J4 i3 q, x+ j) \7 P) L0 b
  4.     for(count=0;count<length; count++)$ O# l( Y7 c  m* ?, a( ?8 D
  5.     {
    2 X$ X( w0 Y6 ?$ r. `) M! U
  6.         //等待发送完成. \4 Q' X& ^5 h/ q' U
  7.         while(!LL_I2C_IsActiveFlag_TXIS(I2C1));8 S3 k4 X  x0 N0 c! x
  8.         LL_I2C_TransmitData8(I2C1, *(pdata+count));
    / z1 @9 `: z& H6 G
  9.     }+ [. h8 g2 }7 m7 [0 B! J( T! o
  10. }
复制代码

+ h' w7 ^  a  s- h. ]: E4 C连续读取小于255个数据:
+ y* G8 p! S* V
: u2 {. h2 x+ p, c+ N& J
  1. void STM32I2C1_ReadMultipleData(uint8_t *pdata,uint8_t length)3 ?$ [4 e" }% d. S9 x0 ?  A
  2. {
    " I  [4 W2 D, j  \
  3.     uint8_t count;& v  G9 Y" s& h9 G
  4.     for(count=0;count<length; count++)
      m/ ~0 ]; i/ G0 e
  5.     {
    ) H. C) m* D& p, `9 M
  6.         //等待接收非空
    ) b7 P; ~8 A& j4 t. s+ n
  7.         while(!LL_I2C_IsActiveFlag_RXNE(I2C1));: F0 M( h& C% x. S
  8.         *(pdata+count) = LL_I2C_ReceiveData8(I2C1);0 U; ^. ]# w4 R6 ~' i) O9 Z9 s
  9.     }& J- ^" E) `; s
  10. }6 L  u" C6 ^8 ^" ?/ v( H; D/ k# T. r
复制代码

5 c! i! _# \& A9 C7 ]& ~$ J9 I& A6 f/ Z& S1 {# O. |9 o
收藏 评论2 发布时间:2021-11-10 22:53

举报

2个回答
Spring_ly 回答时间:2023-1-12 13:32:15
你好,我想问一下,HAL库自带的函数可以连续写入256个字节,为什么改写的LL库的这个不能连续写入256个字节?
submer 回答时间:2023-4-27 15:53:32

有收获,感谢分享。

所属标签

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