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

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

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

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

6 b9 D2 {7 j, [9 K# k/ v

/ Q( {3 e( `& T 微信图片_20230612191118.png
) |$ g7 j* a+ g3 ]  [8 v  p, m- r, s* e( G/ e% r

0 t! c' }' u9 x# o& M0 T) q6 n1 x. {2、HAL库中的us延时函数3 c$ F) r: J& a6 k

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

  1. /* USER CODE BEGIN 4 */4 Q5 h' p6 ^, d/ \, y5 c, u9 c- {" C( f. u
  2. void delay_us(uint32_t Delay)( ^  ^6 J: m, P$ K4 }/ L- r
  3. {0 O  \/ i! Z. W& l/ D$ q3 W- D. m
  4.   uint32_t cnt = Delay * 8;  
    $ M# L2 w- S8 |2 [0 |  i1 u
  5.   uint32_t i = 0;7 m8 x5 m8 ^4 d% _
  6.   for(i = 0; i < cnt; i++)__NOP();; c* W, H8 q; r3 ^9 q
  7. }6 s. a- d/ Y1 l( X7 [
  8. /* USER CODE END 4 */
复制代码

/ @1 }1 I0 B; I3、移植I2C代码3.1  SHT21温湿度传感器

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

  1. #include "i2c.h"/ B& Q9 e5 ?( ?) t

  2. + N  c+ M/ A7 l5 P
  3. // ------------------------------------------------------------------
    7 z1 \% T$ ~$ i. E: B- s, C
  4. void i2c_init(void)  {
    8 J, }3 ]0 r) r4 d& J1 i7 x  S7 [
  5.   
    3 i3 A, h; ~  |* h& _9 u) Z
  6. // the SDA and SCL pins are defined as input with pull up enabled
    & m  L! K2 _' f+ z- W
  7.   // pins are initialized as inputs, ext. pull => SDA and SCL = high
    * t# e- Z9 K4 b8 O4 k  h
  8. 2 U% z' Y/ Z; @8 r3 V% C  R( @1 G
  9. }. M+ h5 O1 I( R' T' `* k$ n2 x
  10. // ------------------------------------------------------------------) M4 |" Y+ J8 _. a3 v+ q* _
  11. // send start sequence (S)* {2 j" a2 ?+ L8 }5 u1 T! i9 t

  12. 5 ]. ^4 G: ]3 O; Z* h: x" z6 s3 |
  13. void i2c_start(void)  {                                    
    * X" }" @% a7 _4 ^
  14.    sda_high(); 2 F: G% a0 }* ~1 o# Y, j+ C4 ?0 C1 |
  15.   delay_us(10);
    " C% T  _# X. N0 O" [8 W
  16.    scl_high();  
    ( ?/ A% h1 g; {4 P. R/ a- p$ b
  17.   delay_us(10);  F7 I8 f9 q4 R! G! N  ~( W6 f
  18.    sda_low(); # Q0 e: X4 r& l3 Y! z" q8 f' A
  19.   delay_us(10);; e2 r+ r+ L! w, F( n; k& H. [6 R! O
  20. scl_low();                                                   " U9 x* s3 V3 S4 I" s4 T
  21.   delay_us(10);
    4 P0 c0 A2 o, M; r
  22. }
    * T% z  B8 r+ l3 x9 Q
  23. // ------------------------------------------------------------------8 w/ z' \/ L% f3 j9 n
  24. // send stop sequence (P)0 y: W4 i; r* _# L) ?% Z$ Q+ p
  25. void i2c_stop(void)  {                             
    2 z" D/ x2 x2 K' K" z# Q
  26.    sda_low();                                                                          ! T5 w7 e  ~& A: v8 q8 R: ]
  27.   delay_us(10);2 V- y, g! G" V& I( K( k0 x
  28.    scl_low();                                       
    , e2 \% C9 g, k  h9 x
  29.   delay_us(10);                                 6 }' _5 b6 Y8 V, _* T
  30.    scl_high();                                         . k( E* G" L' U5 A% ~
  31.   delay_us(10);                                       
    $ w- h" o7 _9 _# c
  32.    sda_high();
    6 t! R, f; K0 e) M
  33.   delay_us(10);1 ]8 W* V6 I% ~/ r/ x" b
  34. }
    , p; @5 W. @, K
  35. // ------------------------------------------------------------------. {. C. G* C7 A7 O
  36. // returns the ACK or NACK/ T% e7 P9 Q; X% p5 j4 w' Y( t
  37. uint8 i2c_write(uint8 u8Data) 0 V7 _+ z# \  A  b+ a- d
  38. {
    5 ~7 y. d9 }& R6 g' v% w! ~$ K& v
  39. uint8 u8Bit;( C' C- W2 q9 V/ t9 o
  40. uint8 u8AckBit;+ J/ x- C/ {2 r3 N
  41. // write 8 data bits; v, L0 ^  w4 L
  42. u8Bit = 0x80;  //msb first  
    * n2 |! r( @: }8 i1 n( Z! n( M
  43. while(u8Bit) {
    - E$ W# M# v; h  K( b2 B  j; t
  44.   if(u8Data&u8Bit) {
    $ E# w  a& U7 U; B: I( L- q# j
  45.    sda_high();
    6 ~1 G0 Q+ [& g- k+ {
  46.    delay_us(20);" t$ |8 V7 K; U
  47.   } 9 t- O2 M$ H/ ^7 ^
  48.   //& compare every bit
    . P1 c3 r+ j+ i) x# B5 a" c
  49.   else{ 4 F# D  d; Q: u( ~& ^+ W
  50.    sda_low();
    ! i+ ~/ U7 I# x8 W, {. _
  51.    delay_us(20);' @$ O8 u" n5 K9 [3 i
  52.   }   
    . E3 I2 o; P! V5 m; t0 C
  53.   scl_high();
    2 F$ g. z( l, w& y4 |/ U
  54.   delay_us(30);) C9 |+ ~9 l3 Q/ S$ e
  55.   u8Bit >>= 1;
    # ^/ V" O- N9 i" {5 y3 {( A
  56.   //next bit: [) ~, C3 R: h
  57.   scl_low();
    ' G  e: W4 P( r( [* W; T
  58.   delay_us(30);
    6 [; P+ H8 C: S4 }) N0 K+ D5 n) h
  59. }3 N" Z5 U/ G: j9 a3 r) V
  60. // read acknowledge (9th bit) * _0 B0 X+ Y7 O4 F! u! w
  61. sda_high();                                               
    ' j1 m9 Y0 e3 u" q2 @# \8 j3 \8 _
  62. delay_us(10);  4 U$ o8 n& x7 B2 i5 K
  63. scl_high();* R: k5 G7 D% o$ k
  64. delay_us(10);) @( H2 T- U$ X9 N  h" R
  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
    0 M* G% e6 g' S2 V" V4 [
  66. delay_us(10);
    % e3 A& [8 m& k/ e
  67.     scl_low();                                             
      m3 e! y3 T; J& D
  68. delay_us(10);
    5 @8 L: S; x& p4 N5 Q- E- t1 ?
  69.     return u8AckBit;. ^5 {3 }7 j+ _% b4 j( F8 R1 ?
  70. }
    & U" o: h1 _$ \* t' F' n! }2 W
  71. // ------------------------------------------------------------------6 U" f9 H8 Q' W7 b
  72. // pass the ack/nack
    . q; x& T% N$ L! x# D
  73. // returns the read data - _6 I7 R* J) p4 A# w& r( T
  74. uint8 i2c_read(uint8 u8Ack)  
    $ Q2 V/ n+ P+ g2 c  q
  75. {
    2 Z2 l- a7 @6 u: r9 c- Z
  76. uint8 u8Bit;% D7 Q  V: g% d1 v% j
  77. uint8 u8Data;5 u, Q+ J7 s7 R* F% y
  78. u8Bit = 0x80;       // msb first
    8 n5 _8 q/ f3 v6 z/ T, D$ ^+ l% b
  79. u8Data = 0;
    + k/ f8 ?' d; D. M3 H
  80. while(u8Bit){
    ' m; r. f6 Q' S6 j4 F$ ]' C
  81.   scl_high();
    # L5 @: _/ N+ |7 B( O2 F
  82.   5 S* {, P7 ^' k) L  @* L1 e3 z
  83.   delay_us(20);, z4 p1 Q) ]5 a7 F$ S  E3 X' u

  84. 6 k+ n+ o" N8 s! U( P
  85.   u8Bit >>= 1;    //next bit
    3 ~6 y! L5 F8 W. ^& o( g+ |1 g4 A' U# O
  86.   u8Data <<= 1;' X8 n2 Q2 P1 M

  87. 4 o0 ~) Q/ |' x8 z
  88.   u8Data |= sda_read();         //(sda_port & sda_pin)? 1 :0      sda_port gpio0   sda_pin SCSEDIO0* h  d: A( U% `; r
  89.   delay_us(20);
    / ^2 N# s. _3 u$ b! r

  90. $ r" Y: i! C1 {+ k: r% j; q5 M7 X6 K) y- K
  91.   scl_low();
    ( u& J5 q# P. x. Q* @4 i& E+ m* k
  92.   delay_us(50);
    , m5 x2 n( O2 s- o% @
  93.     }
      Z/ D* v9 y: ]; z: I7 c
  94. // 9th bit acknowledge
    / L9 L* B$ g( C% G2 z* t" z  j
  95. if(u8Ack==I2C_ACK) {- @5 ?, W9 o! x# z7 y/ _
  96.   sda_low();& d" o5 S4 K# W/ l* O
  97.   delay_us(20);( q/ D3 c& M8 `4 w* O* P# s- Y7 x5 Q
  98. }     - E- ?$ X* O7 A, N2 X0 S
  99. //I2C_ACK=0
    9 i2 @: T; b, n* z- j1 Y+ b) G
  100. else {
    * d$ n) O8 r, N3 b5 U0 K" n
  101.   sda_high();
    - ]! f  a! f9 c6 @7 g  B5 f
  102.   delay_us(20);
    5 t/ K3 I# B: K
  103. }
    & `+ P* ]' k2 u& m
  104.    scl_high();
      v9 G$ C% d8 L% _: Q$ s: Y0 w
  105. delay_us(20);, ]# V- d$ J3 ?6 ^
  106. scl_low();) ?$ Y! N9 T. r8 B2 F
  107. delay_us(20);! [6 G- G: g, _- p5 ]0 c) n# J* o
  108. sda_high();
    9 ^& |% M3 H2 O, y3 }
  109. delay_us(20);         " J* A  ]5 T2 S' b1 c7 i
  110.     return u8Data;) b6 U) m# i* \
  111. }
复制代码

- Q  m) }2 `6 v+ y  B

i2c.h:

  1. #ifndef _I2C_H_INCLUDED
    6 E5 k( I# M7 t- p
  2. #define _I2C_H_INCLUDED
    . u: `, |  R- A* t7 {) m
  3. 3 d/ h1 J6 A4 q& p+ p3 U
  4. #include "main.h"
    * {( [  n8 ?( w
  5. #include "Datadef.h"4 M4 y4 W. U" o+ `: P
  6.         9 M  [6 C! q0 M. u+ f
  7. // #define I2C_CLK_HIGH()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);* A" r5 A+ a* i$ T
  8. // #define I2C_CLK_LOW()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);- L+ @) N# k5 j" q9 ?2 b/ @

  9. # v4 f, u6 n) X' x
  10. // #define I2C_DATA_HIGH()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET);
    - ^6 U  M4 @$ G& w4 V. D. r
  11. // #define I2C_DATA_LOW()    HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);  2 r& h. D: E9 t/ N
  12. // #define I2C_DATA_STATE()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);
    ; L8 e3 j& ~* ]

  13. : ~0 T+ N/ E" m( j/ }6 f* G# N: _; ?, \
  14. // #define sda_high()  I2C_DATA_HIGH()     // set signals to HIGH first before selecting IN -> slew rates4 p% i1 a' z# E, x# U0 N  l. t
  15. // #define sda_low()   I2C_DATA_LOW() 5 ]) o. _2 O$ X8 ~0 e9 b2 ~0 r
  16. // #define sda_read()  I2C_DATA_STATE()    //ack on bus is low -> u8AckBit = 1
    6 L! M- l( e$ }  n2 W4 ?  K0 W

  17. 9 |. r+ S, p- V; |& q5 @
  18. // #define scl_high()  I2C_CLK_HIGH()     // set signals to HIGH first before selecting IN -> slew rates) D; U# L# l" R% G/ k
  19. // #define scl_low()   I2C_CLK_LOW() ; A1 x. `* j/ V3 T7 ?$ x) q" d

  20. / d3 o) ]6 d% `. c+ a! J
  21. #define sda_high()  HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET); 5 T$ [; H% X" q- b
  22. #define sda_low()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);
    ( N( I0 o) D2 k0 C/ ]: S# _
  23. #define sda_read()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);
    0 U9 j7 [) V; ~$ {' S

  24. - P" N0 X" m2 q
  25. #define scl_high()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);5 H3 `) r" v+ g
  26. #define scl_low()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);6 F7 `, W! g) w1 ^( }/ D  L
  27.                         
    8 v0 d2 h; x% v: B/ \! V
  28.                          : a8 |% B" D6 B( @
  29. // ------------------------
    ; ]( f5 U5 ~0 l2 q& e& A9 }4 x5 ]
  30. #define DONOTHING()          {;}- S0 H8 C( j: T( K, z, B. J# L

  31.   ?: `8 ~, ?# g
  32. // ------------------------
    $ Y) p/ ^1 ]$ n3 h, R
  33. // command's$ d! W4 W+ s# B- f* h2 M
  34. #define I2C_WRITE             0 ; o4 g& i8 `8 `" k
  35. #define I2C_READ              1/ Z4 {! a7 P4 b& W/ k
  36. #define I2C_ACK               0
    : O! r% c! Y4 i4 ]$ U% U
  37. #define I2C_NACK              16 \/ f7 t- {* n

  38. ) h. g; ]! P# A- R
  39. void i2c_init(void);
    , n9 S& o4 v% j* n( m8 J) y- C1 U
  40. void i2c_start(void);
    , n& L6 b9 G, \3 T. |: {
  41. void i2c_stop(void);
    + R  x8 `# {9 r- H2 B/ \
  42. uint8 i2c_write(uint8 u8Data);" o7 f. z" Q1 t: {1 y0 D/ S
  43. uint8 i2c_read(uint8 u8Ack);
    0 ?* e; h: Q0 C* D5 I% B
  44. 5 w: I- n; B) r* `8 }) {0 V+ G
  45. #endif
复制代码

/ D( G; |% G9 N% t

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

测试结果:

6 k1 Y7 |& p; {$ T; |; }

微信图片_20230612191105.png


  G  z8 ~3 y! B  ?

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

0 \) l3 Q1 M- L2 X3 f  _# Y( H

转载自:矜辰所致

如有侵权请联系删除2 `* B; U. Z0 h; ^4 J6 v. L

. D5 m! Q. E( F8 w9 |4 h

) C4 c! J- Q; D- O8 C+ G
收藏 评论0 发布时间:2023-6-12 19:11

举报

0个回答

所属标签

相似技术帖

官网相关资源

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