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

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

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

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


( S3 G+ Q3 c, v+ J6 d! i; y9 ~

8 e- t' k5 B2 N0 [4 r 微信图片_20230612191118.png ( l  k% C7 R7 ~) ^/ l

+ y$ X+ a4 L/ w

7 d6 s7 z0 v4 U2、HAL库中的us延时函数
& o' n+ C, p$ f* u! e' ]

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

  1. /* USER CODE BEGIN 4 */
    ' z: r- g% P0 K8 u5 i2 \
  2. void delay_us(uint32_t Delay)
    8 c) j6 u( D# {, m/ d  @1 S
  3. {
    ' \3 w/ x- j; g  P
  4.   uint32_t cnt = Delay * 8;  
    1 N: k' @* ~$ k: P% t
  5.   uint32_t i = 0;
    7 V3 t  ^4 z1 i; r  L* q- X
  6.   for(i = 0; i < cnt; i++)__NOP();. H7 n. L+ n8 x! a/ u
  7. }
    " e2 w1 Z* g. w! |+ j# |
  8. /* USER CODE END 4 */
复制代码

5 J; z, F7 [( M  i3、移植I2C代码3.1  SHT21温湿度传感器

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

  1. #include "i2c.h"4 N1 p$ N: P- ~, n
  2. + n9 W0 t& p( a2 v0 X
  3. // ------------------------------------------------------------------
    & e0 U, |7 e+ G# l
  4. void i2c_init(void)  {0 h4 |1 }# e( R8 \' a* D6 U
  5.   4 u$ U, T% J0 e6 {
  6. // the SDA and SCL pins are defined as input with pull up enabled% N' l9 [: `5 l' z4 m
  7.   // pins are initialized as inputs, ext. pull => SDA and SCL = high# E3 n) q4 ], `6 e: s- y5 M
  8. # s1 S0 r2 \) k& ^: R4 c4 d
  9. }
    $ r3 V4 S/ k8 I
  10. // ------------------------------------------------------------------
    7 U: w* @3 l, P: _5 b
  11. // send start sequence (S)9 M& b2 J2 S2 L  i( r2 v, ?

  12. $ _8 i; N" J8 t$ J: w; K  r+ j2 s
  13. void i2c_start(void)  {                                    7 w* T* S/ M8 g. Y" T+ c, U
  14.    sda_high(); % g# k$ e1 \& D4 t
  15.   delay_us(10);
    + `1 T7 d6 q4 n; f8 _
  16.    scl_high();  ( n. |/ J4 z) ]( w& o+ c
  17.   delay_us(10);6 c) U+ E7 V* X. v1 a
  18.    sda_low(); ! g6 z8 a+ p3 e% q! K" J7 O0 B- i
  19.   delay_us(10);
    + q1 c3 |, A) w+ J2 U
  20. scl_low();                                                   
    . o! [% v9 R5 R5 _) E0 a
  21.   delay_us(10);7 e! z3 s: O( L! k5 Y
  22. }
    # N7 B# r# S9 b& L2 C
  23. // ------------------------------------------------------------------
    - b3 ]7 L1 |- c% s+ D
  24. // send stop sequence (P)/ o& d# a8 g+ v9 |6 b
  25. void i2c_stop(void)  {                             ( v9 r( ?$ C% h5 s
  26.    sda_low();                                                                            t- r3 X$ c3 L- v1 _
  27.   delay_us(10);
    ) M9 j" {4 q# ^$ |+ u- g, C
  28.    scl_low();                                       
    " a' t3 d3 ]0 r, H
  29.   delay_us(10);                                 
    * g; M4 Q( p1 B2 `/ s3 `/ Z4 s
  30.    scl_high();                                         
    0 b7 r! y. |, u, J9 E
  31.   delay_us(10);                                       + u% o0 B5 C. {+ |9 m2 k
  32.    sda_high();$ [8 o. D/ l1 P) J; ^+ s$ n
  33.   delay_us(10);5 J% Y5 A* I; P* c. `9 t  T5 U
  34. }
    9 A3 j* |2 N' f# A; I
  35. // ------------------------------------------------------------------
    & d! e4 h: ^8 q  H9 Q+ Y2 u8 |
  36. // returns the ACK or NACK
    * m  a( S  Z1 Q: }+ h: j8 V% I
  37. uint8 i2c_write(uint8 u8Data) 4 _7 i- @" L6 V. m9 U- `; r
  38. {
    % M% h8 l. b9 N, I1 j2 y% {
  39. uint8 u8Bit;
    , l( y( V4 d* v
  40. uint8 u8AckBit;
    ( k4 ?) d' `5 B: l& g0 |6 V; m- u
  41. // write 8 data bits3 a" _3 Q0 H+ F( \$ x. O/ g. u0 Z5 S
  42. u8Bit = 0x80;  //msb first  
    " l7 H& h2 N) m; u; _8 N9 y# V, R
  43. while(u8Bit) {
    * e  h% O; V; q/ o8 t
  44.   if(u8Data&u8Bit) {
    / r3 B9 K: g+ N9 q4 w$ u1 V: g
  45.    sda_high();' Z5 m9 N/ G$ o
  46.    delay_us(20);1 ~6 G; p# Y' ]6 `
  47.   } % \5 Y: d# C4 |4 n% A
  48.   //& compare every bit! Z7 F4 X- V+ W: g
  49.   else{ 8 v2 [8 i% u' S) F4 ~
  50.    sda_low();6 Q) f! `# m; o9 z, F/ J
  51.    delay_us(20);) v* b2 p( C4 C3 U8 i
  52.   }   
    8 p, i. ~+ j9 _* r" `
  53.   scl_high();
    6 ^( L3 k$ R7 n& z! W  @& T
  54.   delay_us(30);2 G4 [: |' w& a5 P" y3 [
  55.   u8Bit >>= 1;
    3 o* ?1 {) ^0 N; E9 L4 j; t: w
  56.   //next bit! @. S, x, [* y1 B$ f
  57.   scl_low();+ u% R+ [( R% \$ S( x
  58.   delay_us(30);8 f- K4 p6 I* M' J
  59. }
    ; F, G$ W& \, k
  60. // read acknowledge (9th bit) % H0 y$ I9 O6 t$ z
  61. sda_high();                                               5 _- q0 Y  Y6 i
  62. delay_us(10);  
    2 \3 y1 j& ]6 U
  63. scl_high();
    ! g4 }3 b7 ]7 ~  `  t6 H
  64. delay_us(10);  q( w% q% ]( V$ Y* l2 \, X% l
  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 SCSEDIO07 K3 A" U/ x4 @3 B" t
  66. delay_us(10);6 F8 W8 F3 q+ h
  67.     scl_low();                                              ' u' m2 \7 X  U' ?9 w
  68. delay_us(10);! I  Z" Y5 ~2 n' a( b! z( k
  69.     return u8AckBit;3 V9 x. ]! z/ w+ S6 K
  70. }
    + u. h: K1 t2 V6 M- X) G" S
  71. // ------------------------------------------------------------------
    3 ]; u- g( p; r- s
  72. // pass the ack/nack . w, o2 w' r/ L( L$ c$ S
  73. // returns the read data # p2 l) I$ v  V; S1 z  \4 Z3 r/ Q
  74. uint8 i2c_read(uint8 u8Ack)  
    $ ~/ c: ~+ t4 a2 ~* p+ X; L
  75. {
    ; H1 E! e" ~* X
  76. uint8 u8Bit;
    2 {! ^$ W" _# \
  77. uint8 u8Data;
    5 q& k# f$ ~) |+ P9 ]) k
  78. u8Bit = 0x80;       // msb first1 ^* |  |. }* `) O
  79. u8Data = 0;, A' f, d0 b" x
  80. while(u8Bit){$ J1 p. x) R; S5 H& q4 b; ?" Y$ M
  81.   scl_high();7 O0 A# e9 ~3 q" f
  82.   
    ' V! |: h: F3 u) J6 {
  83.   delay_us(20);' z. w, G' p7 _9 m; e2 V
  84. 5 k$ n( K5 j1 f6 H  j. y: e) w) k
  85.   u8Bit >>= 1;    //next bit
    ) n% x5 y) |  l* k, V
  86.   u8Data <<= 1;
    # S$ X* B" N4 m1 ?
  87. ( Z. e" Z) m; k5 P& i
  88.   u8Data |= sda_read();         //(sda_port & sda_pin)? 1 :0      sda_port gpio0   sda_pin SCSEDIO0
    / v; k+ M( f8 u6 p$ R' X, h9 f! Q
  89.   delay_us(20);3 P6 a! g2 v" u2 R8 B7 _) t+ u

  90. ' L( G) Y3 `$ ?+ ]* W
  91.   scl_low();$ h' a8 i2 \5 w' m+ d
  92.   delay_us(50);/ s6 l+ {8 u# y' {3 U  {- \
  93.     }
    6 Q$ }* ?/ d% F  E  B, e4 H
  94. // 9th bit acknowledge" {- L& n6 b7 {8 z  R- i
  95. if(u8Ack==I2C_ACK) {
    + M# Z4 w' T. s5 v
  96.   sda_low();
    $ M# N& d. o, D7 f
  97.   delay_us(20);$ B; t/ b! B5 q5 k6 R
  98. }     6 Q9 [& ^  n! \
  99. //I2C_ACK=0% ^2 K! S& H' z6 \
  100. else {, Z8 B9 ~: s/ m4 l
  101.   sda_high();8 N( {( l2 s- s1 }) w* ?% P2 ?
  102.   delay_us(20);. N) ]( m) {' s4 `$ I$ {: t' Z
  103. }
    / h  E: g+ u* v8 x( {5 {
  104.    scl_high();
    2 v! S- l* w- E5 R# a7 J
  105. delay_us(20);( i1 ~5 L4 @7 h, ^8 ]$ Q
  106. scl_low();5 e( }0 k- S' i2 s4 E
  107. delay_us(20);7 m& T  F; j7 I* V+ E9 i) _( i5 t& T6 D
  108. sda_high();/ y- a+ N+ P. o9 U* a
  109. delay_us(20);         8 P8 p, ]: j# c4 I4 v
  110.     return u8Data;
    * c" v/ t& x5 t* T4 t4 [2 q- z; D5 f
  111. }
复制代码

% _% z3 G" R* p# \' K

i2c.h:

  1. #ifndef _I2C_H_INCLUDED. d: d6 F1 N/ L7 ~! n
  2. #define _I2C_H_INCLUDED8 g$ i  ~6 ]& N& B* s/ r4 @" V
  3. - `; _3 F2 Q9 t1 N) A. m, P
  4. #include "main.h"
    1 f$ o9 A; m! ~; Y  j$ Y
  5. #include "Datadef.h"
    0 Z% |1 t8 m  a
  6.         ) Z  ]. w& M7 E2 D$ c# X
  7. // #define I2C_CLK_HIGH()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);
    , R$ d" v" I* M: k5 \, j1 y3 F3 P, ]2 d
  8. // #define I2C_CLK_LOW()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);9 b& X# @- m4 ]6 I$ ~# z( p
  9. 3 z: G5 ^5 }* P+ I' V
  10. // #define I2C_DATA_HIGH()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET);
    # o# j) v& k& l: S6 g& N
  11. // #define I2C_DATA_LOW()    HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);  
    % o+ i( }3 t' L% W9 s! b, X4 u
  12. // #define I2C_DATA_STATE()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET); ; B2 K1 e3 C1 C
  13. / h9 N& I7 n$ Y2 ?0 F; r
  14. // #define sda_high()  I2C_DATA_HIGH()     // set signals to HIGH first before selecting IN -> slew rates0 M0 R; l6 b' n: a
  15. // #define sda_low()   I2C_DATA_LOW()
    / B; U; L) R) r9 k( f, L
  16. // #define sda_read()  I2C_DATA_STATE()    //ack on bus is low -> u8AckBit = 19 D! u, d" @& [3 n, |& ^

  17. ( @+ j3 F8 s  g: D( O% |
  18. // #define scl_high()  I2C_CLK_HIGH()     // set signals to HIGH first before selecting IN -> slew rates
    4 Q! S# e* @" y* ]- |
  19. // #define scl_low()   I2C_CLK_LOW() 9 P7 @$ U' K  g* `( W

  20. # B4 Q# E) o" F/ N, d3 s
  21. #define sda_high()  HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET); . D8 C9 L7 D- o$ j) e5 S* z
  22. #define sda_low()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);
    4 }( e* w( s* F
  23. #define sda_read()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);7 Z4 j2 q0 J7 t7 S, a7 ^
  24. ) @+ C& S1 T% C
  25. #define scl_high()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);1 k( n. J/ u. s6 L3 j  |
  26. #define scl_low()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);! Z  `3 y5 M$ L4 z5 L  u7 c7 {: O' P
  27.                          % u; K" F1 ]) G0 F0 |
  28.                         
    ' g2 F* e# N8 o. O" l0 S; x& d
  29. // ------------------------) T4 }$ q6 e" D% F/ B& f4 g
  30. #define DONOTHING()          {;}. `/ b6 _# u( X' I) Z9 z, N
  31. 1 q' m: \( n* V# h# `
  32. // ------------------------7 R5 }/ v- m$ G& K$ F
  33. // command's
    9 g+ M8 B. @# W, ]2 C( U
  34. #define I2C_WRITE             0 5 n4 E# o  m8 M. q
  35. #define I2C_READ              1
    ) c0 S! V+ i( b5 C9 d: s
  36. #define I2C_ACK               0( d! u% I: R. _9 Q3 d2 y
  37. #define I2C_NACK              1& \0 R# U4 m) Z, L8 Z1 d, r
  38. . A3 M; _, K' B7 E1 v5 H
  39. void i2c_init(void);! n" @0 s$ x7 B% _0 q+ L3 x3 _9 D7 f+ T: \
  40. void i2c_start(void);
    % _7 @7 V! f& n: ]1 E7 |+ |: P3 i' p& F4 G
  41. void i2c_stop(void);
    - o, {! I' y' E& w* F1 m
  42. uint8 i2c_write(uint8 u8Data);
    : N$ R! V7 a% \5 f9 u% a2 \1 s
  43. uint8 i2c_read(uint8 u8Ack);# |+ M5 i2 O7 E" B
  44. ; |3 N& g7 Y, t/ {7 l/ \
  45. #endif
复制代码

" l4 a  F' F3 B* a

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

测试结果:

( v/ E0 M* d/ O. t9 |/ S

微信图片_20230612191105.png

( H; r: A' ?2 q# M) F/ @* ^

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

& t( d4 e) N( l0 `' \2 Q- L

转载自:矜辰所致

如有侵权请联系删除
9 T. i' B0 d( ~6 t

, n( w  V1 N& f9 a

7 X, L6 {: G  S0 w% n" J8 x( n$ |
收藏 评论0 发布时间:2023-6-12 19:11

举报

0个回答

所属标签

相似分享

官网相关资源

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