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

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

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

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


# b( S# A) F7 l: R8 }! W0 C
# P$ h% \. ]1 T
微信图片_20230612191118.png $ H5 ~% U# {9 p7 f, w" y! l) u0 n

2 i- ~2 c% H3 `6 Y3 R1 W$ U6 ~
' R5 q' Y6 t4 Z2 W7 c2 R( E
2、HAL库中的us延时函数2 q( j% z6 N& A

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

  1. /* USER CODE BEGIN 4 */" E  b  @( @" t/ D+ w
  2. void delay_us(uint32_t Delay)! g% Z4 \4 s4 l* N: ?9 i
  3. {
    # ?( R$ v7 H4 E. I" s9 G# D
  4.   uint32_t cnt = Delay * 8;  
    ( U/ T) y7 F- P/ W
  5.   uint32_t i = 0;; ]  G1 H; U% Y: }+ H
  6.   for(i = 0; i < cnt; i++)__NOP();
    9 H1 i/ w2 W% j! ~* \
  7. }3 }! S# ~9 J3 S+ {/ M+ m) ]
  8. /* USER CODE END 4 */
复制代码

2 E$ `+ O2 o# n- z+ P  q3、移植I2C代码3.1  SHT21温湿度传感器

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

  1. #include "i2c.h"( i& e7 t/ p4 K( ~( S' E' A0 p6 q

  2. $ ~, m: m( v7 R# [" c* e: J6 t
  3. // ------------------------------------------------------------------
    3 f6 N" r( d, m2 ~8 E
  4. void i2c_init(void)  {
    / p8 o9 N/ R. y8 r% e6 j( t
  5.   $ R; c/ r0 B& \- @, F* d! Y
  6. // the SDA and SCL pins are defined as input with pull up enabled. k; Y4 [6 f* h% f
  7.   // pins are initialized as inputs, ext. pull => SDA and SCL = high2 y0 i& s, s2 e8 m& p+ b7 l

  8. 1 N( H  {" H' {$ }
  9. }; f: c* q( w+ L7 g8 G/ e
  10. // ------------------------------------------------------------------; a: U( f% Z7 e
  11. // send start sequence (S)1 K# G& r0 b0 z/ k7 Y, _3 E+ r
  12. 9 R2 L5 m! i7 w; _: q
  13. void i2c_start(void)  {                                    
    9 K5 r& y2 S8 d7 G' q8 `3 Z! T
  14.    sda_high();
    , J3 C, Q4 R$ F! ^% f# Q* u+ H
  15.   delay_us(10);: G2 N. Y  A- q/ h* X% n, }! U+ j' g
  16.    scl_high();  
    % z7 t) F% A& t9 J7 n
  17.   delay_us(10);
    5 k& \5 ^) b& h$ ~) @
  18.    sda_low();
    + S' C4 H" f4 r3 s* ^$ C( `/ Q: M
  19.   delay_us(10);- a1 F1 ^) D3 q. b- W! k
  20. scl_low();                                                   
    9 Q$ W0 v5 |: x9 {* A: w3 d% u
  21.   delay_us(10);
    1 m. N; ~8 N" P
  22. }
    9 b' g+ z% K  t! f' h
  23. // ------------------------------------------------------------------8 M% D6 k; [4 z' j/ O& L
  24. // send stop sequence (P)
    8 W7 [7 W3 f' H3 r+ j2 T
  25. void i2c_stop(void)  {                             
    7 l8 o8 L( `& s* u; W# z
  26.    sda_low();                                                                          
    7 t; \( r* t! u- g
  27.   delay_us(10);' J' `$ M) E  G, u6 D. q
  28.    scl_low();                                       
    7 U8 Q6 A" b6 ?; {: o) ?% h
  29.   delay_us(10);                                 % x- o# ?0 o9 o% v' k; Z8 P( k
  30.    scl_high();                                         ) v/ P; {# G2 F3 N' B
  31.   delay_us(10);                                       / t1 S7 ?% `0 [) W! I6 \7 o; N7 q
  32.    sda_high();
    0 o0 O" C/ |% f4 X" S1 d( x$ I
  33.   delay_us(10);
    0 ~0 g' P  L  M4 I" P3 f
  34. }
    ! B" \+ H8 ^) X
  35. // ------------------------------------------------------------------, P7 h) {5 V; b# R& Z
  36. // returns the ACK or NACK
    ; W. R( w# }  o; z+ C
  37. uint8 i2c_write(uint8 u8Data)
      R: }+ r$ n$ i+ e6 w5 {, z
  38. {
    + g. G# ~5 x* b# c* S3 \* {% M
  39. uint8 u8Bit;
    7 J+ @. ]. X: N4 s1 ~  q
  40. uint8 u8AckBit;( |# v) b0 t" [# G0 P+ @- Z
  41. // write 8 data bits- o1 k" P. _) f' {3 L
  42. u8Bit = 0x80;  //msb first  
    7 Z/ S% p# A% N' {& @
  43. while(u8Bit) {; }- |+ y3 |! ~( r6 A
  44.   if(u8Data&u8Bit) { , O  @' f  h2 U2 J
  45.    sda_high();
    5 b* _& K: }9 N  r  ^
  46.    delay_us(20);
    4 y+ J- M# {/ G' s& V8 v1 R/ b
  47.   } ' g' O% @2 I& V
  48.   //& compare every bit
    6 q- i1 h# s% S$ U8 {
  49.   else{
    * L9 D( Z3 Y  N1 q0 n( u8 R6 Z9 S
  50.    sda_low();
    9 ~0 C! {9 l  X  R3 E
  51.    delay_us(20);9 m/ U1 ]9 ?0 h- T8 O$ l4 R+ V
  52.   }   2 f, o% _# ~. z5 k' ^) C; T4 \
  53.   scl_high();" }1 g( n# r( x
  54.   delay_us(30);: o# i$ b( ]# U/ |0 p9 \" I  D, {2 ]
  55.   u8Bit >>= 1; % T; U7 r; k" n( u/ L( b( c" @& U
  56.   //next bit
    ' t* t+ E7 v5 R; D3 d, g
  57.   scl_low();
    % _) k* C5 E0 R2 }
  58.   delay_us(30);
    0 U8 ~7 d3 N7 h1 u- U
  59. }
    8 s, `: S* a/ i
  60. // read acknowledge (9th bit) : I* s! Z3 ?0 m  O) p# M9 j; Z
  61. sda_high();                                               
    & \" |3 t1 U% g5 r
  62. delay_us(10);  
    ' o' n1 B# K/ b: K) X
  63. scl_high();/ d, r( u. w3 B- I  W# z
  64. delay_us(10);2 P2 h2 ?$ h# N/ K! C1 o& s
  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 SCSEDIO06 T8 }9 Q# }/ C# e, E, e% ?
  66. delay_us(10);6 q; `- ~2 e7 u. r! J5 {
  67.     scl_low();                                              * U3 n$ O; m: A! e4 o/ m
  68. delay_us(10);
    $ f0 }! y) L; s4 Q
  69.     return u8AckBit;" C1 G9 C) Z! ^9 I( K
  70. }
    ; Z" ~- u0 i  x& c
  71. // ------------------------------------------------------------------
    7 N7 v; ~# O- c9 O6 e
  72. // pass the ack/nack ) J' ?2 d' M- f. D8 R
  73. // returns the read data
    ; n* B6 Z7 A. p' a; r, j0 [
  74. uint8 i2c_read(uint8 u8Ack)  - [5 |; S4 U6 T9 t; \
  75. {' J: c$ H2 T0 h
  76. uint8 u8Bit;4 u" `. J5 m- z# r& K8 p( a. O
  77. uint8 u8Data;
    , @: y$ F1 U' @% g$ n
  78. u8Bit = 0x80;       // msb first7 U( C* t7 }! a! T, o$ C
  79. u8Data = 0;5 m# z3 w0 C" C- n# O+ R) q
  80. while(u8Bit){
    ( e  X) o+ @3 D
  81.   scl_high();) S  T/ l0 N' U3 D8 l. D8 _) ?: U8 T
  82.   
    1 u  |& J& N5 ]+ F. j3 R2 q7 ^) l6 i: U
  83.   delay_us(20);7 b# S, d- l  c) N; D0 J

  84. 3 e9 A4 a( p, K7 Y7 N
  85.   u8Bit >>= 1;    //next bit
    1 x5 s4 x7 y' ^5 |. T& w: |( [
  86.   u8Data <<= 1;
    & E1 Y8 Q  i2 V0 X
  87. / @+ L7 }& X6 K
  88.   u8Data |= sda_read();         //(sda_port & sda_pin)? 1 :0      sda_port gpio0   sda_pin SCSEDIO0, N6 I" U5 }' E
  89.   delay_us(20);
    6 n  u* v. T, |  o1 D
  90. ) Y, k# S: M; z) K$ E% ]6 w
  91.   scl_low();( M( o5 N" D/ N9 O. ^/ T/ ~
  92.   delay_us(50);% u' C7 U/ F2 _% u& \
  93.     }8 _9 o6 y! p! w( v/ m  J) S- ~
  94. // 9th bit acknowledge* g' A2 U$ f$ y% F  e
  95. if(u8Ack==I2C_ACK) {
    & U# k! \1 V4 Q4 e
  96.   sda_low();
    ! S# n7 l, B( I/ s2 I. I: X2 G
  97.   delay_us(20);
    , K( l  k3 i) W+ E0 \
  98. }     
    / N; y* [) B* T( T, N4 _9 F4 g/ M
  99. //I2C_ACK=0
    9 M5 t: Q$ S4 U; }
  100. else {- |# P- c* ]( o6 J- ?+ U- w
  101.   sda_high();  D4 r( ?" _* y4 t% S3 {5 T+ I
  102.   delay_us(20);
    6 y5 o" B0 ^' |5 i( p2 k
  103. }
    % u! J7 Q  u/ Q
  104.    scl_high();
    - a6 p2 C$ F( h
  105. delay_us(20);/ P5 b. R# j4 ^" q7 O  W* W6 ]
  106. scl_low();* ^- T% n1 U3 _6 h
  107. delay_us(20);
    ) D9 H" b8 j8 V1 h& i: \
  108. sda_high();
    1 n4 c: n5 m$ ?' o" b. B
  109. delay_us(20);         $ q' g2 w0 d2 x
  110.     return u8Data;
    . {. [- ^6 z8 z! A% x
  111. }
复制代码
5 E5 n# d7 r8 O% R

i2c.h:

  1. #ifndef _I2C_H_INCLUDED7 Z5 S( _. ^5 m8 }* j. m
  2. #define _I2C_H_INCLUDED9 n0 Z) H3 p. K. Q2 c4 N
  3. 5 P/ K3 Y% |) ?5 i6 R- T/ X4 ?
  4. #include "main.h". s' j; Y/ T* S* ~4 W: O
  5. #include "Datadef.h"
    ; Y$ M2 S1 H. V9 n
  6.         6 ?! _5 k; W! b" p9 h
  7. // #define I2C_CLK_HIGH()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);
    ' R0 T; {; O* A/ O, b
  8. // #define I2C_CLK_LOW()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);
    6 V$ C3 `! n7 _6 r

  9. 6 R$ |* l; l2 \, w5 {+ l
  10. // #define I2C_DATA_HIGH()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET); 7 d! u2 E! @3 V% I$ X, n
  11. // #define I2C_DATA_LOW()    HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);  
    + ?5 q4 ]9 k) |( l6 b
  12. // #define I2C_DATA_STATE()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET); 9 [9 l7 I$ A6 @7 R, ?
  13. * m8 U0 g: q# f3 i' `$ N) @
  14. // #define sda_high()  I2C_DATA_HIGH()     // set signals to HIGH first before selecting IN -> slew rates
    0 S2 y* u/ a5 z, A9 F: @
  15. // #define sda_low()   I2C_DATA_LOW()
    & Q# H. O* F' a7 A' [
  16. // #define sda_read()  I2C_DATA_STATE()    //ack on bus is low -> u8AckBit = 1
    1 k! s8 X4 C$ E+ J+ B" y
  17. 1 W/ [/ u& z) k
  18. // #define scl_high()  I2C_CLK_HIGH()     // set signals to HIGH first before selecting IN -> slew rates+ M9 Z& p4 h! k9 O5 }
  19. // #define scl_low()   I2C_CLK_LOW()
    + p" p) |0 B( h- w( R. l
  20. # i5 j+ H7 ]- a: P( Z
  21. #define sda_high()  HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET); 1 R5 k& O1 a4 i" R$ x
  22. #define sda_low()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);
    . y% m( I4 o, `0 y& x9 O
  23. #define sda_read()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);8 ], E) w' d7 R
  24. $ _9 l1 K! l& v$ Q9 F
  25. #define scl_high()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);9 _# K. q: C4 Z/ q
  26. #define scl_low()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);5 e- l- o, t( x8 q9 D# ^
  27.                          # _1 g* T, h0 o0 O6 \' M0 J" B# Z
  28.                         
    + b- S& l" ^- }! q( w
  29. // ------------------------
    6 t+ K! E$ S- E& v
  30. #define DONOTHING()          {;}
    5 h( x) d9 E* c
  31. $ J, E8 _5 z7 J2 o: {
  32. // ------------------------8 }) f; B0 c) c8 I
  33. // command's
    . H% s# {# Q. F9 T) C
  34. #define I2C_WRITE             0
    * `7 f, m8 R* m$ l  _
  35. #define I2C_READ              1( h/ \+ j2 }% @$ k
  36. #define I2C_ACK               0
    3 t3 ~1 L0 _7 W
  37. #define I2C_NACK              1. W! a# m1 C1 `, }6 }
  38. + |- l# m8 Q" O. L) A! f9 h4 M  E
  39. void i2c_init(void);6 \! @8 ^. Z: D7 K
  40. void i2c_start(void);, a8 y/ T$ I& J* A
  41. void i2c_stop(void);
    + J$ {) p. F  ?3 K
  42. uint8 i2c_write(uint8 u8Data);4 ~+ d, F$ o* G1 S6 K6 J2 T
  43. uint8 i2c_read(uint8 u8Ack);
    7 S  M) C- W* i& U1 q! ^: q
  44. 0 V5 |! [" p* t$ U" E- T
  45. #endif
复制代码
- Z5 K9 k9 I; m

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

测试结果:


! `5 Y, e, l$ H

微信图片_20230612191105.png


( b4 N) S) M" P$ c

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

( ^! R0 d: ]' u; n$ v' Q5 J

转载自:矜辰所致

如有侵权请联系删除3 `- x  i, H, Y

8 h; E& Z* `- j+ i, m6 f$ w/ }

: E/ w/ }) x% l/ r! V
收藏 评论0 发布时间:2023-6-12 19:11

举报

0个回答

所属标签

相似分享

官网相关资源

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