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

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

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

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


- O% t8 X/ a  y
8 J) I3 r6 }1 b$ |
微信图片_20230612191118.png
9 Z9 l( ]5 `  G% p0 A/ Z
! m3 z7 d2 }1 [  Y8 ^# w: ]  q

+ \7 H6 n; t$ O) {2 G( x" v3 @* p2、HAL库中的us延时函数1 t, V" d, ~3 d# k1 ^# b

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

  1. /* USER CODE BEGIN 4 */
    2 f. Y' A8 }* r
  2. void delay_us(uint32_t Delay)
    & }/ Y1 g6 v2 K  e/ ~/ J) Q7 H, X
  3. {* D! W5 v6 y+ ]3 x
  4.   uint32_t cnt = Delay * 8;  4 _9 L2 ]% R# S! W8 Y
  5.   uint32_t i = 0;
    9 N) \( d+ Y' z1 ?
  6.   for(i = 0; i < cnt; i++)__NOP();* |6 p  C- L6 D1 w$ F) T$ w
  7. }
    5 x& [8 x) q! p" h0 F' a
  8. /* USER CODE END 4 */
复制代码

/ B9 T, U$ Z, H: S1 _% z4 K/ D3、移植I2C代码3.1  SHT21温湿度传感器

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

  1. #include "i2c.h"% z7 P6 A6 c; E4 P
  2. 6 g: h7 l! s, B
  3. // ------------------------------------------------------------------
    ) L/ Y8 B* K: U# I
  4. void i2c_init(void)  {
    # u* t3 d5 R( E& [- T
  5.   
    , ]! B* B8 x* B1 j. P
  6. // the SDA and SCL pins are defined as input with pull up enabled) F1 W/ X5 j% V1 l. {4 R
  7.   // pins are initialized as inputs, ext. pull => SDA and SCL = high
    , m" e  y: t8 Y+ k

  8. & n5 ]) T/ U  A6 {
  9. }
    % s. q4 E# F! j
  10. // ------------------------------------------------------------------
    + p# H: U) ?: T8 t  b" @
  11. // send start sequence (S)
    8 _. e6 z1 {4 W7 ~% s/ @* _
  12. - C+ e0 D3 x. a+ j, R
  13. void i2c_start(void)  {                                    
    $ u2 c0 v$ U8 e' l
  14.    sda_high(); + y% i  d( S& g7 x/ \
  15.   delay_us(10);
    ' b; y$ z8 {! d( W, G/ |# Q# z
  16.    scl_high();  
    7 @6 \, m, \" w5 c$ o/ f! w( ~! D
  17.   delay_us(10);
    4 t: x- o4 g$ _' Z
  18.    sda_low();
    7 D8 H' i" d0 K5 R/ Z% v& e
  19.   delay_us(10);* s. P3 o2 v8 @8 N* r
  20. scl_low();                                                   & {/ T' \! ?% P$ t1 t
  21.   delay_us(10);$ d2 q: O' K! g* d: t& V
  22. }, J+ f5 s& F) H; ]. b+ Z$ p
  23. // ------------------------------------------------------------------
    7 E6 S) a8 H- h* ~+ b" {' G
  24. // send stop sequence (P)
      {( x$ _/ s' T3 w/ L7 K: n/ t- H
  25. void i2c_stop(void)  {                             9 t8 ~6 V" M- m  W/ k4 E* ^
  26.    sda_low();                                                                          
    3 f/ e) O; `$ m8 m* t4 g
  27.   delay_us(10);0 n5 x5 @: |3 k5 _/ i  n9 e8 f
  28.    scl_low();                                       
    # i8 R$ x- |6 ]1 p) y0 i
  29.   delay_us(10);                                 
    3 s8 q8 Z. c% l# }" g- a
  30.    scl_high();                                         : R. R0 d( ?4 M3 B0 i. c
  31.   delay_us(10);                                       6 ~0 o% r, X. G5 a- K' {
  32.    sda_high();0 {- y0 O7 _  U
  33.   delay_us(10);2 T" N% j. a1 H6 f2 ~# P7 {; w
  34. }
    4 T5 M+ [. p, `' d6 A  e" `
  35. // ------------------------------------------------------------------
    & I9 O' Q) I$ h1 X  M) ^
  36. // returns the ACK or NACK: ?* n9 M2 e9 r4 @: ~* q
  37. uint8 i2c_write(uint8 u8Data)
    2 r% C+ z; S, n  ?3 a. ?
  38. {
    $ y6 m& |$ n- E! |- G/ s
  39. uint8 u8Bit;- q7 o5 E) X* f( Y& }4 P& d
  40. uint8 u8AckBit;2 `/ p4 W5 u4 U; g% w* L6 v
  41. // write 8 data bits* q+ Q! }+ C8 \. ~% |6 u( P
  42. u8Bit = 0x80;  //msb first  
    / n' `7 _3 x2 O) |) P, C6 s# U8 b" j6 O
  43. while(u8Bit) {
    : v) w0 \( l: C" `
  44.   if(u8Data&u8Bit) {
    - ?; Q( T: N! k( e# m( X1 `9 e' m
  45.    sda_high();
    ! q" n" K3 a& ^
  46.    delay_us(20);
    , e8 \4 }- S/ l4 w5 }8 d2 @4 K: j
  47.   } + f7 ~' e2 A; p6 x8 u- {) }
  48.   //& compare every bit
    . H+ M* @# \, n8 Q
  49.   else{ ; Q+ o* T  A+ |/ K& }6 Q1 z
  50.    sda_low();  l! [' r9 n9 @  s' |* Z
  51.    delay_us(20);5 x4 b9 W3 |& v
  52.   }   
    4 u( |) F0 L5 M4 s5 ~) t( ?9 w' R1 N
  53.   scl_high();
    . N4 z# V2 I8 R$ [
  54.   delay_us(30);
    $ j# C! b+ A3 `/ O/ B. h$ B* c
  55.   u8Bit >>= 1; ( f+ ~8 \' w3 B; R  b9 J2 u
  56.   //next bit
    $ n1 e2 B5 l  }' M& X
  57.   scl_low();
    5 M  d8 x7 a* Y8 L3 L( @
  58.   delay_us(30);
    6 R) i# ~3 B$ Q5 s/ r
  59. }
    . B- C3 Y+ B' l
  60. // read acknowledge (9th bit) 9 ]% |# c0 u4 r7 E" q4 n
  61. sda_high();                                               
    ' ?$ R5 @# G0 ?2 b, ~
  62. delay_us(10);  
    & k5 L" M* l% F1 M1 w% e, R5 a
  63. scl_high();
    - _" d1 [8 C5 s' u! M  S
  64. delay_us(10);7 K6 P% h$ l* J1 E: z2 V* K* ?8 i
  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
    8 z8 Q* g/ m1 v  T9 f7 ~" q
  66. delay_us(10);
    ; f4 @. u  j. `7 |. ~  o/ S
  67.     scl_low();                                              % V, H" ~% N8 f4 m, ^
  68. delay_us(10);
    9 Q9 [* u* |. A% J
  69.     return u8AckBit;# ]) _& Q$ H1 `+ }9 \
  70. }
    4 ^! g, D' o- s3 w
  71. // ------------------------------------------------------------------
    4 O/ s( h" L* X( h+ R9 m! S1 q6 _
  72. // pass the ack/nack   @$ o% I/ d6 H- o# K! `" e
  73. // returns the read data
    5 D+ c: x' @' ^/ s5 k7 j2 {% ^* h+ K
  74. uint8 i2c_read(uint8 u8Ack)  
    7 `( S5 _3 M- z/ l1 `7 E5 B
  75. {* S7 f! `* ^) Q( `9 _- t$ \$ m/ z
  76. uint8 u8Bit;8 G7 Q9 o# S3 N  H0 F
  77. uint8 u8Data;6 c+ q+ _; Z3 x" ^; m7 g
  78. u8Bit = 0x80;       // msb first* d; g; H* Y* G3 D% x: [; o4 v
  79. u8Data = 0;
    6 r# S0 Z- G. l, ~& y  s
  80. while(u8Bit){7 `. M( v0 P" y! t- O
  81.   scl_high();$ w( Q; ?2 K: d4 E' n# R7 V2 ?
  82.   6 M+ u0 e* W, ]3 H5 `
  83.   delay_us(20);
    3 ~" J5 r2 x$ s, f
  84. 0 l- B: G: Q0 a
  85.   u8Bit >>= 1;    //next bit; p- S. E9 ^2 Q
  86.   u8Data <<= 1;
    ( R0 N  E5 ]* ?( y6 k% t

  87. - c. Y  Q: ]0 T" Y) f. a' M
  88.   u8Data |= sda_read();         //(sda_port & sda_pin)? 1 :0      sda_port gpio0   sda_pin SCSEDIO0
    $ S5 a) s; @2 b4 c! P
  89.   delay_us(20);
    . g: A6 y/ E# {) ?9 p
  90. ' U  a9 [( ]+ @. \
  91.   scl_low();4 C. b' K% b1 M: W; w" R: @4 L5 m
  92.   delay_us(50);/ v; b! l$ _! ^
  93.     }+ X* ?5 ]0 ?4 |( t3 q! g: S5 r% |
  94. // 9th bit acknowledge( x6 C* M) x! X) c5 o* p
  95. if(u8Ack==I2C_ACK) {
    ! ?) r! M$ V0 O0 }
  96.   sda_low();
      ]; S' b' W0 y7 Q7 g6 f1 D
  97.   delay_us(20);# ?% c9 U/ r' h5 j3 O
  98. }     
    / L; [8 y, ~8 C+ V8 ?% `* J% X/ ?! C& q
  99. //I2C_ACK=0
    & n% G% h3 X/ p
  100. else {
    / ?: S. b0 I8 F# X/ m
  101.   sda_high();
    ( m2 m, b6 y4 C: E) [6 k8 N. z" v
  102.   delay_us(20);
    0 @+ `, }# g2 f) c0 e
  103. }
    / a; {# ]) O3 ~
  104.    scl_high();
    ' z* m" d' A" l  w! M' V6 M
  105. delay_us(20);6 v+ b7 Q/ U; d
  106. scl_low();
    ' Q- h9 i" L3 y1 z( d/ L
  107. delay_us(20);/ h; _' M! \, }) ~
  108. sda_high();' H3 L- @: x$ ^! q1 [) w1 F# Y, |
  109. delay_us(20);         : I% J, R' n" x5 a) i3 [: E% I
  110.     return u8Data;3 G& K2 h8 J4 H) E. w. X- e
  111. }
