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

【经验分享】STM32 HAL库BH1750光强检测器驱动代码

[复制链接]
STMCU小助手 发布时间:2022-4-11 10:16
  1. #ifndef __LIGHT_H
    8 R; w& C- l& o; F* f- n. N# c
  2. #define __LIGHT_H
    ! _) P/ U2 p! E! z5 q
  3. . x% P+ D/ P+ S0 k
  4. #include "system.h"
    + r7 o# h3 n, J/ p
  5. #include "delay.h"
    0 m6 U2 y% Y9 l* X
  6. ( C6 K- p* `7 \" c
  7. //IO方向设置
    # h- d- E4 R! d$ ~
  8. #define SDA_IN()  {IIC_SDA_GPIO_Port->CRH&=0XFFFFFF0F;IIC_SDA_GPIO_Port->CRH|=(u32)8<<4;}
    ( n  T8 P8 }7 U
  9. #define SDA_OUT() {IIC_SDA_GPIO_Port->CRH&=0XFFFFFF0F;IIC_SDA_GPIO_Port->CRH|=(u32)3<<4;}- Y7 P7 W" i! s
  10. + t3 u5 I  u  f% N; _8 D8 [
  11. #define IIC_SCL    PCout(8) //SCL
    % I$ J0 R4 c0 t4 Y
  12. #define IIC_SDA    PCout(9) //SDA           Y1 Y# I8 Q# @7 r
  13. #define READ_SDA   PCin(9)  //输入SDA1 X% u3 _, }6 g8 V% c
  14. #define ADDR 0x23                        //0100011
    # N: M+ v9 |; y; _. [. ~/ _/ r( ?

  15. 9 ^. f1 w+ L3 A
  16. #define BHAddWrite     0x46      // 从机地址+最后写方向位6 P7 _- E% n% [/ W
  17. #define BHAddRead      0x47      // 从机地址+最后读方向位
    5 h( h2 P! |9 r" b
  18. #define BHPowDown      0x00      // 关闭模块
    2 r% ]# F. G4 E& a  T
  19. #define BHPowOn        0x01      // 打开模块等待测量指令: L9 J- n# W/ {
  20. #define BHReset        0x07      // 重置数据寄存器值在PowerOn模式下有效
    ; l) {+ _, [1 s- _
  21. #define BHModeH1       0x10      // 高分辨率 单位1lx 测量时间120ms+ _8 v! W4 n1 j- D
  22. #define BHModeH2       0x11      // 高分辨率模式2 单位0.5lx 测量时间120ms
    * \& G( L5 y" E; b! p
  23. #define BHModeL        0x13      // 低分辨率 单位4lx 测量时间16ms1 ~6 l3 q+ n' J+ q; y
  24. #define BHSigModeH     0x20      // 一次高分辨率 测量 测量后模块转到 PowerDown模式2 b; J" l; w9 }8 s
  25. #define BHSigModeH2    0x21      // 同上类似
    : u4 N0 u) n% Y% c
  26. #define BHSigModeL     0x23      // 上类似8 r8 v) T7 Q1 O  J( }/ s

  27. ( T( x9 @9 R0 s' ]9 j+ P
  28. void Single_Write_BH1750(u8 REG_Address);8 ?: X: g% j8 a! G1 a3 B) u4 q
  29. void Light_Init(void);
    5 R( e( `8 I8 s5 {$ I8 k
  30. void bh_data_send(u8 command);; K& o5 U" u5 W  v/ `$ R  ^
  31. u16 bh_data_read(void);
    ) ~2 ~2 ?, ^. J  w1 W1 _7 i* _3 k
  32. 5 P! l# B3 l9 C
  33. //IIC所有操作函数
    ( ?- V1 v* P' ]  N" _8 \! [4 n
  34. void IIC_Init(void);                //初始化IIC的IO口
    + L3 N+ r* \# h/ F7 `+ U* O5 Q
  35. void IIC_Start(void);                                //发送IIC开始信号6 B* d7 L& W5 J6 G
  36. void IIC_Stop(void);                                  //发送IIC停止信号) d) v: z# Y- N9 U1 t
  37. void IIC_Send_Byte(u8 txd);                        //IIC发送一个字节
    ) i3 V+ e0 n- m& G' f( ]) ?; S
  38. u8 IIC_Read_Byte(u8 ack);                        //IIC读取一个字节
    9 K& G" d, a7 ?; C, [" t; r" V
  39. u8 IIC_Wait_Ack(void);                                 //IIC等待ACK信号) U8 u/ @( j- O- C, S
  40. void IIC_Ack(void);                                        //IIC发送ACK信号
    9 M( h+ o, Z! ~7 f, a
  41. void IIC_NAck(void);                                //IIC不发送ACK信号- `& m! o' b: C. g9 d6 M, q
  42. 4 ]  n& {6 {2 H5 s
  43. void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);" R9 ]2 T2 t) N% b( ?5 `
  44. u8 IIC_Read_One_Byte(u8 daddr,u8 addr);
    9 J' T+ N1 o: R; i3 j0 N8 C

  45. # \. \; V+ G$ a$ V  `
  46. #endif
复制代码
  1. #include "bh1750.h"$ X8 b# E8 W. K3 ^- V/ j! N
  2. $ _5 N8 }  c: ~
  3. void Single_Write_BH1750(u8 REG_Address)
    7 y7 A! _& C5 a1 ?& z/ a/ q: y! O! H% v
  4. {
    3 _7 j, ^+ x/ D& i% J) p( h
  5.     IIC_Start();                  // 起始信号
    " z$ c! D, r. k, b
  6.     IIC_Send_Byte(BHAddWrite);    // 发送设备地址+写信号
    " D4 l8 J5 w& f4 ~
  7.     IIC_Send_Byte(REG_Address);   // 内部寄存器地址,
    : i" |2 ^% I% |& I' U2 }1 b
  8. //  BH1750_SendByte(REG_data);       // 内部寄存器数据,. a" v$ J, T. o) k1 w
  9.     IIC_Stop();                   // 发送停止信号
    $ g3 a' g- `  p- m
  10. }
    6 X) z$ [' V! n9 ~5 M) f
  11. : F7 c) o3 P8 j, ]. R
  12. void Light_Init(void)' t3 b5 W& J) y  O/ s: [
  13. {; K  S1 o1 n, I
  14.     GPIO_InitTypeDef GPIO_InitStruct = {0};# P2 E, l, p" H- T  Z! P- j

  15. % p2 f" s, v& M  q8 t% ]  B
  16.     // 使能GPIOD时钟1 s& _4 T' `' M1 `# W( s
  17.     __HAL_RCC_GPIOD_CLK_ENABLE();& B4 R2 A  H, S! Y% h. |
  18. / \2 Q) H5 y" K  {3 ]
  19.     // PD6和7引脚置高  |; f# T! Q7 H
  20.     HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET);
    & j8 B2 W' f9 W6 @
  21. 3 d: C* r3 P! F, n
  22.     // 初始化引脚: ~9 i5 t) `& I/ B' U6 W9 Z
  23.     GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;( |) S8 d+ ~% {' k3 O$ v1 l
  24.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    0 d! s9 r% Z$ K  G) x% W
  25.     GPIO_InitStruct.Pull = GPIO_NOPULL;6 g# Y3 A7 r1 i4 H% f, o* x0 s
  26.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    8 Q( |$ N2 d, f: z! @2 r
  27.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);* i* V) ]8 g5 n% J, v
  28. 6 a; Y" Y, i" V: D, ?& T
  29.     Single_Write_BH1750(0x01);2 f( d  @$ H8 d7 M! [  I* w
  30.     bh_data_send(BHPowOn);! P0 o) L. l8 F4 C4 T2 T; h- C
  31.     bh_data_send(BHReset);
    $ a) k' k" k# X* \- p$ T
  32.     bh_data_send(BHModeL);                        //选择的是分辨率是4lx,测量时间是16ms的
    $ F" J- S5 {( f" U
  33.     delay_ms(180);
      l8 G7 ?2 i2 Q: ?  e
  34. }( Z+ O& v  A2 x7 H, m! }' s  K

  35. " s/ G" _( b$ A7 }) K. Y" W, i4 U
  36. //产生IIC起始信号
    , U0 _5 ?: F( F
  37. void IIC_Start(void)! t" e) N( d3 a! e
  38. {
    , K# h# I# O/ e# J2 w* Z
  39.     SDA_OUT();     //sda线输出- _: z! q2 Z9 P' d" C
  40.     IIC_SDA=1;
    ' u$ f$ w) W' ]8 l7 G4 N& H4 A
  41.     IIC_SCL=1;, Z+ m3 Q8 z; ^0 H$ N. y, |2 T
  42.     delay_us(4);
    7 o# }& r& t- w+ U
  43.     IIC_SDA=0;//START:when CLK is high,DATA change form high to low2 P- ?- F9 g6 K4 G. ~
  44.     delay_us(4);
    0 \# \& ^" s7 Y% J
  45.     IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
    0 K7 R8 O# H& o) i# @* G
  46. }- d" t' p6 ?" Y/ @4 Q5 \

  47. , |' a) C4 `. G1 V6 N6 i
  48. //产生IIC停止信号
    % y; j: g# ^! q  C, f
  49. void IIC_Stop(void)* p% C! \& P* z
  50. {4 Z# [8 `) e0 ]6 l- L% [5 `
  51.     SDA_OUT();//sda线输出
    ( X3 \9 F2 [/ [" {0 e4 G' E9 E2 V
  52.     IIC_SCL=0;
    6 W2 t; }% ~0 a5 t7 e
  53.     IIC_SDA=0;//STOP:when CLK is high DATA change form low to high& {9 N1 {' `+ T- }( S3 Z/ D
  54.     delay_us(4);
      i3 i$ y# V+ B7 A% E8 E1 ~
  55.     IIC_SCL=1;
    6 T8 m" n& A! s9 B. B
  56.     IIC_SDA=1;//发送I2C总线结束信号
    * l( N0 ^4 N3 t& W- x: f: s# z- U8 L
  57.     delay_us(4);, P$ Y: W. y) \2 j0 o2 B
  58. }
    0 J6 p9 c* d7 r! h
  59. 1 ?; J& D6 a9 ^, X
  60. //等待应答信号到来" m! N' A$ [5 x+ p; n
  61. //返回值:1,接收应答失败
    1 `5 G  O8 S( m. e$ @  Y
  62. //        0,接收应答成功
    ( f- |  p9 K; }& P1 B) m/ X) t$ P
  63. u8 IIC_Wait_Ack(void)! y2 `9 ^0 F, Z# D+ x
  64. {
    5 |9 m, D3 ^8 \+ S. C5 d2 h
  65.     u8 ucErrTime=0;- W7 l  g9 t% @
  66.     SDA_IN();      //SDA设置为输入+ A* B0 {, B8 w- P' Q, W, e
  67.     IIC_SDA=1;
    ; }7 U# [8 L5 E4 C: N4 Y* i
  68.     delay_us(1);6 _  T4 n' O# M3 O3 p( N' X
  69.     IIC_SCL=1;
    . ?( m* k7 M! f/ x
  70.     delay_us(1);9 p# p3 t$ H2 t3 n/ [# ?/ U
  71.     while(READ_SDA)8 V- z# o3 M2 S6 c4 E' ]6 p4 b
  72.     {
    8 \& y* b( X$ z/ F* V
  73.         ucErrTime++;
    # p3 }  f) R2 q; c6 e
  74.         if(ucErrTime>250)2 P4 T; g' d; P9 g4 b
  75.         {
    0 |7 D6 `9 v& d7 a1 M
  76.             IIC_Stop();
    - G8 Q; C' Z) e3 }
  77.             return 1;5 ~# f) E0 d5 j0 {* U7 Z
  78.         }
    $ D; V0 [, t1 @
  79.     }
    + o5 U7 g" q9 I) H: m  `
  80.     IIC_SCL=0;//时钟输出03 S- d) @$ d, d8 J7 o
  81.     return 0;
    5 j7 b; Y$ O3 D/ h5 |
  82. }  [$ t; L) a  Z/ c9 s9 v( r: u, h5 r
  83. ( u6 {% r- U$ F# Z6 n4 o2 d" f  }6 [
  84. //产生ACK应答
    : Z( d" m& M* K
  85. void IIC_Ack(void)
    5 ?, ~- l8 [& ~" O0 X5 _
  86. {
    * j/ j3 ^6 x: P
  87.     IIC_SCL=0;
    : N; G" G1 n+ H6 Y) H8 B
  88.     SDA_OUT();
    8 {- X/ R( U' x6 j5 l+ N6 b
  89.     IIC_SDA=0;$ b& W7 w. ~; ]/ h$ [8 @
  90.     delay_us(2);% d/ v( N* R3 @4 ?! L6 z. j
  91.     IIC_SCL=1;
    & U! O- g$ l- b! ~( N
  92.     delay_us(2);% G1 e9 ~# n/ k* A# l3 c. O
  93.     IIC_SCL=0;
    , C3 {# ~; d0 r/ A( M2 H
  94. }
    ! \( ~) C2 _. n3 c3 i9 Y# u( L

  95. / x( Z* O* s+ x3 x1 b  c, U
  96. //不产生ACK应答- s- J+ }; n4 Q; z% D
  97. void IIC_NAck(void)5 g: H, I1 j, h* E2 D; z
  98. {
    6 Y; l+ Q2 W4 s& ^+ w1 f5 K
  99.     IIC_SCL=0;$ o+ j2 \  m0 H# A9 |
  100.     SDA_OUT();6 R, m( V8 i6 ^& q! Z/ l
  101.     IIC_SDA=1;
    0 T& F+ ?$ H8 t$ i  r3 i6 o+ ~% k# B
  102.     delay_us(2);
    + g: x8 q2 I1 P+ N% I9 W
  103.     IIC_SCL=1;
    ; c) v% B% E6 V) Q4 ~* Y# q) a
  104.     delay_us(2);& @, i+ D7 F4 ~
  105.     IIC_SCL=0;
    5 N3 X5 s1 b) @2 a
  106. }- Q. l0 b8 n8 l4 E+ a* A
  107.   X) u1 y/ {8 j3 X+ b
  108. //IIC发送一个字节6 r2 E0 \+ w" t' |4 O
  109. //返回从机有无应答
    # J2 ^" ^" n; S9 v, w* J. U
  110. //1,有应答
    # M& @' _% k$ k
  111. //0,无应答% i+ ]* L3 J. w3 n; \
  112. void IIC_Send_Byte(u8 txd)6 @7 f- J( f  m' J
  113. {, A7 H2 {( E4 T/ P' E: S
  114.     u8 t;5 R/ G1 k, N, C
  115.     SDA_OUT();8 t2 o3 b: l# l9 b
  116.     IIC_SCL=0;//拉低时钟开始数据传输1 [! m% [1 A2 O" n, G
  117.     for(t=0; t<8; t++)+ t  K6 a- W1 T8 m( E- Q5 f
  118.     {
    ; f$ H! ~8 a; M) }. n" P5 q( m0 R# Z
  119.         //IIC_SDA=(txd&0x80)>>7;
    % E* Q5 K- e3 C9 y. Z
  120.         if((txd&0x80)>>7)* w6 x  Q# d" s4 J/ u( \9 g2 e, Q
  121.             IIC_SDA=1;
    . _! X5 k, @& R+ `
  122.         else
    : r; p2 ]- V4 g+ z! E
  123.             IIC_SDA=0;# f! }5 u' |" l) r' [
  124.         txd<<=1;) J7 _6 Q& ]  A0 v
  125.         delay_us(2);   //对TEA5767这三个延时都是必须的
    ) ~! ?( u! c+ s" p  L! T
  126.         IIC_SCL=1;
    / w; _8 K) Q# a
  127.         delay_us(2);: R5 M/ G' r5 B+ f1 T: k2 }
  128.         IIC_SCL=0;, E% M6 @; Q9 a6 T" g0 d
  129.         delay_us(2);- V4 x; @/ L2 z7 t( j/ s
  130.     }# ~, P' k0 ~; m. R+ s
  131. }
    ( T/ s+ a3 w' \% |. h- {* U7 B

  132. ' B" K5 l* m5 T+ |! R6 y+ J
  133. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
    0 W9 P' z- Y" P
  134. u8 IIC_Read_Byte(unsigned char ack)
    9 H5 `$ C9 [: U- {2 \0 d! \" J$ s$ ?
  135. {
    & i; L/ B/ g( b4 F
  136.     unsigned char i,receive=0;
    3 J) [# C7 C' [. ?1 L$ C# x
  137.     SDA_IN();//SDA设置为输入
    ! G4 S2 }0 {& @3 ~/ d1 D* e( @6 U: A
  138.     for(i=0; i<8; i++ )
    ' D, G8 H# }5 W1 B0 D% q
  139.     {
    + z; H. x0 }" B0 Y
  140.         IIC_SCL=0;/ [3 b$ O! q& O
  141.         delay_us(2);( {/ U9 y! q* V% |0 V  I! c
  142.         IIC_SCL=1;
    1 u, Z6 {1 \" f# J& T; E
  143.         receive<<=1;% Y& E* `& G6 _0 i3 Z
  144.         if(READ_SDA)receive++;" k1 S3 ~' q# @' z7 e) P: D. C
  145.         delay_us(1);2 d: q+ _4 N1 U7 A0 r" P" f
  146.     }
    , ^+ t, ~9 w- y) }
  147.     if (!ack), K% X, F' l# l& U  ]" [6 o5 B0 e
  148.         IIC_NAck();//发送nACK& s( J& @$ m5 D. ~3 `* i6 S( O
  149.     else
    # j. b. R9 ^/ J/ X/ D6 _- w( e- x, X+ w
  150.         IIC_Ack(); //发送ACK3 Z3 K( p; h" d& N- u5 U( N
  151.     return receive;
    4 [. Z2 u) V' h, h) V* a+ {/ K
  152. }
    ( Q+ E$ e. O% i# x, U

  153. 1 V  I- L# @" ]
  154. void bh_data_send(u8 command), R0 G0 y$ L9 g/ K) C
  155. {
    % z" o2 k" [( x* `
  156.     do
    / Y, `5 ^- g5 A7 \2 x0 e5 F
  157.     {' x! V; V, ~& @, {( P0 t
  158.         IIC_Start();                      //iic起始信号" ^' \/ A; k$ B$ ]
  159.         IIC_Send_Byte(BHAddWrite);       //发送器件地址
      \/ P* ]+ i# i$ I4 K9 G& z
  160.     }
    " R: `% Z) m# o' ~4 Z2 r
  161.     while(IIC_Wait_Ack());            //等待从机应答: {$ a  ]4 c; ?  C+ a7 b% f- q" V- ?
  162.     IIC_Send_Byte(command);          //发送指令4 j! D7 R: W6 X$ j) ?  E8 E; W
  163.     IIC_Wait_Ack();                   //等待从机应答
    3 x: y7 k" k; C
  164.     IIC_Stop();                       //iic停止信号
    # u/ z% i  v! M/ v7 _
  165. }7 w' `- c; e3 [2 w2 O( x+ J

  166. " r: }0 c: S. A% R2 C3 ?- J& w3 S
  167. u16 bh_data_read(void)' J: _9 l' _7 L) [6 u) ^+ u# B
  168. {
    7 O$ F0 R" f* N  y; ~
  169.     u16 buf;
    ! k1 d' u/ X9 e5 s9 e8 I4 `
  170.     IIC_Start();                       //iic起始信号
    # B+ g" ?2 O- d& g  l
  171.     IIC_Send_Byte(BHAddRead);         //发送器件地址+读标志位; G; ^' m/ J8 U) ~0 Z
  172.     IIC_Wait_Ack();                     //等待从机应答
    1 F+ h/ Q5 Y2 J- a% r* P  t, d. g
  173.     buf=IIC_Read_Byte(1);              //读取数据2 B; T7 F; R+ T* J
  174.     buf=buf<<8;                        //读取并保存高八位数据
    2 @' K) }1 t9 }/ r5 |
  175.     buf+=0x00ff&IIC_Read_Byte(0);      //读取并保存第八位数据( J& D" A, o/ c  E% d# s4 d- n( X
  176.     IIC_Stop();                        //发送停止信号! B. L5 b" z7 d' }0 X% }
  177.     return buf;
    2 |% x. h$ B0 f$ J( x
  178. }
    ' M; o: A: ?  z9 j3 p' w. c+ Y
  179. & ^" l1 j" @* i/ L

  180. 4 @( p7 u* }: E- T
复制代码

( T) b$ m; U: r
收藏 评论0 发布时间:2022-4-11 10:16

举报

0个回答

所属标签

相似分享

官网相关资源

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