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

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

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

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

. a5 J9 [/ e0 d
: |, `6 N# c1 t9 P
微信图片_20230612191118.png
) s$ w: M5 b, i, D' q( Z, ^' w5 i
0 l2 N! d( E0 P+ n
2、HAL库中的us延时函数" u0 a3 E! |1 }& j

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

  1. /* USER CODE BEGIN 4 */7 D0 D# r# q! X1 V
  2. void delay_us(uint32_t Delay)
    , Y$ G9 y' }/ O9 X1 c7 j' v3 W' E
  3. {
    + K( X6 N- Z# ^6 S/ r
  4.   uint32_t cnt = Delay * 8;  " H" U! g' s5 {' ~( S
  5.   uint32_t i = 0;- w8 |4 Q6 a4 D7 K
  6.   for(i = 0; i < cnt; i++)__NOP();
    / D* k$ J+ d* K! X  n8 P
  7. }
    4 }4 v! H( \5 g' I
  8. /* USER CODE END 4 */
复制代码

' h! l( W5 B6 {# p0 }1 E3、移植I2C代码3.1  SHT21温湿度传感器

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

  1. #include "i2c.h"9 x* v/ {4 h6 k$ j, B

  2. $ g. l7 `- U/ x% [1 m2 y
  3. // ------------------------------------------------------------------
    : x7 |: u' ~: F$ P& F+ @
  4. void i2c_init(void)  {, E% J) S* B$ \9 I
  5.   
    4 N1 X- e: k; ~7 A, p) L
  6. // the SDA and SCL pins are defined as input with pull up enabled
    ( r( s; a" o. w8 x: ]
  7.   // pins are initialized as inputs, ext. pull => SDA and SCL = high" y7 u/ s, w4 E9 w3 D& m/ `" K
  8. % y8 P" V; m7 C" {1 ?
  9. }1 ?8 U# D6 z$ ^- X, x: D6 \
  10. // ------------------------------------------------------------------
    ' z+ X  A9 r" f
  11. // send start sequence (S)
    ) t; e$ G% T. `3 N  Q

  12. 8 N" t; O8 r5 G; O$ _! [/ l
  13. void i2c_start(void)  {                                    
    % T$ f4 L8 X; X: N. H
  14.    sda_high();
    1 g7 R, @! X4 r7 p( E( d$ ]" N+ g
  15.   delay_us(10);3 Q* P+ E7 _9 i& d7 [/ K2 }% p
  16.    scl_high();  
    8 z7 n* e9 q) Z% z9 o4 ?
  17.   delay_us(10);* W1 e! I( H. K, W" J7 q6 \- u
  18.    sda_low();
    2 d, ~  M" {7 L* p
  19.   delay_us(10);
    ( R) i8 L# T9 S* ~
  20. scl_low();                                                   ) x# j) t* ^6 H# H5 B+ G, p
  21.   delay_us(10);
    % A0 w" R3 q+ h- D( p
  22. }! N0 v: @- U. o- W1 ^
  23. // ------------------------------------------------------------------
    6 C: [8 p$ J) y7 ~; R! E
  24. // send stop sequence (P)
    & l) l3 _; z7 L7 m2 J
  25. void i2c_stop(void)  {                             1 s& t4 d8 Q. q5 F
  26.    sda_low();                                                                          - N9 [/ ^/ j1 l
  27.   delay_us(10);! \2 a; H8 b* t4 A" w
  28.    scl_low();                                       - m+ g5 [/ {9 e, v' F, }" t) F
  29.   delay_us(10);                                 . L6 Y+ ?; b) q
  30.    scl_high();                                         
    6 L* Z; e! A, h" v- F
  31.   delay_us(10);                                       2 N, A* T/ }- \. I$ J7 m; b8 L
  32.    sda_high();, X" C, n8 F( n% T) B4 I# q
  33.   delay_us(10);
    ( i8 {; r: ^4 l4 o! g
  34. }
    ) H- i1 L6 P6 ^  F0 Y
  35. // ------------------------------------------------------------------% G  f# ?- w9 D! j4 {5 }$ S# h2 |
  36. // returns the ACK or NACK. G/ k2 X) X$ @4 Y3 R, s7 T/ n
  37. uint8 i2c_write(uint8 u8Data)
    2 N3 }4 q0 l% p0 v* [- B* `7 W
  38. {
    4 Q9 X* ]6 I; \' G. l; X0 w
  39. uint8 u8Bit;/ D  h0 {4 h" N1 Y
  40. uint8 u8AckBit;) `. x/ J( O' E2 ]/ U
  41. // write 8 data bits, @5 R1 e- v5 T& M& `7 ]
  42. u8Bit = 0x80;  //msb first  
    6 M6 }0 Y1 U" v* Z) a
  43. while(u8Bit) {
    , l$ [. f1 w* w+ U: m, L" X
  44.   if(u8Data&u8Bit) {
    8 Y4 A- ?3 [& d8 n
  45.    sda_high();
    6 \5 c4 n2 ~# g6 L: a5 u: e: `
  46.    delay_us(20);5 w. c9 C1 ~6 x3 G  m5 x+ R
  47.   } 2 h& g) W' f  ]: W
  48.   //& compare every bit" l: ]: [1 \' U
  49.   else{
    # N, f; Y/ a- c1 H, m! }# R
  50.    sda_low();
    & U! E* r- q, T5 r3 N8 x
  51.    delay_us(20);
    - H5 D* G0 z5 t/ n; i
  52.   }   
    % Z! K9 v+ X' i1 F
  53.   scl_high();
    , h# s9 a$ I& m/ T4 S7 _( `8 d: i" a1 {
  54.   delay_us(30);
    7 s7 o. Q5 ]$ p! M$ ?' J
  55.   u8Bit >>= 1; ; C5 P  U' D3 o* Y) [- k6 ]
  56.   //next bit
    + `2 A! P8 t% ]% t" Z2 t
  57.   scl_low();
    0 K1 H; a/ ^8 p# c: Y
  58.   delay_us(30);
    * f, ^8 {" A) Y5 T/ t% c
  59. }2 w7 a4 S8 \! x% K5 Q
  60. // read acknowledge (9th bit) - ]+ c- Y" `3 }( a+ d
  61. sda_high();                                               
    ; i; e% Q; |# P3 R7 Q) J* T
  62. delay_us(10);  $ W9 |& T% w+ L9 v
  63. scl_high();5 _# U+ j! X# q1 V6 ]
  64. delay_us(10);3 X: D% |! b7 I5 P* k7 v7 H
  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
    3 \  D! n) l" X0 n8 U
  66. delay_us(10);. n4 d' U. w4 U& Q0 X
  67.     scl_low();                                             
    . E0 c3 P* U9 x! s7 g; V
  68. delay_us(10);
    / ?% i4 ]- |1 Q; W& X4 M
  69.     return u8AckBit;! v  e) |' Q5 B3 ]7 @4 u
  70. }
    5 i( X6 r0 k" d, A
  71. // ------------------------------------------------------------------, V3 i4 P. r2 {- R- {
  72. // pass the ack/nack
    2 Y2 C! [% n, F, I2 u' n
  73. // returns the read data " A* }9 N, G6 E- X& p* z
  74. uint8 i2c_read(uint8 u8Ack)  ) n0 O  G) |) ^4 R" L; B
  75. {& u& x8 }3 v( ^
  76. uint8 u8Bit;  v+ i1 c. M" B& J  f
  77. uint8 u8Data;' z$ `, ]; Z  a& _  h5 M
  78. u8Bit = 0x80;       // msb first
    " r4 l3 E" y7 A4 |, ~+ i/ b* p
  79. u8Data = 0;" V. l; F7 T4 W( u( s
  80. while(u8Bit){
    + J9 E8 S& [+ [! I2 K" A0 w; w
  81.   scl_high();' \( Z+ y+ J0 A; D7 i7 ~
  82.   ( f8 z7 g& k9 o
  83.   delay_us(20);
    0 c: P( {3 x6 _/ ?
  84. % _  O% }; b( X2 n
  85.   u8Bit >>= 1;    //next bit
    / Q2 L% L  W7 r
  86.   u8Data <<= 1;) z# u' j5 F8 M/ t( O6 N

  87. 2 \' F7 w( {! l+ r7 e, [7 n
  88.   u8Data |= sda_read();         //(sda_port & sda_pin)? 1 :0      sda_port gpio0   sda_pin SCSEDIO0
    1 }, h3 X3 u- Y% G3 v- M3 B
  89.   delay_us(20);8 l* C0 d0 @: x. _5 J6 m$ [% n
  90. 0 p* ~3 j; e& N
  91.   scl_low();7 O$ _8 i' h  M) i
  92.   delay_us(50);& ], q6 b+ _& f( o1 e$ K
  93.     }. L5 w! C( R" r& I3 o
  94. // 9th bit acknowledge! j* ~- p" o1 R4 L5 e$ [# D" g
  95. if(u8Ack==I2C_ACK) {
    , ], G) r6 \+ ]2 T, Q& W, a
  96.   sda_low();
    ) z" B  R( n9 T
  97.   delay_us(20);, g* y0 G0 s9 J9 x* N/ F' D
  98. }     
    4 ?) ?2 ^0 E6 ^& a- c3 l; r
  99. //I2C_ACK=07 @" t, u: C: t4 T
  100. else {
    3 E# a; y2 m2 w+ h  f% d; s
  101.   sda_high();
    8 h4 v8 Y$ O: c2 Z
  102.   delay_us(20);' S2 `+ d' \# E# ~& e! y, Z7 i8 {
  103. }
    2 t2 L& m8 n% T- `( s. l
  104.    scl_high();
    / V1 l6 W) T: O2 e' _
  105. delay_us(20);( ^8 ^" ]: J! R. @" Q( i
  106. scl_low();! t; D& A3 W1 i* \( ^0 b% o  o
  107. delay_us(20);8 o9 z" g9 }& w4 f/ l4 l1 S
  108. sda_high();
    0 _% q" B9 R$ L# g+ _, C) y7 u
  109. delay_us(20);         # R; K! X4 W  U
  110.     return u8Data;  w$ j* M0 W* p* [; P) E, f
  111. }
复制代码

& D! ?1 `. X9 ~8 P' G/ r% ^

i2c.h:

  1. #ifndef _I2C_H_INCLUDED  t* A6 }+ [  x) A" {
  2. #define _I2C_H_INCLUDED2 `& N' ^. _3 D' q9 i$ M
  3. 2 k5 x  ]/ l/ [9 ], P3 z' m- N
  4. #include "main.h"
    8 R# ]* b( b; _' q8 J' V0 G2 t
  5. #include "Datadef.h"
    * u" G! \6 J  M: [7 K
  6.         3 E/ B& A) _- f, f% G7 h
  7. // #define I2C_CLK_HIGH()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);7 k+ V" }. l) m& |
  8. // #define I2C_CLK_LOW()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);- n: B& u: b5 f% n. ?& G) \' T* E/ X4 Z
  9. % s* x' Q1 n+ R" M0 a5 H; ]
  10. // #define I2C_DATA_HIGH()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET);
    " c; ^* Q: I: ]+ S% k
  11. // #define I2C_DATA_LOW()    HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);  ; E9 T( u9 k" ?( e! n! i. [& v; P
  12. // #define I2C_DATA_STATE()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET); 2 b' m4 c6 ^1 P0 R# s# n
  13. 2 u" Z7 V0 F. D$ G8 T% ~( V" V
  14. // #define sda_high()  I2C_DATA_HIGH()     // set signals to HIGH first before selecting IN -> slew rates& g, Q- e! b: L7 i9 ?) z/ d
  15. // #define sda_low()   I2C_DATA_LOW() * t. a, ~1 [3 q8 q/ K. n
  16. // #define sda_read()  I2C_DATA_STATE()    //ack on bus is low -> u8AckBit = 15 c! e) _9 k1 w- _
  17. & g+ v# z4 t, e9 m/ o8 {
  18. // #define scl_high()  I2C_CLK_HIGH()     // set signals to HIGH first before selecting IN -> slew rates4 W  t  J* |/ @% R3 K% S2 i- _5 U" h
  19. // #define scl_low()   I2C_CLK_LOW() 6 }5 F+ I2 Y4 O- {6 `; `6 z
  20. 1 }& O6 v" E! p" \/ T" z
  21. #define sda_high()  HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET); 4 ?# \4 ~! l/ Q7 D
  22. #define sda_low()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);
    2 {) u3 j' M" q  `; }
  23. #define sda_read()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);4 h. p+ u( V6 i) a( X* E+ r, B
  24. ) |9 O, |! Q7 G% r) j
  25. #define scl_high()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);
    2 i8 u1 P2 X2 m) v+ f, Z+ j' K  {
  26. #define scl_low()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);. E8 L# [. P& u2 m' C: c
  27.                         
    , Z6 |% C2 u! i. g" q
  28.                         
    % x- L1 H9 C! o, ]; @
  29. // ------------------------( ~% U- \4 i1 j  J
  30. #define DONOTHING()          {;}
    - _: u/ w% z" s

  31. 7 m5 u) f9 W. Y! g5 V
  32. // ------------------------
    1 ~1 J# n" ^. h2 p0 c% G
  33. // command's
      P8 J5 U" j. Z3 d4 o% ^& `/ Y
  34. #define I2C_WRITE             0
    # `2 a' _/ d5 M( y4 G; J( m
  35. #define I2C_READ              1: W% Z  e: T' J
  36. #define I2C_ACK               0
    2 {  E6 F' J& o1 H# C7 |& h! V
  37. #define I2C_NACK              1
    * |2 U: }9 a2 X- t/ p* Z
  38.   w1 t. W# z0 L3 A; t7 H; c' C
  39. void i2c_init(void);+ r. B5 l1 ^# Y- T( M% h
  40. void i2c_start(void);# k7 B6 B: E( D- Y- [3 \
  41. void i2c_stop(void);
    # [, F' E4 Y. F6 m" e$ g* _
  42. uint8 i2c_write(uint8 u8Data);+ ?4 e) M' ~8 j4 _8 s
  43. uint8 i2c_read(uint8 u8Ack);
    : E0 k0 d+ ?2 u+ r% r8 e
  44. 6 h* ?* t7 T. m) p, V+ a- y) E
  45. #endif
复制代码

# M0 B4 H3 ]5 f: G, C

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

测试结果:

. w# @! v. ^, `: B# Z% T

微信图片_20230612191105.png


* a% J2 C! v# q! R3 U! g. E9 q

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


! X( Y4 u# S( g% Z6 }

转载自:矜辰所致

如有侵权请联系删除
9 z. x5 [7 ~+ s9 z2 t

" Y, E0 J8 Q/ P& R5 w7 k2 m9 f

/ d; C+ q( @0 B8 R
收藏 评论0 发布时间:2023-6-12 19:11

举报

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