复制代码

3 J- m( Z/ Z0 T0 G! O

i2c.h:

  1. #ifndef _I2C_H_INCLUDED& ^- {! C1 O' v0 J* G7 j1 g
  2. #define _I2C_H_INCLUDED
    # X4 ~  ]; U; y& P/ t/ V

  3. ) t7 b. N$ p+ k. T& F
  4. #include "main.h"4 V9 _7 g4 ~# |% b
  5. #include "Datadef.h"
    6 u4 t1 u1 e$ Y. p& B
  6.         & x6 e" O: N5 X7 A( }6 L
  7. // #define I2C_CLK_HIGH()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);
    - B' R6 j3 C- e* Q  a$ B/ @
  8. // #define I2C_CLK_LOW()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);, e. y. V& x. `0 H) ~: I1 ~4 @+ ~

  9. + R7 a& Q) X) K3 K  Y! c
  10. // #define I2C_DATA_HIGH()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET);
    7 g, j0 e. D% f$ o- q& D+ t
  11. // #define I2C_DATA_LOW()    HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);  / F! ]9 n* a# x4 N3 @8 r: b! s
  12. // #define I2C_DATA_STATE()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);
    * |* U, W' H- G# C3 \

  13. . Q2 A0 S& l. j! r
  14. // #define sda_high()  I2C_DATA_HIGH()     // set signals to HIGH first before selecting IN -> slew rates0 m# [. g- K  O0 W8 U8 F: z/ @
  15. // #define sda_low()   I2C_DATA_LOW()
    ; J- t6 i- c; ^0 b+ I" H: z
  16. // #define sda_read()  I2C_DATA_STATE()    //ack on bus is low -> u8AckBit = 1
    " Q7 u# ]( d! M; d, X* R& {3 d3 i

  17. 6 x0 Q' v4 x/ v: B
  18. // #define scl_high()  I2C_CLK_HIGH()     // set signals to HIGH first before selecting IN -> slew rates
    ) X0 V5 ^: H0 q1 d
  19. // #define scl_low()   I2C_CLK_LOW()
    + Z- H" F% l, R! [; m( ]9 _8 S
  20. 1 U, Y2 S! M0 b
  21. #define sda_high()  HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET);
    & E' R1 ~$ ?2 h9 `
  22. #define sda_low()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);
    9 Q0 @, Y2 [# F2 `
  23. #define sda_read()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);  n7 n1 P( j. Z

  24. 3 j& Z& e! {2 {9 J* d0 H! I8 {0 Z. \
  25. #define scl_high()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);7 |$ E. a8 _; V( M5 v/ p4 {' a: u
  26. #define scl_low()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);
    2 [% c# e2 J2 [! n; j
  27.                         
    ! O; f) m" z5 x
  28.                          ! y( b" \) p6 ]& S7 V
  29. // ------------------------
    + P/ P) B$ |+ o3 Z4 I
  30. #define DONOTHING()          {;}
    % a* [9 J" A/ S% K) S; J5 ?
  31. # k4 `8 m" V& U6 h: g
  32. // ------------------------
    ! q4 h. w" o2 q/ r1 {4 W
  33. // command's8 M. W0 }3 X4 r4 _
  34. #define I2C_WRITE             0
    , x/ C2 l, A! z5 K: R- s; J4 X
  35. #define I2C_READ              1
    , {6 C3 \4 i. \2 m
  36. #define I2C_ACK               07 S8 M6 a- C2 a3 |: n
  37. #define I2C_NACK              1
    . r" b! E( x3 s5 E7 Y) z% }
  38. / g9 V# X# h" R* [9 v" w
  39. void i2c_init(void);
    0 g. T' I! W8 T" }3 K1 v  @
  40. void i2c_start(void);; h2 z: U! E" U' t3 t9 }
  41. void i2c_stop(void);
    5 T" P/ t8 S+ v7 F
  42. uint8 i2c_write(uint8 u8Data);
    4 k( e: i6 n  `
  43. uint8 i2c_read(uint8 u8Ack);
    , N: n, o1 G  J. |

  44. ; ~' L. F  K; ]
  45. #endif
复制代码

3 k! Z' q) K( F7 |7 S! L4 l0 \2 z

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

测试结果:


, B( w+ u( h3 s' h0 A! c# O/ I9 _, f

微信图片_20230612191105.png

8 A: c4 p' Z* _/ Z% ]" `) O) U

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

3 Q  R9 ?) l7 R

转载自:矜辰所致

如有侵权请联系删除
, @& P9 x: z; V) X: M2 o4 j

" J8 {) O  w0 y- k" f5 d

3 \" Q8 K" }% H0 U
收藏 评论0 发布时间:2023-6-12 19:11

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版