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

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

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

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

. z) t- Y7 Y# S

+ O- f, A2 V! s( n- P0 r 微信图片_20230612191118.png
4 f$ M& s% A; [6 h- r8 Z8 |' |, ^7 h) ?0 o1 z1 A9 ]2 P
' Q: B" t3 A1 Z9 [
2、HAL库中的us延时函数
# P" }8 `+ W* B: V8 [1 U

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

  1. /* USER CODE BEGIN 4 */# k% P0 U+ r  h' U: Y% ]' P
  2. void delay_us(uint32_t Delay)6 }' L  H- H' j& f( x
  3. {3 o; W' F5 R1 x) N6 P$ C0 A
  4.   uint32_t cnt = Delay * 8;  
    ! J! ]$ J$ ]2 }& N/ k5 Q
  5.   uint32_t i = 0;
    ; A% w) m" g# _' b( y7 n# S
  6.   for(i = 0; i < cnt; i++)__NOP();
    " U8 Z! G: S6 f" J
  7. }
    # Z4 C% B( {2 W" B0 f" s# @
  8. /* USER CODE END 4 */
复制代码
7 Q% D" Z0 |: o
3、移植I2C代码3.1  SHT21温湿度传感器

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

  1. #include "i2c.h"% z. B* r9 w3 [9 \. L

  2. 5 ^1 i" b! w1 t6 u9 Y5 J
  3. // ------------------------------------------------------------------$ a5 B9 ]- x) M
  4. void i2c_init(void)  {8 ?* c9 y; u  j* e* _% l2 B
  5.   
    & T$ a, ~& x- m% {
  6. // the SDA and SCL pins are defined as input with pull up enabled
    5 ~9 b1 R: w* G- q) {
  7.   // pins are initialized as inputs, ext. pull => SDA and SCL = high
    ; T  K( ]3 K& p1 ?& C8 J9 c
  8. 5 X) |% T7 k0 A, |
  9. }
    1 i+ ]* c" [1 B7 G
  10. // ------------------------------------------------------------------" h) h* _5 o) ]6 O
  11. // send start sequence (S)
    4 S2 m. j" ~) V1 z
  12. / W1 U6 y0 A7 A# q% }# T6 X  Y
  13. void i2c_start(void)  {                                    
    5 f; D7 q" w- b- |- U2 H
  14.    sda_high();
    * J- Q3 \4 G4 W5 g; c+ j& z. O
  15.   delay_us(10);
    , n4 b' ?9 B1 G5 h# Y8 e( {* t$ ^" H
  16.    scl_high();  
    - y3 W2 W5 J9 e0 W) j$ N' a
  17.   delay_us(10);- r( R) J9 C1 i0 W
  18.    sda_low();
    8 ~# g. C$ Q6 c8 f- b! Z0 V* F
  19.   delay_us(10);# D4 M6 {; \$ p: P! q
  20. scl_low();                                                   
    " `  p  c4 j/ g6 @
  21.   delay_us(10);7 j) R+ g" [; H, \& X/ P% T% L
  22. }
    , ~+ X0 N& O3 ^/ a2 P* c/ x
  23. // ------------------------------------------------------------------/ D8 D: C% G& r
  24. // send stop sequence (P)
    - H8 E9 S0 r# u$ x% I
  25. void i2c_stop(void)  {                             
    / O9 s. f1 B4 L1 C( i, j  h$ B: n5 E
  26.    sda_low();                                                                          3 j  @; R6 t& c: T9 \) J
  27.   delay_us(10);- ]+ a: s; A/ J% U5 d4 c; S3 o
  28.    scl_low();                                       
    9 e5 E. j  X3 g
  29.   delay_us(10);                                 
    2 j9 b) o. ~) W) v* b
  30.    scl_high();                                         
    % v# ?; |3 I* K& |6 _7 ]5 T
  31.   delay_us(10);                                       
    " ?, Z- F1 v  p$ r
  32.    sda_high();1 H; I# ?' ?" k" r: q
  33.   delay_us(10);9 b3 t$ |* |8 ~, P. W6 ]" P+ D
  34. }
      v' C0 S, {5 u' Q3 ]: a8 |
  35. // ------------------------------------------------------------------, S8 ~" X- I# T& I+ K' R3 z( T
  36. // returns the ACK or NACK
    $ P2 }5 I7 g: s* V7 D, K/ O
  37. uint8 i2c_write(uint8 u8Data)
    ( [% s) t, U% H. q9 @- L
  38. {
    9 B7 H1 N3 z7 w
  39. uint8 u8Bit;
    ! V+ Q8 C) N! O0 E" W. X2 @
  40. uint8 u8AckBit;0 w% E5 t. j, ^( ^& D6 e5 D
  41. // write 8 data bits# `( V$ V) H; ]; J7 ~$ B
  42. u8Bit = 0x80;  //msb first  
    ' f: l& R+ W2 {4 i
  43. while(u8Bit) {
    5 w4 j, b& N$ x: I1 G  b% o4 K
  44.   if(u8Data&u8Bit) { % }' n+ _7 p5 ]1 Q
  45.    sda_high();6 n( r4 m& }! u! Y( w* ^6 [
  46.    delay_us(20);
    " a* ?% u. ~7 t# Q) E
  47.   } 9 t/ B" _6 B' E/ ^& |% j9 J
  48.   //& compare every bit
    0 \0 P# h; K) T5 _! J; q
  49.   else{ 3 U- i% w1 r  y2 N
  50.    sda_low();
    8 o4 A$ e$ N3 X0 [- S6 R; g
  51.    delay_us(20);
    0 B4 Q1 T  R/ c2 ^! j
  52.   }   
    $ |- ?* W# g( d9 x8 p- }
  53.   scl_high();
    ' [" n1 v0 x! y; h- \/ J, @+ W
  54.   delay_us(30);
    + h; I  W2 F2 ^" e. }% U1 K/ l+ e
  55.   u8Bit >>= 1;
    $ t6 [; P' |. `) b8 O% t
  56.   //next bit
    $ S. e8 R) Q) n8 h& G2 I
  57.   scl_low();3 f- K% ^+ i) D; C( u2 h+ X
  58.   delay_us(30);
    ( n( W) Q6 G" U6 s
  59. }( d* g8 r( }( j8 {/ L4 m6 v+ h
  60. // read acknowledge (9th bit)
    ! r0 d- B2 V: r5 Q- Q4 G# G
  61. sda_high();                                               $ v6 r0 U% e, z  ~' H' Q9 R
  62. delay_us(10);  $ w) \) U6 E9 K2 C' S! c0 l/ v
  63. scl_high();' G0 U3 G0 c. [1 o+ \# s% Z
  64. delay_us(10);
    7 T$ i( h: R- v
  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' D4 S7 {5 p1 Y; r
  66. delay_us(10);
    3 Q; T. v5 C& X: X2 K
  67.     scl_low();                                              ( `4 C6 `6 c6 _! B
  68. delay_us(10);# N* q' Q: I; p, `: b. \: |* L
  69.     return u8AckBit;
      j! ?/ G" E: L, h) Y+ }! _: e4 H
  70. }
    " h3 f  {) A+ g* C% o! w' }* I
  71. // ------------------------------------------------------------------+ r2 b8 @  F( ^0 `% C$ u5 }7 L
  72. // pass the ack/nack + O5 v# i3 y+ F2 @7 Z
  73. // returns the read data 0 k. g% L! z/ J1 d+ h2 h+ j
  74. uint8 i2c_read(uint8 u8Ack)  
    * `, }% l6 o7 g0 i8 y& N
  75. {
    4 p6 g; S# k+ p
  76. uint8 u8Bit;
    % J: i0 p# P, }) m+ c& J1 A
  77. uint8 u8Data;8 X5 c+ V/ Q$ ?$ G8 t6 X
  78. u8Bit = 0x80;       // msb first
    ) Q" K. k0 G0 m9 B$ d  S
  79. u8Data = 0;
    / b! v5 d: k* n* ?0 @, L0 [1 ]3 Q
  80. while(u8Bit){+ O- d) F& x* X$ d$ d3 E2 I
  81.   scl_high();2 _  `/ I% P! n1 g) M
  82.   
    , Z6 W( R8 Y5 d' W2 D/ E' p
  83.   delay_us(20);
    6 U( o3 A, @$ b) E
  84. " z4 j2 W4 u0 h* R
  85.   u8Bit >>= 1;    //next bit% J0 \* }2 x3 s- Y, A4 `; _* s- i6 a
  86.   u8Data <<= 1;
    : B# I2 x  T; F! w

  87. # o* f. V4 b6 B6 t$ ^, F
  88.   u8Data |= sda_read();         //(sda_port & sda_pin)? 1 :0      sda_port gpio0   sda_pin SCSEDIO01 L$ A# n" K& F6 ~& e& D
  89.   delay_us(20);% C# j1 m8 t6 T/ W. w: y& Z

  90. ( ?% ]9 T2 z+ Y7 d/ {% A
  91.   scl_low();
    % r2 V/ K0 q, Z' _& @
  92.   delay_us(50);
    ! D# [8 c( l; l8 A' x( h& ~
  93.     }2 W' Z& E5 K& `$ R
  94. // 9th bit acknowledge
    6 Q! D+ e4 a8 b% l
  95. if(u8Ack==I2C_ACK) {! h+ G* B. S1 R2 |
  96.   sda_low();
    3 Y: V/ m; Y, N
  97.   delay_us(20);) b7 |7 W9 A0 R3 |) |; f
  98. }     8 ^" D" y2 m9 `9 G
  99. //I2C_ACK=0. b% E% g# R" \: u) u9 Z4 |- m% t) z
  100. else {* U7 R- Q- Y1 i- R) Z
  101.   sda_high();
    7 \% y' E! e" t1 x
  102.   delay_us(20);
    4 E! p/ g9 s! |- \* L/ U0 x- u0 y) o
  103. }, a# ], p3 m) z' w  {( b
  104.    scl_high();
    % R5 d* n$ Q9 h7 i
  105. delay_us(20);
    2 L) N% F# l+ q: y5 H6 M1 V
  106. scl_low();4 b$ q! T$ p5 d2 W) s! _
  107. delay_us(20);' X4 x3 D7 x/ _; X- }. \* U  T5 y
  108. sda_high();$ _9 r5 Y* D( \7 l0 L
  109. delay_us(20);         0 ^+ S2 h8 F- i" `
  110.     return u8Data;
    , U( B7 [6 X1 a
  111. }
复制代码

7 ^6 ]7 P- |1 R! l" v

i2c.h:

  1. #ifndef _I2C_H_INCLUDED1 U& o8 [+ h: G0 M
  2. #define _I2C_H_INCLUDED& Q  {7 O2 q/ |) q# h2 s3 c( ^

  3. 4 ^$ G* B' D$ z  a
  4. #include "main.h"7 b4 w0 C4 w+ b
  5. #include "Datadef.h"
    ! M6 R9 ^, V- F$ ~  }+ R: L
  6.         
    2 q: Q& s; D& j5 G4 ^2 R
  7. // #define I2C_CLK_HIGH()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);8 |: j& I" }+ T0 N5 A
  8. // #define I2C_CLK_LOW()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);
    5 @+ F- l2 R! O* a

  9. 6 l6 @; C& V0 y
  10. // #define I2C_DATA_HIGH()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET); # K& Y' p8 ~! y4 u: D  Z% z( x
  11. // #define I2C_DATA_LOW()    HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);  
    , F; P2 }4 v) d4 k, @
  12. // #define I2C_DATA_STATE()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);
      K5 a' ?- m2 U; j  ?. n. m0 F
  13. 4 D1 J. p" r6 f8 v
  14. // #define sda_high()  I2C_DATA_HIGH()     // set signals to HIGH first before selecting IN -> slew rates
    3 H2 c6 K# Y$ M& ^8 ~2 T
  15. // #define sda_low()   I2C_DATA_LOW() - d: ^' j* @* y; K6 Q1 n) i
  16. // #define sda_read()  I2C_DATA_STATE()    //ack on bus is low -> u8AckBit = 1* P" o2 P# a% T+ M
  17. " J( \% h! q, y: q/ H( [
  18. // #define scl_high()  I2C_CLK_HIGH()     // set signals to HIGH first before selecting IN -> slew rates& a7 v/ x( ]5 O6 g/ B. J. r
  19. // #define scl_low()   I2C_CLK_LOW() % @# X& h' m& R% W" p

  20. ' q3 z! M9 ~4 f# t* S
  21. #define sda_high()  HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET);
    : y; D7 a. U0 }+ E: E5 O3 s
  22. #define sda_low()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);
    3 K- L3 f. M2 `5 f
  23. #define sda_read()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);
    6 ~: N5 \7 E0 ^# I. K1 K5 [
  24. ; v( \+ Q# [9 Q1 U" ^7 _1 Y
  25. #define scl_high()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);
    3 g/ U6 p: L6 {' ^/ B
  26. #define scl_low()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);1 c( p0 i! ~6 r' W
  27.                         
    $ L7 k3 ]3 X# l; _, D( G
  28.                          8 J1 ^: a+ T/ ]' ^" B  G- M7 T, [
  29. // ------------------------
    0 o+ X! u7 O3 q) a
  30. #define DONOTHING()          {;}- H- s* d0 p! p# y4 _1 Y

  31. ! ^3 }, n7 f4 I& l6 ]
  32. // ------------------------3 {) H% i! m$ X1 B/ S( w% Q# s, C0 ]
  33. // command's
    " a0 k: o3 t1 h4 l
  34. #define I2C_WRITE             0 2 l& A7 p7 a- ]1 H* `! |: `9 D! H
  35. #define I2C_READ              14 Y, ^8 O; Q: v6 d# g! c) u
  36. #define I2C_ACK               05 d0 c" j  m9 T# Z) X0 l
  37. #define I2C_NACK              1. X- S* A1 B; [
  38. 4 B& r& ]- ^& s4 y: N9 \4 b  \; \4 L
  39. void i2c_init(void);
    + L$ o0 y/ s4 U1 ^
  40. void i2c_start(void);
    , _0 D7 P  T; x' u
  41. void i2c_stop(void);! V/ W7 H, p& f3 d1 m6 ]
  42. uint8 i2c_write(uint8 u8Data);( A2 q1 \1 ^* Q; N, J
  43. uint8 i2c_read(uint8 u8Ack);
    7 v3 X4 C& N/ i+ [$ h/ X
  44.   R" B7 X0 f) g: F2 U1 \
  45. #endif
复制代码
" n  k5 w# j1 E, I; Q9 `

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

测试结果:


- c+ {5 J# v! e# ?( i7 X

微信图片_20230612191105.png


: Q3 x/ O* i* c

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

3 C  I6 x. D% v. z* H" A

转载自:矜辰所致

如有侵权请联系删除5 Y! Q( k. L) R, n1 h


4 c7 K5 G' S4 f9 ^
. p9 t, E5 }1 r, h! Z) j) ~) A* _
收藏 评论0 发布时间:2023-6-12 19:11

举报

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