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

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

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

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


! c/ B: M7 ~+ d* @, L
+ X# R+ e# y- n# ?) p; a3 d
微信图片_20230612191118.png
0 b  [$ V7 G4 v6 D8 T2 u, U6 `) \2 X, l) {+ L: Q4 l4 ?
% j* I. u% f+ ]
2、HAL库中的us延时函数/ S& r& I7 H0 r# t: @0 A

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

  1. /* USER CODE BEGIN 4 */, M) q* @* Z) n
  2. void delay_us(uint32_t Delay)# r  Y9 S4 a2 f
  3. {: y/ X; i2 J. M/ c
  4.   uint32_t cnt = Delay * 8;  
    / H1 Y, l2 a7 P( ~' a+ U& L6 P  ]
  5.   uint32_t i = 0;
    & \; @% W/ O0 ~% ~4 I( \7 F2 P
  6.   for(i = 0; i < cnt; i++)__NOP();6 ?% |& q) [% [1 ?
  7. }8 ?: d: r3 E+ d6 w( D; ~2 H
  8. /* USER CODE END 4 */
复制代码

' q8 g, o* g6 j, k3、移植I2C代码3.1  SHT21温湿度传感器

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

  1. #include "i2c.h"/ m7 N6 H# ^! b* K( L

  2. 0 h* c* ], W; p% Y
  3. // ------------------------------------------------------------------
    . k/ r: l: L9 ]/ J+ g" {  k/ u
  4. void i2c_init(void)  {
    - U2 g7 ]1 U5 \/ @  ]* p
  5.   
    9 E4 L8 {/ L0 M3 G
  6. // the SDA and SCL pins are defined as input with pull up enabled
    ) a/ n6 K) @% x$ I, ^
  7.   // pins are initialized as inputs, ext. pull => SDA and SCL = high
      B4 T" L* }$ v
  8.   ~% u/ _) R  W
  9. }
    : w. G' t% D+ G, O& Z
  10. // ------------------------------------------------------------------1 c; c+ o' |% _- [, H! m
  11. // send start sequence (S)0 m+ r1 Q' I' R/ c# g
  12. ; \1 U$ n* ]2 G$ e( x7 V4 _
  13. void i2c_start(void)  {                                    
    9 p2 f* _0 M3 T* L5 y$ J; x& y7 f" E# H
  14.    sda_high(); - t) l; N7 A5 z) h- L
  15.   delay_us(10);& o( y$ L) q3 L* i' M
  16.    scl_high();  
    5 T- j+ [6 ]5 A& O  `
  17.   delay_us(10);$ h* r7 u5 ?5 t" K6 M' x* ]
  18.    sda_low(); 7 f3 C2 C5 [" Y; h6 z0 [5 e; c9 U
  19.   delay_us(10);( r5 k- b% a( x" f
  20. scl_low();                                                   
    1 {% u8 H8 A9 |8 x& b$ p+ Q
  21.   delay_us(10);
    , X; n, V* X/ s* Q$ A
  22. }# a' w( r8 D* q! r' k" {# c
  23. // ------------------------------------------------------------------* o# N' ^. n7 G4 R* _) l7 K  H
  24. // send stop sequence (P)
    ( d6 R+ K; d( v5 Q" b6 H# ?
  25. void i2c_stop(void)  {                             
    . |9 P+ p! v) t9 h
  26.    sda_low();                                                                          
    ' @2 n6 F* _4 N8 q0 c0 X
  27.   delay_us(10);' ]1 H# e' M/ H% W: P
  28.    scl_low();                                       
    . a, @3 o5 W( G9 ?7 F. i7 a$ i9 U
  29.   delay_us(10);                                 : ?' s- Q: ~' i8 Z
  30.    scl_high();                                         
    , E8 F" n' M( d
  31.   delay_us(10);                                       & ]$ K% h7 x$ f- E, _
  32.    sda_high();* O* c. b" F, r$ F3 `$ Z: o
  33.   delay_us(10);
    $ U% U% d1 \8 O# ]! x0 r
  34. }( X7 o* O# f- |
  35. // ------------------------------------------------------------------
    0 G% I% ?% |4 I  D$ }3 Z+ J
  36. // returns the ACK or NACK5 x% g8 Y' Z  F2 K. r8 u6 b. S
  37. uint8 i2c_write(uint8 u8Data) + r& h6 L1 w2 A
  38. {8 J0 ^/ X* b$ r) e6 k
  39. uint8 u8Bit;
    " Y0 X2 H" W& t8 |4 x
  40. uint8 u8AckBit;
    ! H5 S" t, R4 B, [+ W- c- O# M
  41. // write 8 data bits0 y/ Z6 I  `$ {' N: }8 Q
  42. u8Bit = 0x80;  //msb first  - Z( Y4 u5 |* ]8 t; Y
  43. while(u8Bit) {
    1 p7 m* P* P  w/ |
  44.   if(u8Data&u8Bit) {
    " {! i* v9 f3 x$ e  G
  45.    sda_high();
    1 X! t" C  L# q/ z
  46.    delay_us(20);/ q" G$ L" W7 H& Z
  47.   }
    ; U. s$ p0 B/ ^# _  y
  48.   //& compare every bit: E' F: @$ l/ N
  49.   else{
    5 [" G8 I' i7 z1 ?# X
  50.    sda_low();
    * W1 l. x  Z+ Z" o, e/ \* I
  51.    delay_us(20);+ J7 M) P0 W. K/ ^
  52.   }   7 y+ Z/ _( W. L/ q- r# |
  53.   scl_high();
      I3 L9 \( S9 v
  54.   delay_us(30);
    / C+ ?. F3 B* s6 W$ u/ i: N7 K
  55.   u8Bit >>= 1; 7 r/ p1 Q) h( r
  56.   //next bit
    " {6 C, s4 }2 a7 D3 q: I0 \' {
  57.   scl_low();3 P1 h8 n3 K7 l- }
  58.   delay_us(30);9 r! W: y( g1 p2 C( h3 C
  59. }7 g) P& }+ u$ z+ D3 j: B- r& P( Q! o
  60. // read acknowledge (9th bit) $ C) ~& {2 ?7 O6 o
  61. sda_high();                                               ; P# f4 r, X- K+ Z5 |* G. ]
  62. delay_us(10);  
    , U% V4 |" _/ I
  63. scl_high();5 \( O: ~' _2 r; f
  64. delay_us(10);% }9 z0 E7 F+ Z+ ]' A
  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 SCSEDIO03 J  ^. P% Z' n3 i8 I) d; i* u; ^
  66. delay_us(10);
    + W6 ?, v( L6 ^+ z- n+ A  q
  67.     scl_low();                                              3 g% w8 {7 d6 y" n
  68. delay_us(10);
    , j9 p$ U6 f5 m' @9 o
  69.     return u8AckBit;2 X" B3 F9 r7 ~
  70. }. e* Q8 a, |+ v9 Y! y; T+ }
  71. // ------------------------------------------------------------------& o' ?- O4 k$ f6 O  @
  72. // pass the ack/nack
    0 L" E$ f  l& E/ S2 C! a  b
  73. // returns the read data 4 N: V; _4 e5 M9 }! p! N% b
  74. uint8 i2c_read(uint8 u8Ack)  
    1 p/ X- j* Q/ u2 \2 P4 F5 O
  75. {
    ; ?7 g+ p# q( e! e) E: [
  76. uint8 u8Bit;1 k/ e% t8 I, ^8 Q
  77. uint8 u8Data;8 N, x. d$ }, {/ F! K. Z
  78. u8Bit = 0x80;       // msb first) d  ?( s+ d3 }% @) L' p
  79. u8Data = 0;) O. `5 H! p3 }1 c
  80. while(u8Bit){
    5 g. G/ w$ J$ j6 K8 X: {2 L" g
  81.   scl_high();" f7 x8 v3 W0 [
  82.   
    # m: ^0 A4 }& |9 P
  83.   delay_us(20);
    % x& i: [* s# E4 L

  84. ; k0 F- U8 l5 M3 B
  85.   u8Bit >>= 1;    //next bit
    : Y; H; _  s% F$ ^' v+ B* ?7 R7 o
  86.   u8Data <<= 1;
    , U$ z* M7 Y7 u  |  i" z# u
  87. # g3 s2 l8 V( N8 s
  88.   u8Data |= sda_read();         //(sda_port & sda_pin)? 1 :0      sda_port gpio0   sda_pin SCSEDIO0
    - O9 b, I+ e/ R/ n' `( o2 C0 l
  89.   delay_us(20);, H# X, t9 x* E2 o# ?4 Q1 @% J: ?
  90. * S: }: t6 B( |
  91.   scl_low();# B! o$ \) B" j
  92.   delay_us(50);6 r& F, A  p2 n: M
  93.     }  V: _) j. J9 U! Y5 h
  94. // 9th bit acknowledge
    8 C  m' X+ {6 G8 H1 R7 ^* h+ z5 R0 S
  95. if(u8Ack==I2C_ACK) {
    ) M1 I$ l2 F! {! q4 w' u( C! n
  96.   sda_low();  M8 L0 \3 A1 o  C
  97.   delay_us(20);
    ; Q, O. d& a% r3 L* x: e5 H3 J
  98. }     - O. i2 Q, N. w9 ]. G2 H! ~, x
  99. //I2C_ACK=0& [" C. V8 u8 o9 ]6 k
  100. else {
    6 F8 y: H& v" |' j, ]; j( A
  101.   sda_high();
    * ~5 E7 M8 A, }8 G. I
  102.   delay_us(20);9 U/ e  F1 t9 T, [) ]. n! l
  103. }/ Y' s5 P7 W# U. j0 P
  104.    scl_high();
      N9 R; U3 E. g
  105. delay_us(20);4 H5 P2 j" z- W
  106. scl_low();
    0 h& X4 J9 {; W, p% t2 E
  107. delay_us(20);0 U( |$ d, l% p/ X1 M& l
  108. sda_high();. O8 |' ~1 h, ^4 r
  109. delay_us(20);         
    . r! [+ r$ x" Z4 `# a
  110.     return u8Data;( n$ v( S9 B9 y: R
  111. }
复制代码
# j1 v/ R# O- z/ T3 F

i2c.h:

  1. #ifndef _I2C_H_INCLUDED
    ' \& N! J" f, ^
  2. #define _I2C_H_INCLUDED
    ; W% x4 N& |( z: }; Q

  3. : o/ C( V( i1 I# [
  4. #include "main.h"7 z7 ]: K/ n4 ]: q2 ^
  5. #include "Datadef.h"
    + k3 I1 N/ Z* @
  6.         0 E  R+ b% Z& N5 Z' V2 `
  7. // #define I2C_CLK_HIGH()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);: C# Z, p6 g7 E/ m8 u, C- R# o3 [
  8. // #define I2C_CLK_LOW()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);
    2 I8 I* w7 B$ n5 {5 D- ^

  9. ( `' N: y* W7 l4 @( \/ M
  10. // #define I2C_DATA_HIGH()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET);
    & A. z8 b1 ~. |! s: c! M
  11. // #define I2C_DATA_LOW()    HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);  / C% u5 x- a2 P( \
  12. // #define I2C_DATA_STATE()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET); 2 T( g( B5 h4 ?+ p/ y2 E

  13. - a, G. x$ k" ]3 L1 r
  14. // #define sda_high()  I2C_DATA_HIGH()     // set signals to HIGH first before selecting IN -> slew rates
    ( ?7 ]3 g2 a" t$ k: e+ c, \3 m" u' u0 D6 z
  15. // #define sda_low()   I2C_DATA_LOW()
    " @7 w8 Y0 v0 r/ o. x. n& [# `
  16. // #define sda_read()  I2C_DATA_STATE()    //ack on bus is low -> u8AckBit = 1! R+ ~2 h4 _# u. v3 `; U

  17. 7 \9 o3 M) D  B0 R: b; N' x
  18. // #define scl_high()  I2C_CLK_HIGH()     // set signals to HIGH first before selecting IN -> slew rates: f: s% B% \6 c8 s& V/ |4 L
  19. // #define scl_low()   I2C_CLK_LOW() ' }2 d" s9 b, K! B% j' }
  20. - y) X2 U& v* q' a
  21. #define sda_high()  HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET);
    ( D; x2 U+ j2 J0 Q: E9 w% ^
  22. #define sda_low()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);
    ! D( l  j$ j* u* ]4 u+ N
  23. #define sda_read()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);: V. z6 ]% }1 x) r
  24. 7 ^( k( m6 t* K1 ?5 Y  ]8 R9 J
  25. #define scl_high()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);0 L, ]" s$ f: f. [- l
  26. #define scl_low()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);
    . }8 s4 |5 ?/ B, N( ~) L
  27.                          0 S5 a3 g3 }* V# {/ q' e
  28.                         
    1 ?" [" ?$ u: [+ O
  29. // ------------------------
    ( I# D: ~7 y& P, f' M6 C$ Z
  30. #define DONOTHING()          {;}) i8 U# K, f7 p6 P* o

  31. ) Q; [. R1 C5 @& a; Z3 X
  32. // ------------------------
    ) A- r" w  _( A* v" c5 M
  33. // command's' Q+ M; p- P! Z1 L
  34. #define I2C_WRITE             0 7 R3 |0 {  @& Z1 j! }8 ~4 A
  35. #define I2C_READ              1! E; E" H+ D. ^: E  x
  36. #define I2C_ACK               0
      s, C7 E. r! t4 {- b7 Y6 t
  37. #define I2C_NACK              1, X+ _+ _& v8 t$ t4 K. V/ E# B

  38. 3 v3 f3 f* p% n, D. K# a
  39. void i2c_init(void);* G* V! D2 g5 t) r4 ]2 G! M0 ?
  40. void i2c_start(void);7 G0 E( c2 j! M! p) l9 W" Z
  41. void i2c_stop(void);
      A' H2 ^0 n2 k. D4 z
  42. uint8 i2c_write(uint8 u8Data);& L, k; h7 p9 W4 V
  43. uint8 i2c_read(uint8 u8Ack);
    $ R: n# G: y* \# S3 O

  44. 6 |' N  O" i7 y, O; o5 j
  45. #endif
复制代码
9 |0 _1 O# T7 b6 ]+ }

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

测试结果:

4 q9 j" @: R6 e

微信图片_20230612191105.png


7 Q+ o+ D; x$ W$ z5 F5 b

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


& J* @6 d1 |) g8 `' M8 Z

转载自:矜辰所致

如有侵权请联系删除: f4 u/ o7 x, D+ O$ j, A2 y# ^. x

" B+ P5 O4 s$ \- Y% s% l# [' l
, n" L! e( W* j3 X8 i
收藏 评论0 发布时间:2023-6-12 19:11

举报

0个回答

所属标签

相似技术帖

官网相关资源

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