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

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

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

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

  o, M. A+ K! R9 p1 u

+ A- a- a$ l& p, A' a# |( J9 S 微信图片_20230612191118.png 0 O$ X- ?8 r# i8 j

. }# n3 P- u4 f

2 e+ X+ r" o6 f2 d, `5 S2、HAL库中的us延时函数
% {3 y0 ^) N5 K2 p+ k

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

  1. /* USER CODE BEGIN 4 */" O. |" p; V8 X; P
  2. void delay_us(uint32_t Delay)
    / a% I: V& J- i) M3 s( r, E
  3. {
    ) V0 D# f, E0 w! l
  4.   uint32_t cnt = Delay * 8;  - @; X$ l6 j2 N
  5.   uint32_t i = 0;
    $ B% ?, V" b+ ^" D; w0 U: Y: k/ T
  6.   for(i = 0; i < cnt; i++)__NOP();
    6 n7 {# h; @2 p2 j0 j  Z4 j8 g  C
  7. }
    # A" F2 P, k7 K- c! E
  8. /* USER CODE END 4 */
复制代码
& l$ {) ]9 q  I) Y. f
3、移植I2C代码3.1  SHT21温湿度传感器

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

  1. #include "i2c.h"
    : a& g) k1 O1 c2 g) c8 }0 Y
  2. $ H( C5 m8 W5 K0 r) F
  3. // ------------------------------------------------------------------
    / n) b7 b7 f8 x) y/ }% W
  4. void i2c_init(void)  {
    % e5 Z" d4 ?7 {3 d/ `; B' C6 x
  5.   
    9 S7 V$ E# \. L7 Z6 U+ m
  6. // the SDA and SCL pins are defined as input with pull up enabled
    , c  [1 @) E9 u6 {
  7.   // pins are initialized as inputs, ext. pull => SDA and SCL = high
    + g! a( ?( B* F8 P# m
  8. " R* l4 B6 _0 M* T- I% z1 D
  9. }& Q$ ]' q5 e1 I
  10. // ------------------------------------------------------------------
    3 J, [/ {, H% N* g6 n
  11. // send start sequence (S)/ L3 O. ^- e8 O" J
  12. 1 J! C$ V0 K8 {# X
  13. void i2c_start(void)  {                                    
    0 ]) O( ^9 t* F3 Z5 i9 A& G1 V
  14.    sda_high(); 1 a- M8 V9 {- E* C5 W: X
  15.   delay_us(10);: G- m$ v# G- N# N
  16.    scl_high();  
    , H1 x9 i7 t/ Q0 W# r& ^! }
  17.   delay_us(10);) |% m2 T5 g6 @6 }+ K
  18.    sda_low(); + j7 P+ J0 Z. ?: W
  19.   delay_us(10);
    ) c7 O  g& \, X( C9 e) `
  20. scl_low();                                                   
    8 Y2 e% v2 i7 R5 a) _% l* l. n
  21.   delay_us(10);
      J' R; J/ }' B
  22. }5 N3 g1 t* ^5 R
  23. // ------------------------------------------------------------------% j5 U, A  z* e2 Q
  24. // send stop sequence (P)
    7 `4 ^( l4 c4 j; Z. P: K1 V; \" F
  25. void i2c_stop(void)  {                             
    ! g3 f# L2 v* E/ ^$ d
  26.    sda_low();                                                                          
    + l) L. `$ p8 ?7 p/ V. {* k
  27.   delay_us(10);" U( K8 w5 c8 A/ n0 B2 U" b
  28.    scl_low();                                       
    & I2 ~0 W1 |7 x, C
  29.   delay_us(10);                                 
    4 g+ t- }$ u, B/ X) |: J: T7 E' z
  30.    scl_high();                                         9 ^. A+ H- B$ r8 O7 K9 R- x9 c8 B
  31.   delay_us(10);                                       
    ( H3 {6 D/ w1 p, @! i3 D2 R" K
  32.    sda_high();  H, b  h  ^+ O% T5 |4 v
  33.   delay_us(10);* `+ Z1 |# J" g8 v( b& w, o
  34. }2 L& B  K, n4 j
  35. // ------------------------------------------------------------------
    & I5 ~! G. j2 ^% L  x2 U% I/ A
  36. // returns the ACK or NACK6 H3 [  `0 u( q4 t1 x/ c# q
  37. uint8 i2c_write(uint8 u8Data)
    4 i! p1 b( w6 R2 ]
  38. {" U7 L  B+ q& S- t! q: y9 L
  39. uint8 u8Bit;/ E- f: O  a& T- G4 X  |% I" j
  40. uint8 u8AckBit;* w9 W- e% j3 A' @* \+ p& S3 Z
  41. // write 8 data bits
    ) V+ Y8 G3 J1 C. g9 y: o$ D
  42. u8Bit = 0x80;  //msb first  
    " M. d, y: I7 r$ D" \% p+ A) s
  43. while(u8Bit) {
    / N7 P8 f- L: ?. Q/ K
  44.   if(u8Data&u8Bit) { & B( ^% P. Y5 `, F# b! _. v
  45.    sda_high();
    % l0 |9 G% M/ ~
  46.    delay_us(20);
    6 K6 D2 Y6 r5 A& E, g  b, B
  47.   }
    , s& R  H% e2 D8 a" u% z# P
  48.   //& compare every bit) B, |$ w, q% Q8 F7 Z: ?
  49.   else{
    : v& k/ ^7 p8 S
  50.    sda_low();
    8 \2 c/ d" `0 y/ f' W9 C( r  J- q
  51.    delay_us(20);
    % D0 d5 G6 `9 U; O8 _
  52.   }   # z  R/ V1 N0 [, ~" e- k: ?
  53.   scl_high();5 F# F' b" B: N
  54.   delay_us(30);
    $ z% o% ?) Q+ ]; @. ?
  55.   u8Bit >>= 1; ( o1 }% G7 R, D) q2 C2 J  W9 b
  56.   //next bit) J* D) s$ U$ G& r& b7 n; _
  57.   scl_low();! s# C& ~/ v, f2 i' O+ c! M
  58.   delay_us(30);
    6 Q! ]+ i' y) U9 _' {: m! }3 S9 S
  59. }- ]3 o! U1 ?* t6 \7 w
  60. // read acknowledge (9th bit)
    " T) D/ e  g+ d( D& g9 e" V
  61. sda_high();                                               . |& ^& I0 ~6 G' F. C
  62. delay_us(10);  
    ( x: R9 A$ U& C: |' \8 p" [
  63. scl_high();' Z, k$ [6 k  v  ~& W' I7 ?
  64. delay_us(10);3 K7 a  x5 a1 Z& L9 Y. g  X& b
  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
    * m0 D( l& j0 M. [- U
  66. delay_us(10);4 J# j7 e5 l7 {, A4 G( z
  67.     scl_low();                                             
    " J) a9 n3 o0 [
  68. delay_us(10);2 o2 H8 n" E# z  Y7 v" O
  69.     return u8AckBit;/ E& Z* r% c8 F8 H9 U. n& q! x/ {
  70. }
    3 \: q! p" t( v% J1 L
  71. // ------------------------------------------------------------------
    4 F6 `+ _" g8 X& }* P* y- t9 u
  72. // pass the ack/nack
    : i! k5 X) Z( `2 n$ K
  73. // returns the read data
    4 U+ ~; V- B8 V% l. X3 e$ K9 n
  74. uint8 i2c_read(uint8 u8Ack)  
    ; u1 V* r9 K: w& T; c; ~
  75. {
    . G: U$ @# G* f9 ]- W
  76. uint8 u8Bit;
    # x5 Y( f* `8 X1 |# k, i5 j$ U) |
  77. uint8 u8Data;, k  X: t2 X& e3 e
  78. u8Bit = 0x80;       // msb first
    / n& |! P% s9 `7 `
  79. u8Data = 0;/ g9 ]3 D7 e+ d3 B9 L& T& J# ]6 E
  80. while(u8Bit){
    : c( z4 X5 `& ]; |4 `+ [
  81.   scl_high();
    9 F" s% G1 i( b' `0 |7 j, L3 Z
  82.   
    / a1 l/ i( B: D2 e# t
  83.   delay_us(20);
    ( r6 s/ ?9 u/ ~& K6 t5 i1 u
  84. . O! T  b$ x, v* Z+ K
  85.   u8Bit >>= 1;    //next bit* U9 n3 W) N' s
  86.   u8Data <<= 1;
    0 n, L2 J0 B' z' q: E( Y9 e

  87. " \- X4 o0 m( \4 j0 ^# o$ D
  88.   u8Data |= sda_read();         //(sda_port & sda_pin)? 1 :0      sda_port gpio0   sda_pin SCSEDIO0; n: n9 W% l# j9 x
  89.   delay_us(20);' o. |! A# p( e. j3 c8 m$ t

  90. ' S" f9 S5 u; ~, o( n; C
  91.   scl_low();
    * K5 ?5 {- Y9 \( u2 G
  92.   delay_us(50);
      l  j% ~, h( r5 _$ U7 l
  93.     }+ J3 b' h! d% Y5 Q# I8 C4 |
  94. // 9th bit acknowledge' \6 h: H* d7 \7 W& z- r3 i
  95. if(u8Ack==I2C_ACK) {
    ' \4 Q' G+ A8 L; n( P; \3 {+ [  P$ Z
  96.   sda_low();/ X: ^8 O6 ^/ r4 `) M8 S
  97.   delay_us(20);
    4 Q5 W/ u; y! M( `0 ~
  98. }     
    5 }& [% m" {; b! s5 n
  99. //I2C_ACK=0
    ; w0 i" U. j8 Z: I
  100. else {
    $ Q& {& d( m, }6 V1 B+ e
  101.   sda_high();6 @: S5 {$ i, E4 Z/ ]+ J: M
  102.   delay_us(20);
    ' E; F! S; o4 S* F0 M0 W
  103. }
    : W* c6 {0 K$ r& r$ n
  104.    scl_high();5 \* m3 q2 d* j& h; s) O
  105. delay_us(20);% C: v. T& q  u
  106. scl_low();
    / y: B7 h& b$ ~! }, E7 c
  107. delay_us(20);
      o  y' [: O7 l* w# j
  108. sda_high();
    : v4 m  m4 k- f$ L7 c' s6 U$ R
  109. delay_us(20);         
    , L# `: D5 l" O2 n
  110.     return u8Data;
    0 Z1 u: }  K0 d# g  F$ c# Z
  111. }
复制代码
6 H* S( V" F' n& t( H: W! i

i2c.h:

  1. #ifndef _I2C_H_INCLUDED
      j: T* }" o4 ]
  2. #define _I2C_H_INCLUDED
    & g/ ~% c$ l, O/ a: ?+ V) t7 }
  3. 8 D* e6 a5 a, s
  4. #include "main.h"" E0 `0 }/ N" s* I! Y3 e4 \5 T
  5. #include "Datadef.h"
    - ?( _, G8 m2 |
  6.         + d$ B! P; h  F3 o0 h
  7. // #define I2C_CLK_HIGH()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);' X) {+ T3 A  v  \0 N2 |
  8. // #define I2C_CLK_LOW()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);
    - D# i( Q+ A! k) p

  9. & g7 Z; x& Z5 a# @
  10. // #define I2C_DATA_HIGH()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET); " j7 L8 z) O- E9 O7 U
  11. // #define I2C_DATA_LOW()    HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);  
    8 F( b& F9 p: B1 ~
  12. // #define I2C_DATA_STATE()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET); / G3 x- q9 Y+ G: T3 s; u6 L( }+ ]

  13. + b* ~* r% d. Z5 H. n& ]5 _
  14. // #define sda_high()  I2C_DATA_HIGH()     // set signals to HIGH first before selecting IN -> slew rates
    ( \6 C4 Z5 \  r' j2 Q/ y* n+ Z5 X$ n; V
  15. // #define sda_low()   I2C_DATA_LOW()
    2 d& |2 E9 ^+ D
  16. // #define sda_read()  I2C_DATA_STATE()    //ack on bus is low -> u8AckBit = 1  h3 W$ H$ l% N0 u; b% q

  17. % \1 I# k  C/ n5 [6 ^/ `
  18. // #define scl_high()  I2C_CLK_HIGH()     // set signals to HIGH first before selecting IN -> slew rates
    , G. n! V! j2 b
  19. // #define scl_low()   I2C_CLK_LOW() ' ^# k% ^( Z1 q( W- W6 }6 U

  20. * S! O; @& d  q7 s
  21. #define sda_high()  HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET);
    ' U1 E7 g1 G4 @& u- t& @
  22. #define sda_low()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);
    5 G, [5 j3 Y% x' @9 d# ~
  23. #define sda_read()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);
    4 s4 `1 h5 V4 v+ s

  24. 7 t4 a5 }5 k% s3 Q2 s0 N5 C
  25. #define scl_high()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);
    7 o$ n" t9 h1 p3 t. F, S8 s
  26. #define scl_low()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);
    5 c4 k7 k, j; Z+ x$ K2 \; j5 |# d
  27.                         
    : b8 `% v. F2 |
  28.                         
    * S. x# k+ l0 ]0 U4 {$ |
  29. // ------------------------) t# Y! z# y/ y
  30. #define DONOTHING()          {;}
    8 W) H4 j; [" c! }- ]7 H. J
  31. ! p4 p, b2 A+ `* z: b- D" `; i
  32. // ------------------------  W+ c4 P* f& A% c) j" M
  33. // command's5 S& E5 ^4 ~& c& z' o
  34. #define I2C_WRITE             0
    $ c  A0 l4 P+ G, B% I* a1 @* D
  35. #define I2C_READ              1- @$ [) r, \8 q: }* k
  36. #define I2C_ACK               09 o; n+ z# e( ^) z& Y6 c0 r
  37. #define I2C_NACK              16 j! o( i7 P3 A
  38. # |  H& X  [) E# @* K: d
  39. void i2c_init(void);
    ) S& T3 x! T4 V, F: c- y
  40. void i2c_start(void);
    # q: @) C3 m* }& i
  41. void i2c_stop(void);/ j% D1 [5 N$ R2 V7 p" q+ O- U
  42. uint8 i2c_write(uint8 u8Data);% a$ ~" w' k+ w5 C+ o2 }
  43. uint8 i2c_read(uint8 u8Ack);
    - w+ w& b* m3 b. M

  44. % D+ ?9 E9 t8 F1 P. W
  45. #endif
复制代码

5 I8 d9 }/ S+ H9 @8 m% D

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

测试结果:

  F/ o9 M3 s3 v! {# k

微信图片_20230612191105.png

1 X* @. j* C" O

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


* g$ y( Z& x* s& D

转载自:矜辰所致

如有侵权请联系删除0 A* u& V5 a* H8 A- l" l* o

! s- M8 V8 ]- u( U1 d$ O' q
: y; c4 D0 M6 j7 `1 @7 N
赞 收藏 评论0 发布时间:2023-6-12 19:11

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版