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

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

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

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


: r/ b* U/ a1 ^2 u" S4 _! D

* h" Z3 Q% |. j9 I 微信图片_20230612191118.png
+ w6 c3 C: G: ]' T3 p( e% {' ?* P
: l8 v$ y! r4 I1 r( ]; x0 d

% k/ f5 W+ F1 n* X2、HAL库中的us延时函数
# y$ h: T  O5 u

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

  1. /* USER CODE BEGIN 4 */" w! G3 q# C  v8 n( i
  2. void delay_us(uint32_t Delay). u) }/ N! X5 A- b% O  b% ~# g
  3. {
    . {7 U- A( w9 i5 K4 N0 U5 }
  4.   uint32_t cnt = Delay * 8;  
    0 a8 `7 `6 B' q& B
  5.   uint32_t i = 0;5 i6 L) ^% z3 _) N' ?: _  B
  6.   for(i = 0; i < cnt; i++)__NOP();
    + z0 Z4 g% A% `+ V0 K. G
  7. }2 \1 T5 h+ n" z2 G( T+ O6 B
  8. /* USER CODE END 4 */
复制代码

0 [7 e3 K$ r8 j3、移植I2C代码3.1  SHT21温湿度传感器

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

  1. #include "i2c.h"
    / S# I- V( l5 z: @, J

  2. 5 z# N4 F4 j5 U0 e- }& w
  3. // ------------------------------------------------------------------
    8 X+ ~' m5 n0 L: P/ w
  4. void i2c_init(void)  {4 z; q' Z9 m3 Q# F# p; r
  5.   
    . s" _$ R& ^. o1 C9 m/ t
  6. // the SDA and SCL pins are defined as input with pull up enabled: L. ^5 o5 C: b
  7.   // pins are initialized as inputs, ext. pull => SDA and SCL = high
      G, ^: A: n3 O" R# j7 d: c4 T8 @' K

  8. 7 Z4 b4 R9 H- h4 x/ J# P$ v
  9. }# i: \3 y! e$ P% o- v( K
  10. // ------------------------------------------------------------------; @8 j" O7 t" K; w  s: O4 C
  11. // send start sequence (S)
    4 _3 a4 N" Y& D

  12. / [3 p( Q$ \" c  t+ k1 t
  13. void i2c_start(void)  {                                    
    " ?" U) N# L/ J/ t
  14.    sda_high(); 6 d1 O& ^# {5 z7 O: G4 [1 \
  15.   delay_us(10);
    ! ^; X, Y# g2 i2 F- ]8 o
  16.    scl_high();  
    6 l& P' n5 J* ^5 u: L5 c# v/ j
  17.   delay_us(10);, ?" c: W4 E; y5 y3 A
  18.    sda_low();
    * L; k, {- S) K+ t# V( M/ Q
  19.   delay_us(10);' X3 `- I. q3 s+ w# U0 Q& q
  20. scl_low();                                                   # ]& _2 K1 v7 V0 e
  21.   delay_us(10);
      X+ u% l7 K" B9 F
  22. }
    ! b* D6 M% a. G" i: d
  23. // ------------------------------------------------------------------
      ^4 s: @1 U7 O- t
  24. // send stop sequence (P)5 T" {! d6 e8 V5 {
  25. void i2c_stop(void)  {                             4 B+ @) P9 J# u) S/ A, o
  26.    sda_low();                                                                          1 ]1 a, O: Q4 u
  27.   delay_us(10);6 ~: l' i5 k6 ~  I" s
  28.    scl_low();                                       
    5 J( Y+ {: r, j- [
  29.   delay_us(10);                                 
    & @9 p' t3 ~6 Y) q
  30.    scl_high();                                         & j8 Q6 X' _7 Y4 N
  31.   delay_us(10);                                       
    ! L3 v) P! x8 Z6 }
  32.    sda_high();% h- B) ?" R. G9 \: v: ^' u) v) X
  33.   delay_us(10);
    - t! o: e# @( t, i. |7 V7 U1 T
  34. }
    ! O! w$ J+ e. g) ^+ v  T% j
  35. // ------------------------------------------------------------------- p- D8 a6 J+ A
  36. // returns the ACK or NACK  D3 ?/ r9 }( Q/ o
  37. uint8 i2c_write(uint8 u8Data)
      u& y) _' m/ K9 q. @, m, F4 f
  38. {: ^. B0 W4 B; Y, r2 {; C6 |: s1 b
  39. uint8 u8Bit;
    " U5 k6 [4 x$ D) \
  40. uint8 u8AckBit;
    # h% p6 J1 C, m7 i7 ?6 Z9 X
  41. // write 8 data bits* w( B8 {$ m3 N' ~
  42. u8Bit = 0x80;  //msb first  
    + q& k" ]% n' a: C  z
  43. while(u8Bit) {- h. t6 ^+ J, s( N$ h5 Z
  44.   if(u8Data&u8Bit) {
    * ~8 H( K. ~, u, _# B
  45.    sda_high();  q5 J6 ]' B& U; v6 x. f" }
  46.    delay_us(20);- B  E8 [* e$ n
  47.   }
    . w9 |( F; ?( j0 M  L8 f9 B
  48.   //& compare every bit
    ! q. d, o& p1 P
  49.   else{ % g( H, s) i0 J, T
  50.    sda_low();
    " R. l- P6 V9 V8 Q* j
  51.    delay_us(20);) w2 K' l2 T$ T( f
  52.   }   
      \  }4 J  g9 g+ ]
  53.   scl_high();
    5 l7 Q! W# O! H3 p5 {- P
  54.   delay_us(30);
    , J$ W8 |+ B) R/ D; H3 ~- R
  55.   u8Bit >>= 1;
    ) l+ p$ i- P" o* Z: |7 G& u2 \- j
  56.   //next bit
    , D$ m5 c& d0 _* e3 a, H
  57.   scl_low();/ t; K0 n4 g6 t' Z3 o
  58.   delay_us(30);
    - }: s" b' K+ w/ Y/ d! a
  59. }) g' r  m, ~# G1 T/ ^" r
  60. // read acknowledge (9th bit) 5 N) u5 b; `% B- d
  61. sda_high();                                               
    9 o3 B, ?4 G7 d4 d: [
  62. delay_us(10);  # U& z6 m4 W$ S3 t
  63. scl_high();9 X/ Z4 {, K/ E9 l. w+ c& M
  64. delay_us(10);8 }  Z& s: b% I& [: 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 SCSEDIO02 s1 A  a6 f3 x# u
  66. delay_us(10);
    $ Q5 d  @) C$ O- r1 Q- r2 i
  67.     scl_low();                                             
    ) k  B" ~* f9 g' P
  68. delay_us(10);) i; q5 P) n" S6 ^) t9 D) _$ Y
  69.     return u8AckBit;
    - R9 p% P+ H. P5 l6 P
  70. }7 h2 o9 u4 z3 G2 ^4 Z) R
  71. // ------------------------------------------------------------------
    ! l. Z) ~0 v  A' g4 w
  72. // pass the ack/nack
    . `4 s& U$ }% l+ \9 N# a
  73. // returns the read data
    ' u9 h5 t. n$ s& s* k( P# |
  74. uint8 i2c_read(uint8 u8Ack)  
    3 g% K9 n7 z% H
  75. {
    9 U/ l, n4 R2 Q2 s) M$ z
  76. uint8 u8Bit;4 h3 D4 w2 ~3 H2 G2 e
  77. uint8 u8Data;4 l4 X- F  n) G
  78. u8Bit = 0x80;       // msb first7 w/ D9 G  ^( b; H
  79. u8Data = 0;4 W* W6 y9 a" n
  80. while(u8Bit){/ h% z* K5 V+ \1 o! S  F/ ?
  81.   scl_high();2 t! y  Q' g8 P  M) E
  82.   
    - M3 G! F1 g) v% I) d7 Y. B* _9 ?) t
  83.   delay_us(20);
    ' ]. U) Z( _4 c! V8 T

  84. 0 w0 T9 [; V# G3 h0 y
  85.   u8Bit >>= 1;    //next bit
    9 p1 L3 d! p/ R: ?3 r6 A2 X
  86.   u8Data <<= 1;
    3 d/ U4 q! u+ i
  87. * l1 w/ \2 p& u5 F3 U$ c
  88.   u8Data |= sda_read();         //(sda_port & sda_pin)? 1 :0      sda_port gpio0   sda_pin SCSEDIO0
    7 a8 `6 m3 [% z" J# O! e' s
  89.   delay_us(20);
    , `' A( `  \' W2 X4 K: l8 v& E

  90. ) Q- V0 }! g; M; E: t" \
  91.   scl_low();
    . l7 N3 ?( H" D. p* ^
  92.   delay_us(50);
    1 [; B- ^9 o3 M0 H% j2 c. @& i0 E) r
  93.     }
    " e& t; J7 Q! H+ n; [
  94. // 9th bit acknowledge
    1 O6 s, H' d; T6 M
  95. if(u8Ack==I2C_ACK) {
    0 C* Z% B% s" O! @2 `5 l: y
  96.   sda_low();/ @2 I6 I% i( d- ^( V* g- [& o
  97.   delay_us(20);+ ^$ q+ u# O0 G9 G/ |1 K
  98. }     % g  p: }  A* v
  99. //I2C_ACK=0
    1 f  F4 v* i& _* Z7 q# l
  100. else {) C- y$ ]; e: ~
  101.   sda_high();
    * Z; X7 L3 A* H: d, P! ~! O
  102.   delay_us(20);) z7 Y+ ]9 c" H: F+ o+ d! F
  103. }/ ~" l( F; T0 G, v* y9 F" e
  104.    scl_high();4 `8 {+ L: L- V! I/ H' `' U
  105. delay_us(20);: G: C! P: A* i; K% E" A3 o
  106. scl_low();
    / t+ O5 x6 U7 U. S
  107. delay_us(20);9 F- Y  \2 Q- b2 l% N
  108. sda_high();
    ) B: d+ Z* r! {9 [
  109. delay_us(20);         1 ]: x6 c. b9 S" N8 V0 D
  110.     return u8Data;
    . b" o8 l. ]  `8 R- {
  111. }
