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

STM32L051测试I2C协议设备的添加经验分享

[复制链接]
攻城狮Melo 发布时间:2023-6-12 19:11
1、CubeMX IO口的设置

模拟I2C的IO口都设置为开漏输出,因为电路图上有外部上拉。初始化的时候,2个SDA和SCL都得拉高。所以设置如下:

/ h7 ~5 x+ R% O9 C0 D+ a2 y, x0 t- ~, j

8 U- M* f8 W5 J0 e) Y" Z 微信图片_20230612191118.png 5 o/ w+ J' C6 o% I% h
# P. b  f" d% V6 e. v3 N0 @

1 r, m7 u& s, y3 [( a. f0 [2、HAL库中的us延时函数+ Y2 S0 A& S2 P) y% q* V

在HAL库中,只有ms的延时函数HAL_Delay,没有us的延时函数,今天用了网上一个延时函数,发现有问题,搞得整个时钟出了问题,郁闷,折腾了一下午。时间浪费了,通讯模块那边因为这个时钟设置也出了点问题,一直返回复位信息,用了怎么多年的芯片还第一次遇到,Enocean 的TCM310模块,主要这个技术支持也不太好找。= =!还是快速找一个us函数,不是那么精确也可以,直接用空语句测试,后面已经经过测试,下面这个函数做的us延时可以正常移植以前的I2C程序。

  1. /* USER CODE BEGIN 4 */1 N2 N' q9 j) r/ X. i
  2. void delay_us(uint32_t Delay)
    6 {( ?3 k/ Y$ l; b0 ]# |, ^5 s0 t
  3. {
    0 D8 L0 b( w; g" J+ G: J$ V
  4.   uint32_t cnt = Delay * 8;    r! |: e. B" u0 k3 B
  5.   uint32_t i = 0;
    . ~1 D! p4 Y' a" F- q4 {/ I" o
  6.   for(i = 0; i < cnt; i++)__NOP();
    5 b% ~+ b2 j  T* b
  7. }3 F  S: }; a! Z' }  f( u
  8. /* USER CODE END 4 */
复制代码

4 w  k! T  R' L" a( j3、移植I2C代码3.1  SHT21温湿度传感器

代码移植没什么问题, i2c.c:

  1. #include "i2c.h"
    : P, R5 D5 g. r! q1 i- |8 S
  2. 7 a2 u8 U- u5 T' f2 @: F
  3. // ------------------------------------------------------------------" B1 k. `( _8 X. J$ G% j
  4. void i2c_init(void)  {, V9 Y+ J# J4 `/ G; P
  5.   
    / u% n/ k$ ?! J+ ?' K
  6. // the SDA and SCL pins are defined as input with pull up enabled1 W9 W4 w0 b! l7 Y6 a8 X7 F4 L
  7.   // pins are initialized as inputs, ext. pull => SDA and SCL = high7 B1 j2 b& s/ @/ b6 k, B. S

  8. 7 l( I8 u  r6 V9 @/ @* Z
  9. }& V, H6 C2 `3 y- ^* E! w
  10. // ------------------------------------------------------------------# }) `+ S; c5 h8 J
  11. // send start sequence (S)$ _1 K# g: @2 e  k1 z6 G: k
  12. ) v5 w! q! D0 ^) Q7 E
  13. void i2c_start(void)  {                                    
      l0 J) F, i7 V
  14.    sda_high();
    # h: p. z6 P$ ~8 f7 ]
  15.   delay_us(10);: E# \. `  @% ?5 S$ K
  16.    scl_high();  
    4 j: G1 j4 H( w! J% E9 f2 }( P
  17.   delay_us(10);
    : F) R! @) B' y& L! U$ A/ f
  18.    sda_low();
    5 T5 b0 b3 {, C7 u" ]3 T9 s' u
  19.   delay_us(10);6 y2 z% b) p# C$ G4 X
  20. scl_low();                                                   * I& E, }& m2 b/ C, S  s' ?$ a
  21.   delay_us(10);' h5 _* H. J( y
  22. }4 _7 h% i" ?) t. k
  23. // ------------------------------------------------------------------
    9 p  r& _& V5 {! r
  24. // send stop sequence (P)
    ) K3 \" i4 C  Y  g8 j, ]3 B
  25. void i2c_stop(void)  {                             
    % i+ B2 M  S8 Z
  26.    sda_low();                                                                          
    * ]' v& {+ a& K& C& @: d# {/ n
  27.   delay_us(10);" J& ]2 I  x$ J8 S( X8 n
  28.    scl_low();                                       * s0 d/ w$ T/ S" ~, f$ h* y
  29.   delay_us(10);                                 ) F- {4 q* S8 y# L  e: C
  30.    scl_high();                                         
    , o/ I3 R7 k7 W
  31.   delay_us(10);                                       : J! i; F! u9 d
  32.    sda_high();4 P4 ]0 j1 `) Q: i9 F! V
  33.   delay_us(10);3 w% P6 V/ Y' @# z& S8 U6 I% j
  34. }
    8 f5 D; |+ c% n3 \  t
  35. // ------------------------------------------------------------------
    7 K, [8 m7 H5 b! m
  36. // returns the ACK or NACK' O( [) \  V- u7 k) m2 }4 g
  37. uint8 i2c_write(uint8 u8Data) * X5 o, c5 n! \$ |" j9 \7 i: c
  38. {5 F6 |; y/ l' y# |
  39. uint8 u8Bit;
    9 B4 T. A6 h: W' }$ k
  40. uint8 u8AckBit;
    1 v' }. r. a+ Y- t  J8 t5 [6 L1 m
  41. // write 8 data bits; _. i/ R# p) s- U; \1 t, _
  42. u8Bit = 0x80;  //msb first  - `9 \2 ~( ]5 H
  43. while(u8Bit) {4 M* D7 y6 I; K6 U5 A# I2 g3 R0 {& x9 @9 I; K
  44.   if(u8Data&u8Bit) { 6 m4 {5 U- c/ I9 d  E
  45.    sda_high();) ~# I+ `/ K' n% V
  46.    delay_us(20);
    2 y% A. P+ ~! \8 P
  47.   } ' V' P7 K9 t. R4 Y5 D7 a( W
  48.   //& compare every bit
    * N! W. i, _, J! E/ o  I/ v
  49.   else{ , n8 f1 v, h4 B
  50.    sda_low();, _% ~* {) X0 A! Y5 h2 I
  51.    delay_us(20);1 Z; m1 u& a" ^( C( i! ?# x
  52.   }   
    4 {1 k/ @3 q& ^. M" v8 Z
  53.   scl_high();- u: z( k* v( k3 b1 d  ], C
  54.   delay_us(30);
    4 W1 A+ ^- ]" ~; b
  55.   u8Bit >>= 1; & }( c* g% T- N- j
  56.   //next bit( r* f4 @, |. {5 W
  57.   scl_low();
    ) S" Z" M& Q+ X$ u
  58.   delay_us(30);
    8 G, {2 S0 t- }. h2 t
  59. }
    / [2 s" v# U/ g2 k9 |3 @7 _/ n) |
  60. // read acknowledge (9th bit)
    7 o  b) v. C% x" Q4 V
  61. sda_high();                                               + g0 Y. ~. J" R7 f8 t' i
  62. delay_us(10);  
    9 W1 _' b9 F, q& B% E6 p6 ?
  63. scl_high();0 k0 H) t1 \  i! I
  64. delay_us(10);
    $ l( S1 ?" C" S) X
  65. u8AckBit= sda_read(); //#define sda_read()  (sda_port & sda_pin)? 1 :0  ack on bus is low -> u8AckBit = 1   sda_port gpio0   sda_pin SCSEDIO0
    % p! Z! ~( a  K! W/ ^
  66. delay_us(10);" i$ D9 i% B6 o
  67.     scl_low();                                              ! Q5 J: I; k4 d* o
  68. delay_us(10);4 j+ ^+ H  B3 O# h3 h
  69.     return u8AckBit;
    " k4 ]. J  Z' i! F5 `! H
  70. }4 I5 P) U9 e8 u: V6 @/ B5 n; f6 q
  71. // ------------------------------------------------------------------; j& @% R! N; a5 l
  72. // pass the ack/nack % l$ z: m% q! A6 N+ p3 ?. Y, h
  73. // returns the read data
    6 x, U. L8 }' h9 ^9 ]
  74. uint8 i2c_read(uint8 u8Ack)  
    ( P7 P* v/ a% G: k9 h+ K
  75. {
    5 S- S: X% O( A( z1 k5 _% ~; U! u
  76. uint8 u8Bit;
    / H5 K# G: ]/ Q
  77. uint8 u8Data;
    0 S  ~. Q1 ]. U" \2 m. U
  78. u8Bit = 0x80;       // msb first4 c/ `3 Q8 f. [) M5 c% T
  79. u8Data = 0;$ a6 G% r# Y# x
  80. while(u8Bit){; Y+ S0 o4 s' Q0 W+ e1 q3 ?! A
  81.   scl_high();
    # d3 G' J% |& O8 o6 A4 Z; T0 u3 v
  82.   & |- y: |: @  [6 o: I
  83.   delay_us(20);4 s$ S0 P3 j9 b# @+ e8 g, `) ^  K

  84. & ?, x6 g* ]& h* p0 v1 I- O' ~/ ?
  85.   u8Bit >>= 1;    //next bit3 B4 A1 ?7 Z. I; N
  86.   u8Data <<= 1;& U9 ?& b6 P- c, H6 T1 x0 M
  87. 4 U/ v3 O; a7 _: f2 j: \. h
  88.   u8Data |= sda_read();         //(sda_port & sda_pin)? 1 :0      sda_port gpio0   sda_pin SCSEDIO04 T- q1 k7 {% }6 g  {; J
  89.   delay_us(20);
    + u- B  B- k' K- i) B

  90. - S8 D6 D# |* f  U; i$ A
  91.   scl_low();
    # N- e" G+ f) R* [6 A
  92.   delay_us(50);0 E# }$ g( z$ ^- ?
  93.     }: {" |) x  R+ Y9 X0 p: A
  94. // 9th bit acknowledge! [/ o: t% t) \
  95. if(u8Ack==I2C_ACK) {+ W: a) p  m7 S% z
  96.   sda_low();) C  Z5 j* R' ]1 b; n
  97.   delay_us(20);
    % E! f% U" U: G, I9 l1 w4 q
  98. }     
    ' o7 n/ v" @1 s; b5 c7 @) G
  99. //I2C_ACK=03 ~2 g" F2 q. `) {( O' K: D) O( L( L$ U
  100. else {# Z+ v2 i8 i$ G! M( u( F$ b1 J( R
  101.   sda_high();6 W3 G9 [5 q( k( e! r
  102.   delay_us(20);/ M8 E. g! E8 X0 z" l
  103. }  G9 H, w7 h  N' |) w3 g
  104.    scl_high();
    ! W, }% q: W: L) \4 v4 w
  105. delay_us(20);
    0 |8 }$ }$ H* M" s% v
  106. scl_low();
    / |* o. w) ^* Z- r( O
  107. delay_us(20);, U1 i3 u- y$ v" S' S/ p6 U
  108. sda_high();
    9 L' ?4 ]& J/ [1 k1 e+ Y! N* i
  109. delay_us(20);         # ?- S5 d* j5 ~- h
  110.     return u8Data;
    : f6 M, Q5 ]' c. Q0 L' _+ ?
  111. }
