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

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

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

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


# z* }( K, [  F/ c. W# D

  Q8 Y+ I) J8 H 微信图片_20230612191118.png
: D8 J( r( U9 Y. G# P! M1 w, L# o6 ]8 e' j! ^) v. O$ K

/ B6 H9 `* b1 W9 y2、HAL库中的us延时函数' s. U' P/ C6 U' ]1 u0 ]8 b

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

  1. /* USER CODE BEGIN 4 */
    ) {; }; z  ?8 m3 f+ U5 R; C2 P
  2. void delay_us(uint32_t Delay)
    * o9 g  f" O9 K
  3. {' Z( ?( e0 o3 Q  L) N
  4.   uint32_t cnt = Delay * 8;  
    5 y2 _$ ?  J& ~- \1 t
  5.   uint32_t i = 0;4 h; i0 _' K. a$ Z1 [" c& S- \
  6.   for(i = 0; i < cnt; i++)__NOP();0 D  Z) N6 q! c: p# J* ^$ |% [
  7. }
    % C; H5 N3 P, a: {- c/ w
  8. /* USER CODE END 4 */
复制代码
" s7 ?+ d. x' ?, {  z
3、移植I2C代码3.1  SHT21温湿度传感器

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

  1. #include "i2c.h": w# z0 z7 C8 S

  2. $ V9 i4 y+ x' W9 v8 F: S$ _+ {4 J" F
  3. // ------------------------------------------------------------------
    6 K6 x, n* q9 f4 q0 y- @
  4. void i2c_init(void)  {
    ; A( U# z- S. Z$ h1 b3 X; L' y
  5.   
    $ c) S7 Y) b2 A) k& C
  6. // the SDA and SCL pins are defined as input with pull up enabled
    5 \4 O% o: A& Y: W$ Y
  7.   // pins are initialized as inputs, ext. pull => SDA and SCL = high
    8 a1 y0 i# P) N+ T9 [/ m0 d

  8. 5 Y, G) ]% n: {2 O$ L, k1 i
  9. }; c6 P) ]! h3 A2 M: t/ y& r/ G
  10. // ------------------------------------------------------------------" u9 H( S4 @' i3 u- e) ]1 W
  11. // send start sequence (S)
    9 I% I( q2 h7 X

  12. - ]# Y( M  h% T. i3 Q
  13. void i2c_start(void)  {                                    ; F. a4 M& r, P% m/ m) V5 v5 X1 a
  14.    sda_high(); # B% R) g; ]& x
  15.   delay_us(10);; r7 v( b5 \' p
  16.    scl_high();  
    4 R: _% {% B& t2 t/ l
  17.   delay_us(10);
    * k9 H: b9 R! i7 D* x& s
  18.    sda_low();
    : e8 C1 I4 T0 e3 q
  19.   delay_us(10);4 f* D; l6 V( b8 s
  20. scl_low();                                                   0 Z! a" K$ ^5 f: J3 G2 E
  21.   delay_us(10);. [" G6 A( F8 F! |) P) H) L
  22. }
    / t) j7 I6 `9 P1 w4 \& W
  23. // ------------------------------------------------------------------
    7 a0 t& Y) R& n
  24. // send stop sequence (P)
    + D' s( J! e2 n3 y: b
  25. void i2c_stop(void)  {                             5 f9 o  g6 s2 T. s/ {
  26.    sda_low();                                                                          / X& |# E1 V& E; i
  27.   delay_us(10);
    - k1 R  h+ Z0 v, h
  28.    scl_low();                                       ( a- X% k# l+ D0 l+ j' F; S7 F
  29.   delay_us(10);                                 * f: p$ u7 H, F' r: m- y
  30.    scl_high();                                         ) D$ _# O8 W* v3 e1 I7 h0 x; X
  31.   delay_us(10);                                       
    & H8 s4 U2 ?$ F8 u1 \( v3 s
  32.    sda_high();
    : X, P  }% Q5 u+ t( s1 X
  33.   delay_us(10);
    3 P/ ]& ~0 x, Y5 s
  34. }
    1 Z9 X$ W0 ]3 W; j- |/ N& @. x
  35. // ------------------------------------------------------------------& K; Y3 L. r& T/ `  o& S  U" i
  36. // returns the ACK or NACK! L5 g' d8 r  G! m
  37. uint8 i2c_write(uint8 u8Data) 4 D, Y% r6 r+ O7 [& j
  38. {- p" e6 E) O) r' u
  39. uint8 u8Bit;) |  T& ?5 ~! B, [8 |
  40. uint8 u8AckBit;
    / P" e6 H+ n" L8 @6 t
  41. // write 8 data bits/ S4 C6 u4 o! h4 N, V
  42. u8Bit = 0x80;  //msb first  
    1 d. `, {+ U* N( Z. K% C2 g. K
  43. while(u8Bit) {
    9 Z& E! Y, ^5 n3 v; h
  44.   if(u8Data&u8Bit) { ( U1 Z# J6 G8 }# l0 X' y
  45.    sda_high();' @5 F$ n; e: _& W& T$ p
  46.    delay_us(20);) Q- B+ l. r$ V4 r# {9 P3 s! \
  47.   }
    ' A1 `2 L) U# E, A" b) u2 Q5 l
  48.   //& compare every bit! l. l* Q" ^; \- a, x
  49.   else{
    ' q/ E4 k& s% g9 j& l5 h1 f
  50.    sda_low();3 b. E* L9 d5 }4 O
  51.    delay_us(20);, \" I! t% l  ]& b* a
  52.   }   
    4 i0 {( t* ?7 j* J
  53.   scl_high();
    , y/ t) T+ w1 w3 s1 b$ o; E
  54.   delay_us(30);
      n4 F% s" X" }3 ^
  55.   u8Bit >>= 1; + T) [1 \3 `9 E" ^' t, m
  56.   //next bit9 C! x  T, i1 Q/ S, t% b
  57.   scl_low();
    , U* h& A$ n$ M" n' c
  58.   delay_us(30);
    ; {" Y1 Q5 X, t5 O2 n" C) q) [1 h
  59. }' }$ h2 W% A0 m7 c( q- w
  60. // read acknowledge (9th bit) : V8 F, J- i! N5 ]
  61. sda_high();                                               
    . L$ f3 n% s! m7 Q2 `9 ]) ]0 k
  62. delay_us(10);  7 E' ?- S: C0 h* _4 E4 @" x" l6 Z9 }
  63. scl_high();
    8 _' X: a% z" w1 u/ @+ A% p
  64. delay_us(10);
    , s/ M2 r# U" r8 H! t# R& N
  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' ^5 b# O; L* X9 S) y# r
  66. delay_us(10);
    % ?5 V8 \$ N$ M: e+ ^% @( T1 G
  67.     scl_low();                                             
    $ ~2 u& G; S/ G0 Z) s7 P
  68. delay_us(10);
    " U' A% {* d3 _+ u7 Y# s" r, r5 _
  69.     return u8AckBit;
    8 U% q& ^0 k7 J) `8 ?
  70. }
    2 y9 m% u8 G, f0 b! H1 s; A, R+ e
  71. // ------------------------------------------------------------------
    + j+ _2 [. @" m3 [1 m
  72. // pass the ack/nack 5 D5 i1 k* ^) Z7 @" c
  73. // returns the read data - j  w6 a* u' m2 k
  74. uint8 i2c_read(uint8 u8Ack)  
    6 m7 y/ f" o! |6 ?
  75. {
    0 [2 w( c8 T5 `# _' P
  76. uint8 u8Bit;
    - E, A+ {- o4 n+ {
  77. uint8 u8Data;
    ) S6 y% X# M: m  X
  78. u8Bit = 0x80;       // msb first& h6 r/ a6 e) C( B$ v- K
  79. u8Data = 0;9 |2 u0 k! x+ W1 ]4 V  K9 A
  80. while(u8Bit){
    # h  D7 T& k* g. Z9 z! i" j
  81.   scl_high();. s, D0 x5 q/ s0 N2 r7 d- S4 O8 Z
  82.     B5 {1 ~6 m; A4 K
  83.   delay_us(20);' h0 p, k2 u* g, S3 K* b
  84. ( u/ ^9 l3 \. @4 {6 D! P
  85.   u8Bit >>= 1;    //next bit! l2 D4 t3 o0 E$ s
  86.   u8Data <<= 1;+ y, R  ~5 h3 J# k& p# e

  87. # M/ _1 Z' q3 s  [, v
  88.   u8Data |= sda_read();         //(sda_port & sda_pin)? 1 :0      sda_port gpio0   sda_pin SCSEDIO0
    " s6 n5 i8 q/ g' N
  89.   delay_us(20);4 M! [: ~. A/ w  K4 m  Z# @4 |/ ^+ a" p

  90. ! \$ f# ~( t, J( x) Z
  91.   scl_low();
    - N5 U/ R. S$ R" y6 `2 g. ]+ c# ]# g
  92.   delay_us(50);
    , e+ @1 H. T5 S4 h- S
  93.     }7 ?$ x7 W4 A4 B" E5 D! o
  94. // 9th bit acknowledge; q/ i! [4 o+ g" ^  c$ U- [6 v
  95. if(u8Ack==I2C_ACK) {
    8 R, ^8 p3 d) O8 x1 a- T4 J
  96.   sda_low();8 I: ]0 V8 _- G7 M) ]
  97.   delay_us(20);7 k9 `: P9 I  n7 J  @
  98. }     % `3 ]! }/ b) f( x
  99. //I2C_ACK=0
    # a$ F! z( h% F0 W4 d9 s, p
  100. else {
    7 `8 d4 N; x. O9 J
  101.   sda_high();) f6 r1 X4 \- v: u" e! q3 @
  102.   delay_us(20);
    3 q1 l( H0 F0 t$ C$ K) f
  103. }
    9 C/ M- k& e5 |: ^# x) l: n
  104.    scl_high();
    8 k5 T) D( [7 D# c8 r* N
  105. delay_us(20);0 f, Z( y- Z) _' j7 h  X
  106. scl_low();7 D8 c. o4 f7 L1 u6 {
  107. delay_us(20);/ A/ h+ }# I, A; r6 p8 o
  108. sda_high();8 n+ s$ ^( \9 I2 A
  109. delay_us(20);         
    : ?+ I/ g3 f4 d% n
  110.     return u8Data;1 m3 B2 m* u9 }
  111. }
复制代码

* A, J5 J3 r. t% `, t

i2c.h:

  1. #ifndef _I2C_H_INCLUDED8 V% M" e- @/ Z# D+ M" |
  2. #define _I2C_H_INCLUDED* N# D- l1 i0 t

  3. # V' N* ^- B* a7 ^( {, f) r2 l
  4. #include "main.h"
    % g; L# ]1 R8 G: a. Q) g% E0 t
  5. #include "Datadef.h") x  u& I2 |; W" j+ O
  6.         
      e, n7 C3 M3 E: ^$ A
  7. // #define I2C_CLK_HIGH()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);$ Y# H# G  }7 J9 J5 E4 d. D3 \
  8. // #define I2C_CLK_LOW()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);
    ! w7 l  r5 D2 J) I

  9.   c) h' p7 c4 x- B+ O8 s! {
  10. // #define I2C_DATA_HIGH()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET);
    / i+ f, y4 y/ K5 Q! G- P
  11. // #define I2C_DATA_LOW()    HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);  % Q3 R3 i0 f4 o% ?! }
  12. // #define I2C_DATA_STATE()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET); . S" p0 B& f5 E- {- R4 L
  13. . i2 k( O( v" q
  14. // #define sda_high()  I2C_DATA_HIGH()     // set signals to HIGH first before selecting IN -> slew rates
      G& u' P) T3 ?5 V5 y
  15. // #define sda_low()   I2C_DATA_LOW()
    : }, Y. Y, k5 ?9 ^5 o+ l8 Y7 H
  16. // #define sda_read()  I2C_DATA_STATE()    //ack on bus is low -> u8AckBit = 1: d2 S" H% f+ s2 Q7 S

  17. 6 c0 E; T/ V, D7 k; b8 s$ _' m; z
  18. // #define scl_high()  I2C_CLK_HIGH()     // set signals to HIGH first before selecting IN -> slew rates: }4 F. a( o/ i  Q) ^
  19. // #define scl_low()   I2C_CLK_LOW()
    . x* W' D3 K- Z$ m" H# j

  20. 3 y- N, N9 C- o$ e) m& o
  21. #define sda_high()  HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET); 4 P7 h% ~* f4 B8 x$ J# Q. m/ C) V1 o
  22. #define sda_low()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);& l6 y# c: u0 U; v
  23. #define sda_read()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);
    8 G$ S* z# d" h" b# d, \' a4 }

  24. $ c9 F* E6 t9 P. d8 Z$ G6 t
  25. #define scl_high()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);! X8 c# F6 }7 P! a5 T
  26. #define scl_low()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);  S% X! z: d/ Q7 I/ `' d% L
  27.                         
    8 Z% @0 j- T4 o; Q' P
  28.                          / X$ r! x9 g" ]& B# L' v2 B; g
  29. // ------------------------6 r* T/ A0 J8 z
  30. #define DONOTHING()          {;}
    $ \0 ?* @- i  F  X4 E8 K
  31. 5 m& y! b: j7 {9 j$ b
  32. // ------------------------3 m( W# l& y' k
  33. // command's
    ) B( W4 M( _6 g+ X' o" Y" U1 o
  34. #define I2C_WRITE             0
    2 ]. _6 f2 \  R' f" H) v5 Z
  35. #define I2C_READ              1
    : `1 n6 q1 a& b7 ?9 E/ A
  36. #define I2C_ACK               0
    3 l3 S# F$ m9 v! Q" b
  37. #define I2C_NACK              13 I: e# C. I- S% H( p6 f
  38. & c  N8 b" N: e% Z
  39. void i2c_init(void);
    ! F+ B  c/ E1 j6 C! q: i. Z% b( E
  40. void i2c_start(void);
    + W3 J- T8 K6 A; y5 u* \
  41. void i2c_stop(void);% o. {5 h6 }# G- W
  42. uint8 i2c_write(uint8 u8Data);
    " Z( {# |! F# d6 x. o2 `
  43. uint8 i2c_read(uint8 u8Ack);
    , n6 [* R% U  F7 o" u

  44. / B* {' X) \& s( n3 o
  45. #endif
复制代码

* g- X3 s: J. I: s% X

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

测试结果:

* I% A6 x- E; [

微信图片_20230612191105.png

$ R# K* ]: o: p$ L# m

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

+ X) c+ r1 I" r/ r: t# D. h

转载自:矜辰所致

如有侵权请联系删除
: H' g# |. w/ R+ C/ P0 ^: _/ e

  Q& Z5 z: s9 Q. f3 j
' l/ O: Y, g8 l4 _
收藏 评论0 发布时间:2023-6-12 19:11

举报

0个回答

所属标签

相似分享

官网相关资源

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