复制代码

% J( v) m  u; f) K. F

i2c.h:

  1. #ifndef _I2C_H_INCLUDED4 E) p5 b: c* \3 F# l1 B
  2. #define _I2C_H_INCLUDED& X# B/ `* S6 {; ~0 V, H  Z: B/ J
  3. $ {' d( Y; {9 W1 r/ I! `
  4. #include "main.h"
    * h$ r1 w3 `5 C; j4 V: ~; d
  5. #include "Datadef.h"
    & q3 ]" V. z: ~" x; {( [2 Q0 U
  6.         
    # H+ d' F2 Q0 B7 |" _3 g  e; ~
  7. // #define I2C_CLK_HIGH()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);- N5 h4 {  D8 G3 q* {
  8. // #define I2C_CLK_LOW()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);; s2 y5 O, a2 U9 o: o8 S

  9. - @+ ^6 j) J3 Y  V$ a! n8 R
  10. // #define I2C_DATA_HIGH()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET);
    & B2 h: }6 R4 F( h  ~
  11. // #define I2C_DATA_LOW()    HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);  & I0 M( j( j2 o* {* r
  12. // #define I2C_DATA_STATE()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);
    ! j0 `# Z9 d: k% N
  13. ( E6 v, z* y, m4 e3 e. B
  14. // #define sda_high()  I2C_DATA_HIGH()     // set signals to HIGH first before selecting IN -> slew rates
    * \3 k7 Z  S( u7 V5 {
  15. // #define sda_low()   I2C_DATA_LOW()
    8 }3 c+ Q& ?9 P9 Q+ X2 r9 E# d* f
  16. // #define sda_read()  I2C_DATA_STATE()    //ack on bus is low -> u8AckBit = 1* O* C9 _6 G' }3 B7 y9 y4 |8 f

  17. 3 M5 W9 x. X2 ?( b! l! b
  18. // #define scl_high()  I2C_CLK_HIGH()     // set signals to HIGH first before selecting IN -> slew rates
    3 T/ B; A" D$ G7 [' F
  19. // #define scl_low()   I2C_CLK_LOW()
    & g. [4 j8 K" d% O
  20. 7 F8 v/ `' [" N& i5 d
  21. #define sda_high()  HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET);
    ' G5 D) c5 a8 ]+ l' n+ N
  22. #define sda_low()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);* ~- M; s4 U& l/ G. r- A! C
  23. #define sda_read()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);, U7 a0 B% z' J) k7 c" S6 _

  24. 1 d: z2 L7 H' [/ |; |  j% e
  25. #define scl_high()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);& j; m0 M1 Q4 Y# I
  26. #define scl_low()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);. `. p. c$ A+ U  ]
  27.                            P  a# g2 K) X; f  I. i* b
  28.                         
    6 k1 z) X0 L! K. P
  29. // ------------------------* j* G$ X1 @- {" ~/ m9 @
  30. #define DONOTHING()          {;}
    + ]. T: c& J+ d* ?
  31. / ?- [* z, c0 Q$ j
  32. // ------------------------7 o) u  g) Q5 F4 |& U. p  g
  33. // command's
    4 v4 F) E6 i9 p# Y% u# r7 M
  34. #define I2C_WRITE             0
    - w9 b4 J2 {* K: t4 N2 n; R1 u
  35. #define I2C_READ              1
    0 a% g0 @  g. j6 ?4 A. c
  36. #define I2C_ACK               0
    # V0 d. W2 Q5 U0 B. H% \
  37. #define I2C_NACK              1
    ) J: Z; Q% U$ R( N$ L

  38. : [9 f( g1 f4 @& n  I& L+ i
  39. void i2c_init(void);4 d& ^& b: ?6 C# D
  40. void i2c_start(void);
    & q, b! E1 I& T7 r0 u5 N: b4 m
  41. void i2c_stop(void);
    : g, ~8 T2 z7 b) X0 |" g4 g9 r
  42. uint8 i2c_write(uint8 u8Data);
    5 a+ P+ R% Q3 B/ L) v
  43. uint8 i2c_read(uint8 u8Ack);9 S# N( _- J# P7 z

  44. 0 t! J' ?4 l! z% Q
  45. #endif
复制代码

2 B1 p- ]( A: J1 |4 N

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

测试结果:


0 u. f, j8 |, E0 }4 j) T  m

微信图片_20230612191105.png

0 U! ?% Z& q5 e- ]& l

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

) r( ?$ L2 I4 Q& u& R

转载自:矜辰所致

如有侵权请联系删除
5 N: e( }9 }! @' U0 [# o  S


1 F- C6 O* ^4 R  a4 N$ U( D: J3 z* P  s
收藏 评论0 发布时间:2023-6-12 19:11

举报

0个回答

所属标签

相似分享

官网相关资源

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