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

【经验分享】stm32f3的i2c使用小结

[复制链接]
STMCU小助手 发布时间:2021-12-5 10:44
这几天拿到了stm32f3discovery,拿到手的第一件事就是测试了硬件i2c,使用stm32cube生成库,测试对象为AD5934与ADG715。经过两天的调试,完美调通。中间也碰到了些问题。9 t: D8 c8 s& Y
1、一开始用的I2C1,一仿真就会出现死机的情况。
2 \) g1 r& e- n; A, Y        由于I2C1与swd接口重合,所以调用HAL_I2C_Init()函数后就死机,改成I2C2后问题解决。
0 g! j8 l! o# U: y- e2、无法访问指定地址的设备5 Y4 M( L! X- \# T6 H3 O
        库函数中的入口地址并不是7bit地址,需要输入8bit。我的设备地址为13,始终无法访问设备,改为26后解决。
9 y* f' T2 K2 j- s" Z3、可以读写单个地址的数据,但是不能多字节读写。
; x6 n. y/ ~: O2 {! ?       (1)、对于多字节写, 库函数中的9 ~4 \9 H  u$ P/ [2 O
        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)
2 M5 }! I! u3 \; o4 s, [; e0 \+ [       其中 MemAddSize表示地址的位数,0表示7bit地址,1表示10bit地址。我误认为这个写的字节数,所以导致在写多字节的时候出错。
& P+ L& B6 u2 W3 r' P( b% k. E- k       (2)、对于多字节读,由于AD5934的读操作与库函数的读操作有些出入,所以导致一直读错误。在库函数中写完读的内存地址就开始读,而AD5934中写完block read后接着还要再写一个number bytes read然后才开始读。所以需要对库函数进行修改,新增一个函数,以适合AD5934的block read.
% D0 f3 l2 k. a* c! ^( E1 J3 b0 h- u# u4 W5 t7 l4 C: p0 v

3 y# e. Q4 D! {        stm32f3的i2c有三种模式:Reload、AutoEnd、SoftEnd模式。
1 n& ?) ^6 n0 ?3 a: C! Y
% q& }* J7 t# n( n  O        i2c每发送完一个字节,就会产生TXIS标志,当发送完最后一个字节时:
" q8 o! r0 }* x) c5 W" g0 a' ~/ y$ a+ H* c+ D6 }
        对于Reload模式,当字节大于255字节时,必须使用此模式,此模式下发送结束后,会产生tcr标志。
4 @( }6 N; Z' q
( ^( r3 H) j+ u6 t2 d+ F. A( V& `        对于AutoEnd模式,发送后最后一个字节时,会自动产生STOP。
5 Y, A8 b* t7 q# N! I( I5 |3 ]4 Y0 B8 _0 U: L6 {
        对于SoftEnd模式,发送完最后一个字节时,会产生tc标志,对于发送过程中需要Restart的需要使用此模式。
) ?- C  V: o% H+ Z9 E6 Q: z. \, Y3 d& t" d) f8 E) F! Z  O
        对于AD5934的读操作,可以事先工作在SoftEnd模式,发送完block read与number bytes read字节后,再转入AutoEnd模式进行Restart,读取完指定的字节后自动产生STOP。操作流程如下:, k; O7 K  Q% @% n: |* k6 W( O

+ z7 `% O  v2 \# `
  1. HAL_StatusTypeDef   HAL_I2C_Mem_Read_AD5934_Block ( I2C_HandleTypeDef   * hi2c ,   uint16_t   DevAddress ,   uint16_t   MemAddress ,   uint16_t   MemAddSize ,   uint8_t   * pData ,   uint16_t   Size ,   uint32_t   Timeout )+ f6 r. O0 s9 A* s! t
  2. {
    : d1 M% L7 o& H; X3 ]
  3.    uint32_t   Sizetmp   =   0 ;8 E, u6 O0 S, P7 p  s7 z
  4. / V5 V" N4 ]+ y
  5.    /* Check the parameters   */
    # f/ l6 T  K( j9 H8 X) m- \7 R0 {
  6.    assert_param ( IS_I2C_MEMADD_SIZE ( MemAddSize ));
    ) @$ ?9 I4 [, {+ X
  7. * @% M; O# ?5 W' L! I+ i
  8.    if ( hi2c -> State   ==   HAL_I2C_STATE_READY )
    0 ^$ d( t' l! L/ F  M1 m4 N# Y, e% m
  9.    {     ( l9 w' }* Y+ Z/ A
  10.      if (( pData   ==   NULL )   ||   ( Size   ==   0 ))  ; Y0 c7 B% Z! G3 \: J6 a
  11.      {
    1 l5 d. a9 Y# C. a3 ^7 @
  12.        return    HAL_ERROR ;                                    
    5 j2 h! W) ?! |& v/ h. {% I
  13.      }8 G0 n8 _; k- h, ^0 a3 u
  14. 6 i  A3 X- d9 X0 Q% j6 r' \, Y
  15.      if ( __HAL_I2C_GET_FLAG ( hi2c ,   I2C_FLAG_BUSY )   ==   SET )5 f/ z& L  }" `/ q7 M
  16.      {
    + l6 F1 m6 U) L4 b' k
  17.        return   HAL_BUSY ;
    ' W' k. M8 ~& A0 L6 k: Y) j* z6 n
  18.      }9 h5 L; N6 t! ^% i4 D
  19. * f! \! G7 |) P; E/ k4 O
  20.      /* Process Locked */
    $ K9 S/ t7 H: a1 C! \5 F
  21.      __HAL_LOCK ( hi2c );
    5 f, E5 V" V" K5 k' [4 N8 z9 U) e

  22. + J/ M, Z; G( F- S
  23.      hi2c -> State   =   HAL_I2C_STATE_MEM_BUSY_RX ;
    # L7 v2 b# O5 A1 @
  24.      hi2c -> ErrorCode   =   HAL_I2C_ERROR_NONE ;
    9 ?/ G5 E+ d# @/ v. t+ X
  25.      /*
    0 J/ T0 c: I. E' x
  26.     //Send Slave Address and Memory Address % ~, ]7 b0 U( a$ U
  27.     if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout) != HAL_OK)  f6 }* @9 F% |; B3 V- P! Z
  28.     {# S0 @" s" d2 C, t* a
  29.       if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)- D( z: I) P+ r) f* r, d
  30.       {: o3 W, A; b* N, F
  31.         // Process Unlocked 2 _" j( ?% E, i! O' Y
  32.         __HAL_UNLOCK(hi2c);8 X# B5 o+ M7 B4 ~( _
  33.         return HAL_ERROR;
    # L! X! i, Y, @
  34.       }
    9 m+ _/ Z2 U; u* }' J9 z, L9 ]
  35.       else8 |  i# P! D7 k4 n
  36.       {
    ! Z* l% E: T% o- u2 R
  37.         // Process Unlocked
    , V6 a. \. l8 G/ U
  38.         __HAL_UNLOCK(hi2c);8 d$ b2 z" j- e7 r# D8 s
  39.         return HAL_TIMEOUT;5 M; ^' u% A6 M) V* j
  40.       }
    . \8 J# z, Z4 h. [$ }
  41.     }*/) @$ K- L/ ^: L& m

  42. 2 x! j9 t0 }! {, M: k" v' k
  43.      I2C_TransferConfig ( hi2c , DevAddress , MemAddSize + 1 ,   I2C_SOFTEND_MODE ,   I2C_GENERATE_START_WRITE );
    9 v, v) F, W/ \1 H+ S
  44. . u/ E3 t3 y; J' y
  45.      /* Wait until TXIS flag is set */
    7 B3 A' {  ]; H
  46.      if ( I2C_WaitOnTXISFlagUntilTimeout ( hi2c ,   Timeout )   !=   HAL_OK )
    : @3 A1 ^( S+ ^0 s
  47.      {9 U) Y0 L" D' m0 a& U$ Y
  48.        if ( hi2c -> ErrorCode   ==   HAL_I2C_ERROR_AF ). ]! M: P3 X4 D) }, X' V5 s
  49.        {: S2 p; v& p9 O, Q6 x$ z+ t
  50.          return   HAL_ERROR ;: k. ^0 r! _5 s0 j3 _/ c
  51.        }8 x- s9 _+ x* t; g
  52.        else
      H/ q8 w! h, A9 ?( C4 q
  53.        {
    / E3 R: e  C0 D8 i+ L' `: e
  54.          return   HAL_TIMEOUT ;
    $ J/ |9 h7 ]4 C: h7 J; N
  55.        }
    # a3 x2 R9 }( A0 G+ k" w
  56.      }% D" m- F! i. x0 [' t! W! l

  57. 3 E& ^4 @6 n- ~3 ?' c
  58.      /* If Memory address size is 8Bit */
    ) c+ ]% u3 a8 [9 a
  59.      if ( MemAddSize   ==   I2C_MEMADD_SIZE_8BIT )
    7 K4 B) |, D7 q/ |8 x; J$ x9 H
  60.      {* q5 Y; G$ w6 Y' ~# u; t8 U
  61.        /* Send Memory Address */9 x8 a/ [# I' R2 O: j
  62.        hi2c -> Instance -> TXDR   =   __HAL_I2C_MEM_ADD_LSB ( MemAddress );     3 v$ U7 p% X" I" L
  63.      }       ; N! f7 W6 v+ m
  64.      /* If Mememory address size is 16Bit */
    ( E; ?  R: y7 E0 r& P* l7 g, S
  65.      else) c6 U# D: p5 O/ h: S* @4 H
  66.      {
    0 f) j9 k% Q5 S; P, N/ C
  67.        /* Send MSB of Memory Address */! Y0 k( s* T! z  i/ s% J  v$ k
  68.        hi2c -> Instance -> TXDR   =   __HAL_I2C_MEM_ADD_MSB ( MemAddress );  1 V( Z/ x% d8 W8 R7 R

  69. ) }3 {/ V, [, K) q% ~! k
  70.        /* Wait until TXIS flag is set */7 H4 H  L1 P& d8 v( o8 I5 r- a
  71.        if ( I2C_WaitOnTXISFlagUntilTimeout ( hi2c ,   Timeout )   !=   HAL_OK )
    7 F2 k/ ]7 m: B9 M" F1 P% f2 I
  72.        {
    1 p7 x: H" E# G0 o4 G) }5 Z
  73.          if ( hi2c -> ErrorCode   ==   HAL_I2C_ERROR_AF )
    1 o6 R: D1 {9 a. V7 }3 Y6 [
  74.          {
    0 Z+ V5 U7 R' y. t
  75.            return   HAL_ERROR ;' d+ L, a6 E6 D
  76.          }
    - A( h% i+ ?4 m
  77.          else6 t2 H) L, K. k1 @- r
  78.          {
    # V/ e' G& H  p, o, q& S# \
  79.            return   HAL_TIMEOUT ;
    ' L! q! T% q( \6 k  i; }
  80.          }/ J; T4 r, ~4 S: W/ c7 g4 f# U+ o
  81.        }" y% F' \; p2 n- I  v
  82. + @/ h" A0 R0 p+ n
  83.        /* Send LSB of Memory Address */" C2 n( G' _% j5 M* g
  84.        hi2c -> Instance -> TXDR   =   __HAL_I2C_MEM_ADD_LSB ( MemAddress );   
    ! ~, l6 d# W8 R# G
  85.      }
    0 h/ I8 g' D. D

  86. ; {+ L2 J' j$ C
  87.      /* Wait until TXIS flag is set */% g/ e! l( }& ^3 m& f: K
  88.      if ( I2C_WaitOnTXISFlagUntilTimeout ( hi2c ,   Timeout )   !=   HAL_OK )5 r: M% z9 f; |- V* q/ f
  89.      {
    2 O& v* C9 c1 x$ ^) V" S
  90.        if ( hi2c -> ErrorCode   ==   HAL_I2C_ERROR_AF )
    . K, O" m5 f0 n; R3 V
  91.        {
    % ]3 A  K9 I4 H  W
  92.          return   HAL_ERROR ;3 ]& ]: `, {5 l7 n: w
  93.        }
    5 e+ m( l2 i( G1 V# x7 b
  94.        else
    $ r1 n( y' J2 {8 c# n: D
  95.        {( u+ W; F/ q' P' O
  96.          return   HAL_TIMEOUT ;7 X  J( ?5 X6 [) i% A6 n* W
  97.        }. r. t/ m4 O# t" s! e
  98.      }
    9 Z! i- {% r6 b) T0 r

  99. - U0 b* m. }& Z
  100.      hi2c -> Instance -> TXDR   =   Size ;  
    2 L4 A: X* R7 k; R& K

  101. 9 J) g6 J/ _0 ]" Q
  102.      /* Wait until TC flag is set */
    ( w8 M% i7 n- s( n* ~8 _5 X0 X" T
  103.      if ( I2C_WaitOnFlagUntilTimeout ( hi2c ,   I2C_FLAG_TC ,   RESET ,   Timeout )   !=   HAL_OK )       . m% ~. L7 K$ V2 l: w
  104.      {0 E+ P6 A; D2 ^/ z" Z8 m7 m6 d2 |
  105.        return   HAL_TIMEOUT ;
    4 Y% w. C% T' ~% ~
  106.      }     
    - H4 u% n% u0 t$ |

  107. 3 t; M* o  g3 T) f" F
  108.      /* Send Slave Address */
    ) m$ P- A* j5 x4 Q% @. l
  109.      /* Set NBYTES to write and reload if size > 255 and generate RESTART */3 U+ G* m; i$ w  I0 v8 ]* y
  110.      /* Size > 255, need to set RELOAD bit */9 h" B/ |9 S/ P1 O3 H
  111.      if ( Size   >   255 )( _8 T8 \( ?: s3 Q4 g) ^
  112.      {
    & u% k! P5 V( `
  113.        I2C_TransferConfig ( hi2c , DevAddress , 255 ,   I2C_RELOAD_MODE ,   I2C_GENERATE_START_READ );( t6 l& z) k! U' r; v7 `0 F
  114.        Sizetmp   =   255 ;4 i9 m& ^, I6 K% _, M, U1 g9 D# O: f
  115.      }; i+ K, q2 @9 @' _% `
  116.      else
    " P4 y4 \( |) q9 H  q" R9 T
  117.      {
    & m4 m' H# g: J$ q6 s; M8 ~
  118.        I2C_TransferConfig ( hi2c , DevAddress , Size ,   I2C_AUTOEND_MODE ,   I2C_GENERATE_START_READ );
    , R' [/ o" m8 @9 d* }4 ]0 \
  119.        Sizetmp   =   Size ;7 N4 l$ m2 x: y2 N) r' V; j8 X4 s
  120.      }
    , A9 o3 G; K) R5 J
  121. / p# r2 b" \" O
  122.      do
    8 C) X; `4 m- u" y
  123.      {   
    7 G" W& q4 V8 B, ~6 w
  124.        /* Wait until RXNE flag is set */
    ! Y  V' H# D8 k+ t, a& [
  125.        if ( I2C_WaitOnFlagUntilTimeout ( hi2c ,   I2C_FLAG_RXNE ,   RESET ,   Timeout )   !=   HAL_OK )       ' Y7 I7 R: c( U0 ]; A' S  @
  126.        {) e# y' Y: f4 b# i* M
  127.          return   HAL_TIMEOUT ;
    , e, p. S" a4 T; f2 p- m
  128.        }
    - c: G! |& d7 O9 p; f$ N3 f# z

  129. ( O' w  C& r2 R5 R- L+ t
  130.        /* Read data from RXDR */
    , i" `; s/ r: h+ O
  131.        (* pData ++)   =   hi2c -> Instance -> RXDR ;, [* H0 I7 ~0 g% {# `. f/ Z8 j5 N

  132. ! |' B; P3 g& g2 P
  133.        /* Decrement the Size counter */9 t, @. x0 t8 r5 {' d/ F
  134.        Sizetmp --;8 l1 Z, Q* k. {: i2 A6 o4 y. q
  135.        Size --;    1 ?' N: z$ N: x; ~: s$ ~4 V
  136. - D1 _: e) N# `4 l9 Y
  137.        if (( Sizetmp   ==   0 )&&( Size != 0 ))
    * Y: H: L- L, _8 E! z; E
  138.        {6 M& G5 D0 _+ Q% l2 V
  139.          /* Wait until TCR flag is set */
    ; j& g. i! P# X4 `7 }
  140.          if ( I2C_WaitOnFlagUntilTimeout ( hi2c ,   I2C_FLAG_TCR ,   RESET ,   Timeout )   !=   HAL_OK )      
    & K7 w2 R. F6 M3 X' A: J" H* O* h) S0 D
  141.          {
    & c; ~# y6 K* J/ R6 m) }
  142.            return   HAL_TIMEOUT ;5 X& S5 I( w' A5 G. [! Y, Y
  143.          }
    # q5 B6 n' J# n0 f! e, T* v
  144. 8 e% j7 N# i4 Z; |
  145.          if ( Size   >   255 )
    7 ]. O( w0 l3 Q' u- _5 [" n
  146.          {
    - h3 a; D6 ^$ m* E9 k" R
  147.            I2C_TransferConfig ( hi2c , DevAddress , 255 ,   I2C_RELOAD_MODE ,   I2C_NO_STARTSTOP );: u3 ]7 J0 I" @: p# t$ ~6 U! I2 f
  148.            Sizetmp   =   255 ;) I% H6 G  m% b7 d2 A
  149.          }; q* u1 C! e+ }9 a& ~! S
  150.          else! F/ ~8 f, `1 R; V
  151.          {
    ! N1 g  z0 p& p( ^
  152.            I2C_TransferConfig ( hi2c , DevAddress , Size ,   I2C_AUTOEND_MODE ,   I2C_NO_STARTSTOP );
    ) R* e: r2 x/ y4 U3 j" t7 o
  153.            Sizetmp   =   Size ;
      s2 z) B( V3 ?# N
  154.          }
    # u; Z" R# Y1 h8 y4 r, C- l
  155.        }
    * ~; ^8 a; m' m9 v

  156. 9 [5 {6 j0 Q/ O
  157.      } while ( Size   >   0 );  n7 l0 N3 i: o- {4 H

  158. # f" d$ b, r9 ]! o! H* g3 l3 p1 M
  159.      /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */& F" ~5 Q+ @9 C1 X- ?0 O* M2 ^
  160.      /* Wait until STOPF flag is reset */  
    6 t. ]0 g9 f9 x; f6 a
  161.      if ( I2C_WaitOnSTOPFlagUntilTimeout ( hi2c ,   I2C_TIMEOUT_STOPF )   !=   HAL_OK )/ ]) W* O! N) U6 J
  162.      {
    ; x. B( T9 e4 O3 d0 K3 b" K& C
  163.        if ( hi2c -> ErrorCode   ==   HAL_I2C_ERROR_AF )9 H) f/ c3 M/ h/ t
  164.        {% N" H3 k8 O6 C* v8 t' Y, v- a
  165.          return   HAL_ERROR ;
      T' e! c3 I  N' z8 u& q
  166.        }
      q, d" @4 O+ i  f4 |" n
  167.        else1 H7 ^& N. P3 w- r) U6 @/ q6 |
  168.        {
    " W6 w2 \5 ]0 @+ z
  169.          return   HAL_TIMEOUT ;
    ! Y: i  f! p' r" M: e
  170.        }
    - w0 R' Q, i* a  \2 G+ u
  171.      }" R0 t0 l4 U, N# T. i. b/ y

  172. 3 v# l5 z1 B1 y% J! }% {
  173.      /* Clear STOP Flag */$ }; f8 _# J$ y3 Y8 t
  174.      __HAL_I2C_CLEAR_FLAG ( hi2c ,   I2C_FLAG_STOPF );
    8 a% r8 c- S5 n! q7 ?$ ]
  175. ( d2 T# I/ }+ q7 D) C2 m
  176.      /* Clear Configuration Register 2 */
    9 W, e: }3 O6 x, j1 y
  177.      __HAL_I2C_RESET_CR2 ( hi2c );
    4 v/ x. y) ^( i+ E

  178.   Q% b. L1 ]# G2 g+ e6 J2 \
  179.      hi2c -> State   =   HAL_I2C_STATE_READY ;
    . K. x; n( h+ e9 U6 j

  180. ! s1 p$ c8 a( K% M" P$ d4 N
  181.      /* Process Unlocked */
    ) z# V" S6 j# ]. I1 C4 W4 G% C
  182.      __HAL_UNLOCK ( hi2c );
    8 O5 y3 ?+ B4 Q: Q% w( U) Q  _

  183. " v  T* n' v5 S3 F5 y
  184.      return   HAL_OK ;5 Z! W2 [# T3 m: q
  185.    }
    * i1 ~0 ?4 W1 [9 @: g0 X6 C8 c
  186.    else
    9 a# E3 ~4 F8 z# ~2 o, V+ v
  187.    {
    3 F5 Q, S$ N/ g, J9 j& O
  188.      return   HAL_BUSY ;! V/ o. C; i' O! ]
  189.    }
    ' A" q5 b, T0 ^- N+ v6 I: Z
  190. }
    6 U5 e6 A  c: N
复制代码

) ~3 @+ U% W5 D2 u; ?# ?* p, i
. @- M' ^7 [4 V: O' ?
赞 收藏 评论0 发布时间:2021-12-5 10:44

举报

0个回答

所属标签

相似技术帖

官网相关资源

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