复制代码
& i0 I9 o. x1 _

i2c.h:

  1. #ifndef _I2C_H_INCLUDED
    ; X- @$ @0 b  v
  2. #define _I2C_H_INCLUDED* \) C' |- [. ?  j+ f; U  [( |
  3. 5 {  X; }- U% R" I( L0 k0 k( L
  4. #include "main.h"! N" d4 f6 j) b2 \4 O
  5. #include "Datadef.h"- G! O! Y/ U4 ^8 v3 ^- C
  6.         
    . Z/ ~" @2 u! M; v
  7. // #define I2C_CLK_HIGH()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);
    6 P# O/ z8 X4 i- ~# d/ U
  8. // #define I2C_CLK_LOW()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);
    ( ]) }/ d0 O8 |) T1 D" c% \2 H1 l
  9. , O) P, `+ [" u5 c, i" a' \7 ^
  10. // #define I2C_DATA_HIGH()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET);
    ; T7 l- |! F1 N
  11. // #define I2C_DATA_LOW()    HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);  3 y, w" I+ P0 w; t
  12. // #define I2C_DATA_STATE()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);
    * I2 w, \  V* Q" `
  13. - ~  e# i$ U) J$ Q' J2 ]' `
  14. // #define sda_high()  I2C_DATA_HIGH()     // set signals to HIGH first before selecting IN -> slew rates5 Z5 t. G& j6 j  l
  15. // #define sda_low()   I2C_DATA_LOW() 1 O0 m$ v: k+ i' w3 ?* a8 z
  16. // #define sda_read()  I2C_DATA_STATE()    //ack on bus is low -> u8AckBit = 1
    , S( e! E7 |* S8 M+ c8 ~( L
  17. 7 F! f& g: R- `, H. V" m
  18. // #define scl_high()  I2C_CLK_HIGH()     // set signals to HIGH first before selecting IN -> slew rates1 @8 x6 [- \4 k, x& X
  19. // #define scl_low()   I2C_CLK_LOW() , e& S: i/ q. u5 m. x3 M9 n2 b
  20. - O$ E, A9 L( e% }' T3 G7 \; f) z8 N
  21. #define sda_high()  HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET); 1 D) q, q3 k' N+ z/ j# l* A
  22. #define sda_low()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);9 I5 N6 Y) t4 r# D2 f' v7 A
  23. #define sda_read()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);5 _( R) e0 T* _" Y" x7 W  l
  24. 5 t& E4 `$ M. @: ^6 n* `7 T5 z! f
  25. #define scl_high()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);& |+ |7 M- U% M
  26. #define scl_low()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);
    / x2 {/ P& T/ I5 q0 q) a
  27.                         
    5 F/ h' y0 Z# X" K
  28.                         
    ; i# W+ t- t+ i
  29. // ------------------------
    9 o7 f: ^, B, X# o: S* C( D
  30. #define DONOTHING()          {;}
    ' m0 `" c6 z  ~

  31. * n. z, j9 F# m4 G" z0 k7 y% U
  32. // ------------------------
    4 F; b& Z5 C: I
  33. // command's  S' S9 \% R+ e
  34. #define I2C_WRITE             0
    6 x2 T; J+ R2 a9 }# C" F  f$ L/ s
  35. #define I2C_READ              1+ [  H' \+ v7 u. \: Q8 S- N" v* q
  36. #define I2C_ACK               0
    4 u" p4 j& q  T' p
  37. #define I2C_NACK              16 F7 W! ?) @' j3 d+ ^

  38. ' N' d/ {0 e6 u! C
  39. void i2c_init(void);* L! ?( W" |8 q) \
  40. void i2c_start(void);1 u& m2 K) l5 E2 V4 J& |
  41. void i2c_stop(void);1 T% N) I/ T3 y  H* z
  42. uint8 i2c_write(uint8 u8Data);
    ; w& t: O6 W2 j: d) P" w0 n
  43. uint8 i2c_read(uint8 u8Ack);" K/ y8 C6 J. \* x$ ^+ f* ^$ C
  44. # E* t# J' z; l& H& b' B6 B5 a
  45. #endif
复制代码
; q/ q4 v, F5 |( W, V8 j

SHT21部分的驱动就不用怎么修改了,基本上直接拿过来,把ms延时函数替换一下,就直接用,这里就不贴出来

测试结果:


' F( e' A( w) Q$ B, G) R- L+ p1 }

微信图片_20230612191105.png


6 i& ?6 G7 b  \& S

板载的HTU21D,实际测试下来,一直会比空气问题高一点,这个问题,我倒是有点头疼,虽然做过分割,不铺铜等一些处理,还是不尽如人意。


9 o6 Q5 F7 b; l

转载自:矜辰所致

如有侵权请联系删除
9 l3 J3 S' e0 W# }: U; Q


, S* a: @2 |3 B* x& t: G: j- y- V6 D# u) P
赞 收藏 评论0 发布时间:2023-6-12 19:11

举报

0个回答

所属标签

相似技术帖

官网相关资源

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