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

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

[复制链接]
STMCU小助手 发布时间:2022-4-11 10:16
  1. #ifndef __LIGHT_H
    2 E$ j5 _* g- g! ?
  2. #define __LIGHT_H
    : y3 i, V* Z( |; e
  3. # m5 q, F9 y0 v# C  A
  4. #include "system.h"4 ]; v2 E. G% @$ _8 \$ U
  5. #include "delay.h"8 _0 r7 N$ |& I' ]! [" T! j. T9 \. h) Y& u

  6. 4 J( h( q' I% o1 L
  7. //IO方向设置
    3 ^1 C/ L' W- g  F2 I& x/ A
  8. #define SDA_IN()  {IIC_SDA_GPIO_Port->CRH&=0XFFFFFF0F;IIC_SDA_GPIO_Port->CRH|=(u32)8<<4;}
    ' H. \2 }+ [9 R" y
  9. #define SDA_OUT() {IIC_SDA_GPIO_Port->CRH&=0XFFFFFF0F;IIC_SDA_GPIO_Port->CRH|=(u32)3<<4;}
    ' Q' A: K' U/ ?- I; q4 \% w
  10. % {. u3 v# o4 Q+ b
  11. #define IIC_SCL    PCout(8) //SCL
    - I1 e0 S; B- A- D: T
  12. #define IIC_SDA    PCout(9) //SDA         
    2 D: A* ~9 W! e
  13. #define READ_SDA   PCin(9)  //输入SDA- Z1 U) `: b% y8 I% |* s( G
  14. #define ADDR 0x23                        //0100011
    3 `5 h2 W: @7 O1 `- O* P
  15. ' z, E% C. G9 N' D! H. o# h
  16. #define BHAddWrite     0x46      // 从机地址+最后写方向位6 ?/ p4 O3 _/ R
  17. #define BHAddRead      0x47      // 从机地址+最后读方向位0 i3 q- c, c' G5 T0 ?2 }
  18. #define BHPowDown      0x00      // 关闭模块& @: h0 G) J3 l6 s4 a1 t9 b- B
  19. #define BHPowOn        0x01      // 打开模块等待测量指令
    % N& ?7 f# b  Y: [5 z6 p
  20. #define BHReset        0x07      // 重置数据寄存器值在PowerOn模式下有效
    7 E# @/ V# u+ z
  21. #define BHModeH1       0x10      // 高分辨率 单位1lx 测量时间120ms! G0 Z; A* F: {- y) S# f
  22. #define BHModeH2       0x11      // 高分辨率模式2 单位0.5lx 测量时间120ms* b, ^: C0 A  X) C. ^
  23. #define BHModeL        0x13      // 低分辨率 单位4lx 测量时间16ms# F: G, P; q/ G( z  ^( ~, y
  24. #define BHSigModeH     0x20      // 一次高分辨率 测量 测量后模块转到 PowerDown模式8 Z3 d; A) N8 y5 C
  25. #define BHSigModeH2    0x21      // 同上类似
    9 ~. D0 Z/ X) b) t3 j" j
  26. #define BHSigModeL     0x23      // 上类似$ [( N! m# ~$ H4 S

  27. ' c$ d. Z- d! Q: o) t/ @% d7 s/ H
  28. void Single_Write_BH1750(u8 REG_Address);
    ( a. }6 s$ j- g0 g" }
  29. void Light_Init(void);% B# l" e8 C* P5 |8 G
  30. void bh_data_send(u8 command);! f. D1 T1 n) x
  31. u16 bh_data_read(void);
    8 b& X: F8 s$ d4 K" ?8 g
  32. 6 [) b" z9 X5 |3 `8 w
  33. //IIC所有操作函数
    % f, ]- c- c# Y7 {* Z2 D
  34. void IIC_Init(void);                //初始化IIC的IO口. q. A3 t( y  o% h
  35. void IIC_Start(void);                                //发送IIC开始信号( O$ \" {6 E/ o& Q+ X
  36. void IIC_Stop(void);                                  //发送IIC停止信号  U, j" x2 P/ a& h
  37. void IIC_Send_Byte(u8 txd);                        //IIC发送一个字节
    / H& w3 E# y1 J/ Y. ^
  38. u8 IIC_Read_Byte(u8 ack);                        //IIC读取一个字节- u3 D  ~7 w: P1 A9 b
  39. u8 IIC_Wait_Ack(void);                                 //IIC等待ACK信号
    7 }! H' L* H3 V2 x  B5 m  P8 _) {
  40. void IIC_Ack(void);                                        //IIC发送ACK信号% {9 s- s+ Z3 ~9 f
  41. void IIC_NAck(void);                                //IIC不发送ACK信号7 e# N. `* t. o. `# J7 v& M

  42.   m# {2 }& j2 j0 Q2 l; G
  43. void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);2 K+ d# x% X% p+ x
  44. u8 IIC_Read_One_Byte(u8 daddr,u8 addr);
    9 p* u6 p: x$ I# P6 p" n# [" {0 o
  45.   u5 {; t& _4 b
  46. #endif
复制代码
  1. #include "bh1750.h"
    8 ~# b6 e- b8 l6 M: U6 V
  2. 3 h& k" ?8 F% j9 o2 [. E: J3 E
  3. void Single_Write_BH1750(u8 REG_Address)
    + a$ B9 e( |7 ?0 l! {
  4. {
    9 H3 A5 J7 F1 O$ n! J2 [# ^+ }" J
  5.     IIC_Start();                  // 起始信号3 T$ G: s0 W, B) j$ ?
  6.     IIC_Send_Byte(BHAddWrite);    // 发送设备地址+写信号8 F% P& S' R2 Z. ~; O8 t
  7.     IIC_Send_Byte(REG_Address);   // 内部寄存器地址,
    $ r, B& g' `9 F1 w
  8. //  BH1750_SendByte(REG_data);       // 内部寄存器数据,
    ) }; @. o) q; d; X/ K6 @# e
  9.     IIC_Stop();                   // 发送停止信号
    % {; Z. F4 C; |- @7 ?
  10. }3 I9 a* Y5 g! o6 @
  11. $ `+ B# u3 G) N! d+ x
  12. void Light_Init(void)
      e/ l4 p. Y! q: w
  13. {) A8 ~; P7 c# t) ?9 h. N
  14.     GPIO_InitTypeDef GPIO_InitStruct = {0};! j& _1 e' A7 `/ p

  15. 6 \. f3 J; Q" q
  16.     // 使能GPIOD时钟
    , U" ]. [, v* X# S" R5 y, Q
  17.     __HAL_RCC_GPIOD_CLK_ENABLE();
    , r; S: \2 N5 C
  18. ' P- R( j/ J- U' P0 _" r
  19.     // PD6和7引脚置高  `/ r' c' Y' n# c
  20.     HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET);
    8 r! c4 t$ g  d5 v8 z

  21. 7 F- d3 G8 C* }. H) W4 M6 e$ V3 I
  22.     // 初始化引脚+ v0 c7 {3 c5 @$ d' `9 T/ {: J, u/ M
  23.     GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;- l- [4 c- r3 ?. ^6 T
  24.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    % Z+ m8 g; }, J0 l+ T
  25.     GPIO_InitStruct.Pull = GPIO_NOPULL;- P( A3 U& [; _5 P, W
  26.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;6 h" W9 @0 v3 i% {3 q9 q1 _: p
  27.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);4 o! S  f, z8 S9 h% N3 _

  28. ' }% i3 r) Y' X0 D% Z+ y
  29.     Single_Write_BH1750(0x01);! A: c  h* ]4 t& V
  30.     bh_data_send(BHPowOn);& ?9 V; m' Z$ y0 e
  31.     bh_data_send(BHReset);
    ( p( C: s2 t# q3 S( |* a8 B  a
  32.     bh_data_send(BHModeL);                        //选择的是分辨率是4lx,测量时间是16ms的
    * v6 N$ R5 x) P, a4 N
  33.     delay_ms(180);
    + y4 K8 q; _2 b) P
  34. }
    ! L( X0 ~: @" S6 ^

  35. $ n, i. Q9 J4 }
  36. //产生IIC起始信号
    * ?1 I' z/ L7 y. P( ?
  37. void IIC_Start(void)
    6 Z; U) D, V$ X& P
  38. {1 n) ~$ Z7 }6 l0 d3 i
  39.     SDA_OUT();     //sda线输出
    8 D' D% L3 q. z) i! _' ~9 V
  40.     IIC_SDA=1;
    ! j  `1 {" t9 ~' ~" Z
  41.     IIC_SCL=1;3 q2 F8 @6 {6 L0 w$ Z
  42.     delay_us(4);8 D, U# C( h+ _7 P% ^
  43.     IIC_SDA=0;//START:when CLK is high,DATA change form high to low9 S0 ~0 I# w4 {: I
  44.     delay_us(4);' W; \4 {( ]1 x4 m
  45.     IIC_SCL=0;//钳住I2C总线,准备发送或接收数据% P& T1 J: t/ P/ V; L
  46. }
    4 H6 h' o0 C) @0 d

  47. $ V* @+ {5 F2 L1 d/ B6 C
  48. //产生IIC停止信号
    1 b0 S$ \( Z# R  P; y% k+ Y8 @& I! K
  49. void IIC_Stop(void)
    6 m5 s: `! J' I8 m6 |
  50. {
    ' R- B+ k: g3 v7 A1 E
  51.     SDA_OUT();//sda线输出5 {- g2 |/ @/ }/ N' O
  52.     IIC_SCL=0;; s4 @" |; n; V# C, c3 Z
  53.     IIC_SDA=0;//STOP:when CLK is high DATA change form low to high8 M  d: o) n6 y% y% F% E
  54.     delay_us(4);
    $ B- j' C2 {' T' t( ^
  55.     IIC_SCL=1;0 p  G9 M, Y1 z. G9 I
  56.     IIC_SDA=1;//发送I2C总线结束信号  {' @$ b. X- O/ U/ b; C
  57.     delay_us(4);: i5 t0 l0 V- T6 U! S
  58. }
    % N2 l' Z* M1 S0 J8 U7 C
  59. 5 ^4 t! f  e2 K0 r. |' Y
  60. //等待应答信号到来
    $ r* [: A2 S1 O) ^( N4 o6 m
  61. //返回值:1,接收应答失败- e8 U2 M" Z- |' C% Y# ^
  62. //        0,接收应答成功5 s! m1 p% Y/ k  [7 @1 P1 e
  63. u8 IIC_Wait_Ack(void)& v# f& O  i/ _) d& ]% Q
  64. {
    7 j7 S1 ?7 T- h
  65.     u8 ucErrTime=0;
    % ^0 L; \6 Q1 o  b# B1 v: M
  66.     SDA_IN();      //SDA设置为输入
    ; u0 w7 l3 g; z9 }
  67.     IIC_SDA=1;' S) N; I7 j: ~7 z2 }! c
  68.     delay_us(1);! z" _) k! g7 f! S  G& ]" q( D( O! p
  69.     IIC_SCL=1;
      K  [; |5 \! r! g
  70.     delay_us(1);
    2 e9 P+ \8 n; ^* I& f- h+ o
  71.     while(READ_SDA)
    , Y+ g! Q' ~2 r% `, S
  72.     {
    & I+ h- t* j$ W0 ^" k3 Y
  73.         ucErrTime++;
    5 h6 _/ m  J! ?  _- `
  74.         if(ucErrTime>250)
    ' \4 H/ D0 o& o. ~; v8 N9 v
  75.         {- g& R/ V" P" |4 U- w
  76.             IIC_Stop();/ ]  ?% h' T8 Y
  77.             return 1;
    3 j, M! u! L0 R# R, E  p. b" F& y
  78.         }
      t* s# M% K- K& d1 J# `
  79.     }
    : s+ Y) P( I0 e2 ~3 r
  80.     IIC_SCL=0;//时钟输出0, M4 F% n$ D9 B/ @, m
  81.     return 0;  F4 [8 ~0 w& Q! w& a' [* o9 b
  82. }8 ?, [, z8 _2 M: a# d* A

  83. 5 q' |/ n: w+ X" n' g
  84. //产生ACK应答: M+ {' r( B, e& @) K, u- W% j5 \( D
  85. void IIC_Ack(void)
      \( z& f% ^. u
  86. {$ g; l1 x4 P! D* E' o5 t
  87.     IIC_SCL=0;: g( P) L1 L0 [: I! m  ^
  88.     SDA_OUT();
    5 g# {8 D! t/ C. `7 M
  89.     IIC_SDA=0;
    7 l& |/ n7 O; v6 X* @! X
  90.     delay_us(2);5 n( y" l9 B4 \: ?2 p" A3 f
  91.     IIC_SCL=1;. A) Z% J& \* W; w
  92.     delay_us(2);# F  L4 L( V$ H' v
  93.     IIC_SCL=0;1 K! x: L1 a& U* V2 ]: ?+ n- `. N
  94. }
    9 H& c1 ]" E6 W. Y2 l
  95. % C: W- P; ?; F6 e6 [! v
  96. //不产生ACK应答: k% p, f7 J0 z
  97. void IIC_NAck(void)
    ! |4 Z8 @9 ~3 o; z
  98. {) c" J) G' A" s: V8 Z
  99.     IIC_SCL=0;6 o; L# j! R. N
  100.     SDA_OUT();: b8 Z4 B/ ^0 {6 U* @, w) f
  101.     IIC_SDA=1;; b; _5 p9 |3 C+ x1 T
  102.     delay_us(2);) W" \2 A7 e0 K! \
  103.     IIC_SCL=1;
    : b0 g4 N9 ]& l8 p7 F
  104.     delay_us(2);* y0 Q6 g% w/ w
  105.     IIC_SCL=0;" [9 v; ^$ G3 C  d& m' d' r
  106. }
    ( k$ P% G/ n  q) p% U" d; S9 @

  107. , d5 j4 }. t) ~' [, F1 H8 Z
  108. //IIC发送一个字节
    " Y7 c: c4 d+ \
  109. //返回从机有无应答! P# e4 g: \4 p& ~2 _4 b
  110. //1,有应答
    ; y7 e! p' R+ C, u. W( z
  111. //0,无应答
    % B( }7 e  a" I$ S; h
  112. void IIC_Send_Byte(u8 txd)/ o4 X& E* ]! S2 h3 H& N9 I% T
  113. {8 l& b4 n$ E$ L: v$ S
  114.     u8 t;
    2 O0 ~. c& b, V3 c) @
  115.     SDA_OUT();
    $ R  K) j9 s2 ~! J- o
  116.     IIC_SCL=0;//拉低时钟开始数据传输* ]2 }( e4 f. B# n2 v) l4 u, {5 P5 Z
  117.     for(t=0; t<8; t++)& w5 d7 @4 R! d
  118.     {7 h; Z+ q1 P; m( t! ]
  119.         //IIC_SDA=(txd&0x80)>>7;$ V4 d# E* E/ K$ d5 m5 _
  120.         if((txd&0x80)>>7)$ t% A! S4 H0 D; b) k" C
  121.             IIC_SDA=1;" u2 @& a: c8 |& x8 ]0 i% D$ s
  122.         else
    2 R9 F+ n4 x5 H; Z$ N4 p
  123.             IIC_SDA=0;3 y# v, g7 F9 I4 s8 A$ L2 r
  124.         txd<<=1;
    . q- t$ o" t" P
  125.         delay_us(2);   //对TEA5767这三个延时都是必须的
    9 `1 m/ ]; \9 o: E7 {
  126.         IIC_SCL=1;
    9 N5 _! T- h0 c7 g, I( p# D
  127.         delay_us(2);
    " n3 L! s4 w& ~% A0 j
  128.         IIC_SCL=0;  r4 M, S% ~7 g; k) S2 Z' W: v
  129.         delay_us(2);
    ! M# ~+ v# D& R+ a' j
  130.     }
      U% A; ?5 z8 d" ?
  131. }- w1 j0 `: U3 }/ o8 B

  132. $ x4 s5 a$ k' x2 ]
  133. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK+ K; N0 a9 y$ Q+ ]0 u
  134. u8 IIC_Read_Byte(unsigned char ack)& v/ y0 l8 a$ Y( @
  135. {2 i  d# {- j; m4 A& r/ M4 e  m
  136.     unsigned char i,receive=0;) p3 j0 v, a9 `+ V5 L& i: Y3 r
  137.     SDA_IN();//SDA设置为输入
    & k- }0 j0 M/ _' d' g% O  Q& Z; a
  138.     for(i=0; i<8; i++ )
    9 V' Q8 ]$ {: F% v: g
  139.     {/ D! k/ y# h3 J# \
  140.         IIC_SCL=0;
    7 }9 V. w8 ~3 h
  141.         delay_us(2);
    ! D- D4 [) ~9 l5 F
  142.         IIC_SCL=1;
    ( H+ C, {* s1 J/ x
  143.         receive<<=1;$ `( T: p) K; f+ O4 f$ {
  144.         if(READ_SDA)receive++;
    # S/ s" y9 S- R
  145.         delay_us(1);$ h, L8 X. E* x) [: j0 u
  146.     }
    2 A* T0 W0 `  V! h
  147.     if (!ack)3 q0 @4 [( C  G) l) c; B; U, y
  148.         IIC_NAck();//发送nACK
    2 H3 h. I3 e6 ~( H) z! \
  149.     else
    & ?' N: v2 R, i' s/ ]9 G5 l- A
  150.         IIC_Ack(); //发送ACK0 W/ |3 F; T7 d! v9 R! M
  151.     return receive;$ r# V/ l7 R( [1 s5 G, u. E1 [
  152. }
    ! j: r; B" r$ z1 Z$ x5 r

  153. . u6 I  t: T) E) B
  154. void bh_data_send(u8 command)
    ' L* b9 x+ W; k& O+ v
  155. {
    + e2 h; f3 |1 f8 e8 w
  156.     do1 s8 l  u1 r, Q# R, i
  157.     {, _/ G6 @3 y" e6 G( e4 {4 {
  158.         IIC_Start();                      //iic起始信号
    ! n7 E; y3 Z2 a' g
  159.         IIC_Send_Byte(BHAddWrite);       //发送器件地址
    ' \% |. E: W; d5 _" `, c
  160.     }
    ! V+ f$ f* J$ @: U  T) a- L+ J
  161.     while(IIC_Wait_Ack());            //等待从机应答
    . l! T/ Q* D% i
  162.     IIC_Send_Byte(command);          //发送指令  n5 ~, M+ x+ g4 n/ ^1 G
  163.     IIC_Wait_Ack();                   //等待从机应答
    $ j" t  b8 {. c% J* `, E, @
  164.     IIC_Stop();                       //iic停止信号/ p* H& Z2 D4 Z
  165. }
    4 p( \- M8 E2 B+ _3 s
  166. 7 x4 K" @2 L$ u' z
  167. u16 bh_data_read(void)
    . u  K" u  z2 t; N
  168. {% W. e" S. P( b' ^  B) u
  169.     u16 buf;
    ! o4 s0 a- e6 R! w! @
  170.     IIC_Start();                       //iic起始信号1 q- \3 h5 k7 U; e9 e! N0 L: N
  171.     IIC_Send_Byte(BHAddRead);         //发送器件地址+读标志位! i8 l. k; t: T# o$ u
  172.     IIC_Wait_Ack();                     //等待从机应答
    6 {& {# j* v" o) D; `$ K7 g
  173.     buf=IIC_Read_Byte(1);              //读取数据
    # I# o1 v2 h( H  q0 ~( \
  174.     buf=buf<<8;                        //读取并保存高八位数据
    , t. h: Z5 W7 D- j
  175.     buf+=0x00ff&IIC_Read_Byte(0);      //读取并保存第八位数据$ z7 ^) j: R5 a/ C
  176.     IIC_Stop();                        //发送停止信号5 n3 x% J1 \! v% R4 l$ B/ D
  177.     return buf;
    " {1 M1 n1 D+ ^+ p# s
  178. }# Y; f( k) o. s0 t

  179.   O" g1 t0 S0 @0 V2 _
  180. ' {& y$ i6 N; V% J( d) \9 C" [  |
复制代码

* S" C; j& a! a- E
收藏 评论0 发布时间:2022-4-11 10:16

举报

0个回答

所属标签

相似分享

官网相关资源

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