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

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

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

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

! d% o" F3 X( S: x

& ?' J1 t  [* i  O* Y9 G( m0 L 微信图片_20230612191118.png
3 E& L7 f+ b5 h) W8 ?5 @" [0 O! B) p5 q4 w/ V# p
8 z) _5 F5 x; H' y
2、HAL库中的us延时函数5 F" h7 l9 r; V  J7 y0 g1 O

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

  1. /* USER CODE BEGIN 4 */
    % ~/ o1 I0 i" X$ U5 ~
  2. void delay_us(uint32_t Delay)
    - z# |/ m  D$ ?, V5 b4 G$ ~
  3. {0 K0 H- V) B. r2 p( m
  4.   uint32_t cnt = Delay * 8;  ' v2 \. d, s, X5 N
  5.   uint32_t i = 0;
    3 o7 G+ ^- q5 n. r5 V: [. _
  6.   for(i = 0; i < cnt; i++)__NOP();  B! _4 s! u% i  _% p# ~
  7. }
    " N8 t$ L, z* q/ `( m
  8. /* USER CODE END 4 */
复制代码
, w; N: v& H/ [, j" {4 A& h
3、移植I2C代码3.1  SHT21温湿度传感器

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

  1. #include "i2c.h"( e( G) \. o% L0 |

  2. / j; I. E- S6 o. s
  3. // ------------------------------------------------------------------
    0 D- p5 z7 K( {) P5 S$ g8 f
  4. void i2c_init(void)  {
    4 {+ F2 F/ J' h$ q
  5.   
    * ], s6 n$ C$ E6 T# s4 N
  6. // the SDA and SCL pins are defined as input with pull up enabled- V0 X; G1 b2 |
  7.   // pins are initialized as inputs, ext. pull => SDA and SCL = high; D7 n8 s) R0 |: p
  8. : n2 J+ U/ D  O
  9. }
    8 s( [$ y8 p6 R% E! Y8 D" J$ v
  10. // ------------------------------------------------------------------  R, R3 T$ n' u0 U' s( J4 g6 E
  11. // send start sequence (S)
    3 N- R% O2 {+ e% ~8 T
  12. 4 Y4 ~+ k1 Y0 q% T
  13. void i2c_start(void)  {                                    : J9 F% l5 J, B+ E$ h2 e( D+ m
  14.    sda_high(); ) z8 d8 a$ t7 q
  15.   delay_us(10);/ J9 `% D1 W' G* q
  16.    scl_high();  
    3 k' @4 b# E; ^7 [- e5 d
  17.   delay_us(10);6 H. i+ }9 u$ I  f  R
  18.    sda_low();
      k& ~2 s. n3 S! t( M
  19.   delay_us(10);
    ( F' u7 `1 @7 C6 V7 e5 t
  20. scl_low();                                                   % v% s( z/ e! x7 f' G
  21.   delay_us(10);
      q. L+ u$ Q* l$ v# D0 E8 K
  22. }
    * z/ X: s! A) |; P
  23. // ------------------------------------------------------------------
    ' d8 p* H/ U9 C! _1 T
  24. // send stop sequence (P)
    , h$ o: r) X0 x3 I, {- }; _
  25. void i2c_stop(void)  {                             0 t* K+ D7 q% D; p
  26.    sda_low();                                                                          8 V8 |, b% W7 t0 z( Y. M& {; S* M
  27.   delay_us(10);5 d3 @" q. r; J0 X* z
  28.    scl_low();                                       
    + P: |# o& q" X# L1 r/ j
  29.   delay_us(10);                                 
    ( s) i- ^4 E! H$ Q7 B6 j6 A
  30.    scl_high();                                         
    + p3 z# o7 P% Z* O0 Q* v6 ], w( V
  31.   delay_us(10);                                       0 W) `7 f% Q( ]0 T
  32.    sda_high();: H: B8 V, J* m0 ~
  33.   delay_us(10);6 v' h  }' |1 d6 f! E
  34. }5 u$ J$ c7 I6 X) D6 }! X% e3 y: q
  35. // ------------------------------------------------------------------) @1 Y  ?! e* e. I5 t* B: P
  36. // returns the ACK or NACK
    $ l" t( n' E3 H
  37. uint8 i2c_write(uint8 u8Data)
    ; T8 I! C  Z8 H
  38. {* ]& d1 `9 h, C
  39. uint8 u8Bit;
    $ @$ H' B- e" N' U% r# W; s
  40. uint8 u8AckBit;
    5 r: w4 c6 L" L. I
  41. // write 8 data bits* I4 a  S/ q9 |7 U/ j' I
  42. u8Bit = 0x80;  //msb first  
    & Z; L( Z$ }6 o+ ^8 A$ {5 N% c
  43. while(u8Bit) {! ~& h: X- z4 N2 h' ]& O
  44.   if(u8Data&u8Bit) { 6 U) ]/ {* g  _
  45.    sda_high();( \) z$ x1 W( ^
  46.    delay_us(20);
    % ?7 u/ [* f8 Q  f4 e# {( k
  47.   }
    + S9 j& l/ a$ ], ]* q
  48.   //& compare every bit2 X* R$ I. R  }: Q3 V
  49.   else{ ; E+ P8 {! \* v: e6 p' Z  S
  50.    sda_low();
    ' H$ I1 D4 d3 L
  51.    delay_us(20);8 m: ~* W, i) C; L3 _& [
  52.   }   
    7 w, B3 _' |1 m* {- u
  53.   scl_high();
    9 d9 W: E5 [& y& g2 I( ~" h
  54.   delay_us(30);4 B. b' Y% \2 `+ v' O: J
  55.   u8Bit >>= 1; ; m+ W" c. l* Y
  56.   //next bit
    % J" y7 H7 A* A# {) u# z2 M* c3 {
  57.   scl_low();
    % _, s" B$ d% ]; T9 v5 Q
  58.   delay_us(30);+ G; N6 o' P: m8 n
  59. }
    7 [/ f9 Y7 }4 U; Z; O( m7 P' Y
  60. // read acknowledge (9th bit) 4 g" d, @' w! z4 j" K
  61. sda_high();                                               7 s- v( @1 H3 m% E; S
  62. delay_us(10);  
    $ D, S0 b5 {5 b0 W- Z5 @# c/ x
  63. scl_high();2 \* q0 t2 I% ^4 P
  64. delay_us(10);5 `1 S+ h( a6 S( o
  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. }: L1 O+ ^/ q# [. b
  66. delay_us(10);4 j1 C' R; P& t; e. {0 P
  67.     scl_low();                                             
    3 }6 ^/ p& @: h
  68. delay_us(10);
    " s9 M0 M! C9 {9 Z4 z
  69.     return u8AckBit;
    ; G; ?7 k) A1 j1 M
  70. }1 c) L. d8 u' B$ L( T! d- q
  71. // ------------------------------------------------------------------
    ' ?8 ]! r7 T, l5 Y2 v  V
  72. // pass the ack/nack
    & h9 m& ]3 m0 Y1 H: i9 u$ z
  73. // returns the read data
    # |% M0 z; V& d5 N0 O, ^3 n- w% D/ }4 @- a
  74. uint8 i2c_read(uint8 u8Ack)  
    / T& c* u1 n8 W  F. r" ?
  75. {: J; V& p) [$ I4 Y
  76. uint8 u8Bit;* J1 A  d; k# a: K
  77. uint8 u8Data;8 ~8 U' Q& \6 b, e6 J
  78. u8Bit = 0x80;       // msb first) r8 ]2 [) [. L& ?/ ^- [% u' d
  79. u8Data = 0;/ z1 Q* g# G, @# @# x
  80. while(u8Bit){
    2 x; q" t" ^* `# h/ d
  81.   scl_high();/ n9 h9 n* @4 a0 d/ P- W+ u
  82.   
    5 S, ?1 I  h1 ^8 M) B2 I
  83.   delay_us(20);' e2 [8 s8 @) D, n0 {# Y) T
  84. 0 Q3 u: s' B2 }, _& z
  85.   u8Bit >>= 1;    //next bit
      B9 m- _( U- P# t1 X9 F$ W% W
  86.   u8Data <<= 1;
    ) G& a/ V( Z" r/ ?8 C
  87. + z- e0 E8 d8 g9 U; P* g$ J
  88.   u8Data |= sda_read();         //(sda_port & sda_pin)? 1 :0      sda_port gpio0   sda_pin SCSEDIO0
    + J3 S* L; T. A7 n% a, i* \/ p& _+ Y. x6 i
  89.   delay_us(20);7 W% R2 g; ?; Z9 T( q3 D9 r
  90. 6 A) z8 R/ h  P/ J* ^* q9 F5 I. C
  91.   scl_low();' d% v, q. f& ?! F4 q. e( x9 P
  92.   delay_us(50);
    / K! O% Q1 p, o+ f
  93.     }- s1 ?9 c/ n6 K; s
  94. // 9th bit acknowledge+ N; c+ w# [; F+ f+ R& ]4 S
  95. if(u8Ack==I2C_ACK) {
    ; R1 ?0 s4 S, x1 t+ a& _# y
  96.   sda_low();
    4 k& N. O7 D" t/ f) U& u! o) {
  97.   delay_us(20);* C. A( q. S* t9 D/ ~
  98. }     9 A) n2 j# {- C. a
  99. //I2C_ACK=0
    1 S% Y# ~; }) T6 P3 b
  100. else {
    4 q( L/ o5 n, s+ G* Q" P" ?
  101.   sda_high();7 u9 r9 m: V. ~( z6 F; _; ]
  102.   delay_us(20);5 `1 i( c7 Y# r) Z  [
  103. }" h# j( J% \% m1 D2 E; w
  104.    scl_high();
    $ C' w* `/ z+ Z0 r2 I
  105. delay_us(20);
    7 G& q7 J7 p+ n) h0 e
  106. scl_low();
    # H0 \7 B' o: {
  107. delay_us(20);
    4 `) Z; p9 [# W& j# P9 v
  108. sda_high();2 O% G2 R4 [( @5 O
  109. delay_us(20);           [  e. @' F: A
  110.     return u8Data;
    6 d9 Q) W# O' t" J  U
  111. }
复制代码
' u6 R8 h0 x; A

i2c.h:

  1. #ifndef _I2C_H_INCLUDED
    1 A! u/ b, e& g& V- O
  2. #define _I2C_H_INCLUDED) j. c4 E- s" T4 o7 `) G7 j# _

  3. 0 S5 F4 d; t; Z9 s: d, M
  4. #include "main.h"
    $ i7 c6 P: p% ]. L2 [% e' Z( q
  5. #include "Datadef.h"
    ) O+ E6 M; n4 J1 V# [& _0 q' h
  6.         
    + b# D! p) f- F. F% H
  7. // #define I2C_CLK_HIGH()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);
    7 ?5 `$ C: i- f% _0 s- }$ J
  8. // #define I2C_CLK_LOW()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);: I. }. `( ?/ d; Z
  9. # W2 E, d; {- f5 A/ Y7 `( R
  10. // #define I2C_DATA_HIGH()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET); 8 q* E* C1 S2 |4 a1 e8 E# _0 M
  11. // #define I2C_DATA_LOW()    HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);    {/ U) h9 d$ h% M, b7 B
  12. // #define I2C_DATA_STATE()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);
    4 I+ {3 U# S. j" f
  13. : g$ {+ i& j4 l+ K% x
  14. // #define sda_high()  I2C_DATA_HIGH()     // set signals to HIGH first before selecting IN -> slew rates
    4 x+ k3 K( }# g$ t& G1 y9 s: H
  15. // #define sda_low()   I2C_DATA_LOW() ; w9 a4 u4 j! ?) M& E
  16. // #define sda_read()  I2C_DATA_STATE()    //ack on bus is low -> u8AckBit = 1" T$ X: K- a) m" e" L7 s
  17. 9 ?: F6 z" K$ E7 ]! J5 @
  18. // #define scl_high()  I2C_CLK_HIGH()     // set signals to HIGH first before selecting IN -> slew rates
    4 _& S" d, t$ l/ j
  19. // #define scl_low()   I2C_CLK_LOW() . }- }' O1 k, c- T
  20. $ C: d' ^, t& L$ ?6 S6 }' g
  21. #define sda_high()  HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET); ( M4 |/ F: X% o2 b% @  j0 z, o2 b
  22. #define sda_low()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);
    # B2 z% ^0 v- ~: n# J9 V5 h* r: i
  23. #define sda_read()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);" c) w2 s2 ~( Z- m7 P' c4 f

  24. 3 L0 E9 t9 h, }/ ?) }
  25. #define scl_high()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);
    ) b6 }9 B  J* d; I) `3 M6 i: Q  ?
  26. #define scl_low()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);
    ; E' p7 L1 p" B2 W4 }
  27.                          ) o5 s! l. U5 N) U
  28.                          & P( w8 y: ]8 |
  29. // ------------------------* [$ m8 [. t5 z2 ~' {7 F
  30. #define DONOTHING()          {;}' p3 s- V+ U/ Q, {1 n
  31. / n' Q* m' ]% m% K$ j7 i+ j$ x
  32. // ------------------------  Q4 q* q7 A8 \) h$ ^7 i
  33. // command's
    7 H/ T8 t2 a% P; o/ h) n, `
  34. #define I2C_WRITE             0
      [/ w) B' h$ U2 P" a4 A7 ?
  35. #define I2C_READ              10 O+ @2 ]  q% w, X5 o# }; W/ N
  36. #define I2C_ACK               0
    + f% e. U9 L. Z/ k  j
  37. #define I2C_NACK              1
    , K: Q! i8 t! C) F2 i6 ^! V
  38. 9 w; ]7 C; m) u$ n6 M; b8 @; b' g
  39. void i2c_init(void);
    ) c9 O6 B6 m2 [+ z& a7 g* K7 |
  40. void i2c_start(void);/ ?- ~0 {0 h2 `7 o2 y& N
  41. void i2c_stop(void);& p8 ^0 s7 r/ p5 K/ |- R! g
  42. uint8 i2c_write(uint8 u8Data);
    6 J) d2 E/ Y3 O$ Q; j5 s6 r7 b
  43. uint8 i2c_read(uint8 u8Ack);
    % I5 r( M6 m8 K  B% L

  44. . D6 @8 u/ A/ z- p
  45. #endif
复制代码
4 U( Z$ m- q, W  d6 `( T+ {3 N

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

测试结果:

) f2 k% d/ f% r" C% J$ U1 j2 R) f- ]1 j

微信图片_20230612191105.png

) i: F& |: t$ L. I9 ]. n3 G, |

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

$ H8 V8 @' m4 \

转载自:矜辰所致

如有侵权请联系删除
. V. g5 _6 U- K$ d" W; [/ O

) R: `: d8 c4 Z1 f- G

$ [. L& V( s7 z7 S% p7 L
收藏 评论0 发布时间:2023-6-12 19:11

举报

0个回答

所属标签

相似分享

官网相关资源

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