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

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

[复制链接]
STMCU小助手 发布时间:2022-4-11 10:16
  1. #ifndef __LIGHT_H* M) r/ [( g2 a5 X7 P1 J6 c/ {  A
  2. #define __LIGHT_H9 `* O- J1 m8 Y7 H

  3. 6 P" f2 L: I  M: T7 \+ N
  4. #include "system.h"
    * J& P$ Z  I9 v( N8 x" L! e
  5. #include "delay.h") B: N3 k) h8 t; v, U! l2 T
  6. : X2 O5 o$ D, |0 N
  7. //IO方向设置9 U& i5 x1 l6 V; k4 p- X3 }  O
  8. #define SDA_IN()  {IIC_SDA_GPIO_Port->CRH&=0XFFFFFF0F;IIC_SDA_GPIO_Port->CRH|=(u32)8<<4;}3 i) w3 F1 _: U4 u) M
  9. #define SDA_OUT() {IIC_SDA_GPIO_Port->CRH&=0XFFFFFF0F;IIC_SDA_GPIO_Port->CRH|=(u32)3<<4;}
    ) n9 u6 C7 H' O0 s8 [1 e1 S8 {
  10. 5 ^. b9 W4 l7 {- J
  11. #define IIC_SCL    PCout(8) //SCL
    , j/ N) a+ q0 S: q: f7 n  E
  12. #define IIC_SDA    PCout(9) //SDA         2 s( j) U, b# N% m% @' o
  13. #define READ_SDA   PCin(9)  //输入SDA
    % w5 ^" f1 U/ C$ l: \5 _" B: v
  14. #define ADDR 0x23                        //0100011
    & [1 T$ T: R3 ]  g* f) j! x

  15. ! r5 @; o7 c, [
  16. #define BHAddWrite     0x46      // 从机地址+最后写方向位4 W' ?: r" o& G
  17. #define BHAddRead      0x47      // 从机地址+最后读方向位2 U% A- B4 J1 `" I, F
  18. #define BHPowDown      0x00      // 关闭模块
    & |7 R' Q* g9 D- B" Y7 w( P
  19. #define BHPowOn        0x01      // 打开模块等待测量指令
    1 M: K9 ?0 n8 m6 }7 G
  20. #define BHReset        0x07      // 重置数据寄存器值在PowerOn模式下有效" h7 H9 x0 b5 P' }/ d  E( F
  21. #define BHModeH1       0x10      // 高分辨率 单位1lx 测量时间120ms2 j/ f3 i6 ^2 _- H
  22. #define BHModeH2       0x11      // 高分辨率模式2 单位0.5lx 测量时间120ms
    8 J  s& n& [/ K! _
  23. #define BHModeL        0x13      // 低分辨率 单位4lx 测量时间16ms8 o' v) |; P8 F! y$ m
  24. #define BHSigModeH     0x20      // 一次高分辨率 测量 测量后模块转到 PowerDown模式
    : c$ V" K, H0 h! z+ f1 K4 l
  25. #define BHSigModeH2    0x21      // 同上类似
    : |; Z* A5 g8 T0 W' A
  26. #define BHSigModeL     0x23      // 上类似  N9 Y# c% x9 R6 _7 U4 k

  27. ; g: N2 f! Q" `1 y1 D0 m
  28. void Single_Write_BH1750(u8 REG_Address);$ N$ u4 v$ {3 _" r( |# U( K$ P6 }
  29. void Light_Init(void);
    2 j* ?6 b' Q" ^% F+ B+ j
  30. void bh_data_send(u8 command);
    7 `5 f/ K( Y4 v9 v  w& J
  31. u16 bh_data_read(void);
    7 `3 p- S' M9 x3 C0 ^% x2 ?* ^. A9 y' }4 u
  32. 4 ^! r- f4 l3 \
  33. //IIC所有操作函数+ X- d; P8 j' s, n" R3 s: f( h
  34. void IIC_Init(void);                //初始化IIC的IO口/ P. A& X$ l) S- K: I1 l6 H8 g
  35. void IIC_Start(void);                                //发送IIC开始信号/ \  B5 o, s' Z3 v) @; }
  36. void IIC_Stop(void);                                  //发送IIC停止信号3 A( {" c8 P5 l, I! K: u
  37. void IIC_Send_Byte(u8 txd);                        //IIC发送一个字节) D5 W7 h, r$ ~7 z* i$ t5 P
  38. u8 IIC_Read_Byte(u8 ack);                        //IIC读取一个字节
    $ O) q5 B' {3 X  q
  39. u8 IIC_Wait_Ack(void);                                 //IIC等待ACK信号& Y% y# i; R2 z  m8 o. ~- O/ O
  40. void IIC_Ack(void);                                        //IIC发送ACK信号. \) s4 U+ r" z
  41. void IIC_NAck(void);                                //IIC不发送ACK信号$ q2 P7 d3 Z3 H
  42. 8 U5 }3 ^7 K5 Y' U
  43. void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
    3 D, B; N; H/ Q9 \& j1 G
  44. u8 IIC_Read_One_Byte(u8 daddr,u8 addr);- j) @: ?0 c3 y- I7 ]

  45. ; L. v$ A# G& A0 s, ]& y* A2 W* r  ]. I
  46. #endif
复制代码
  1. #include "bh1750.h"" S$ E2 m+ p* n& e7 e5 b5 D* h

  2. 8 ]# p; j$ r: i; n6 C- |4 E0 T7 @
  3. void Single_Write_BH1750(u8 REG_Address)
    ! F3 L. ~- X$ V5 u( P
  4. {4 v7 i: x0 M; k# q6 V
  5.     IIC_Start();                  // 起始信号
    8 ^6 k9 k6 k& ^' C& y  u0 t
  6.     IIC_Send_Byte(BHAddWrite);    // 发送设备地址+写信号/ a6 w' g; ]6 c- n8 U. [4 w" o
  7.     IIC_Send_Byte(REG_Address);   // 内部寄存器地址,
    : r/ V# ]  }' [5 `; N8 \
  8. //  BH1750_SendByte(REG_data);       // 内部寄存器数据,
    7 \- V5 K! D" A- M, h: G
  9.     IIC_Stop();                   // 发送停止信号/ H1 |' j4 s3 w; H+ H' K5 [  ~
  10. }* e; J  f/ P: }9 s8 n

  11. ( h7 n3 J- s' [( z- H0 h
  12. void Light_Init(void): x' y- Z3 Q9 B" O
  13. {
    - u6 h- f0 m2 \
  14.     GPIO_InitTypeDef GPIO_InitStruct = {0};0 D. s0 _2 v: d4 M7 s+ W% r
  15. & k5 F7 e. A, c7 [. @7 Y9 ]) F
  16.     // 使能GPIOD时钟
    $ `. c( m1 Q. z9 H' Z- b
  17.     __HAL_RCC_GPIOD_CLK_ENABLE();
    ; F! k* F3 d- c* T4 F- P

  18. : I" d3 X$ W& q. h) h$ T
  19.     // PD6和7引脚置高
    5 J8 @- E) @3 q% \$ w
  20.     HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET);& U, ~( L0 ]1 T- s% i4 R- w

  21. 9 z# b9 [1 j' F5 `- M
  22.     // 初始化引脚- N& T. f+ O/ f3 r0 N8 A! v
  23.     GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;
    " O+ w5 V6 r- m
  24.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    - f" S$ |6 T% I# w) r# U
  25.     GPIO_InitStruct.Pull = GPIO_NOPULL;
    ( H8 x, I* G; d! B4 n& g' \# j
  26.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;" e  N  W8 W0 r
  27.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
    & f0 ~# l  m3 {) O5 A
  28. $ n2 k$ P; N7 o
  29.     Single_Write_BH1750(0x01);
    5 J" L; B0 c3 R# v+ d, H/ s
  30.     bh_data_send(BHPowOn);
    : O* p7 }5 r6 w5 s& }" K
  31.     bh_data_send(BHReset);
    ( g6 c; v8 c) s4 v8 L. _  O
  32.     bh_data_send(BHModeL);                        //选择的是分辨率是4lx,测量时间是16ms的- S) A& K; m, k$ c1 y$ T, V
  33.     delay_ms(180);; V/ P, n! P$ e# m5 i5 |
  34. }9 d9 {  q6 e9 T
  35. 0 ?/ D: h: A. j: x, U; L3 y
  36. //产生IIC起始信号
    2 w6 W* [5 r3 o
  37. void IIC_Start(void)
    ! ~5 D/ X0 i7 ]- G8 t& N- `# j
  38. {9 P: u. Z. A; d1 Z( X9 q0 Q
  39.     SDA_OUT();     //sda线输出
      I& {1 ^( `, {
  40.     IIC_SDA=1;
    % T8 G  v: h% Z* ]
  41.     IIC_SCL=1;
    1 t. d+ M7 l9 {) b, m
  42.     delay_us(4);* p# D8 a" I& S
  43.     IIC_SDA=0;//START:when CLK is high,DATA change form high to low
    9 V0 m0 k! ~# W
  44.     delay_us(4);7 v' \5 O+ {* o9 m, z- ]/ Y- J$ c; X
  45.     IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
    8 B7 }- n" X$ y  B" i, o
  46. }  F$ K1 P. F: a1 ^  W  G

  47.   b2 l8 q' Q; ?; O+ h% T8 I; E
  48. //产生IIC停止信号
    ) I' l- I" D. w2 f. c  n! m7 s- C
  49. void IIC_Stop(void), E* _8 T# Y, [7 _. s7 ]% L
  50. {
    ) H9 X  X6 M) p( P
  51.     SDA_OUT();//sda线输出; Q! S! H# Q( m4 J5 Z0 |2 M
  52.     IIC_SCL=0;9 t$ l2 Y  s! ~
  53.     IIC_SDA=0;//STOP:when CLK is high DATA change form low to high) u6 X( c) g6 R; @  e/ e
  54.     delay_us(4);& G# X9 E; T- _& ?  x
  55.     IIC_SCL=1;
    / z+ N- C$ h" a; }
  56.     IIC_SDA=1;//发送I2C总线结束信号
    . t; |) v7 p) ?" V
  57.     delay_us(4);8 j  e4 k1 n3 U4 d6 s/ K, c$ L
  58. }
      p$ \2 ~# A5 U3 r- u4 t
  59. - j& X1 W& R! v
  60. //等待应答信号到来
    5 K3 @. g  e7 `. Y1 K2 `
  61. //返回值:1,接收应答失败
    7 n0 L) |& L$ l9 p( ^
  62. //        0,接收应答成功4 k' {$ X, Z) I, }
  63. u8 IIC_Wait_Ack(void)7 h6 I; S/ \2 L, ], Q1 S6 U4 j
  64. {  Y3 E6 x- f2 G! S! I
  65.     u8 ucErrTime=0;- j# P% I+ w$ f- J3 t; M
  66.     SDA_IN();      //SDA设置为输入- ]* r# [  R, c* m8 G  X
  67.     IIC_SDA=1;
    , y; Q% ]" f* T, F. ^' {- c7 |
  68.     delay_us(1);' X% K+ H$ l$ ]  i7 B2 q
  69.     IIC_SCL=1;6 L$ C* N, P' }. f- U! n' [* o
  70.     delay_us(1);
    * G7 I5 S9 ?* p; M
  71.     while(READ_SDA)( m, v( Y5 H0 C
  72.     {6 a9 n4 \. h4 }0 U2 [+ x4 g( s
  73.         ucErrTime++;3 I6 Z+ T& g& s* W2 a
  74.         if(ucErrTime>250)
    0 r3 z" [8 q4 a3 Z2 ^: }( c! R
  75.         {! ^" y4 T' x9 L; \, T0 F/ {
  76.             IIC_Stop();0 {% H# S2 r7 |- i" Y- w% g& ], C
  77.             return 1;. V4 h7 H) |& y1 y6 n2 W( z
  78.         }
    " B3 {2 }/ Y3 \: B  w: c! ]
  79.     }
    7 S* O' _' T, z# g- |
  80.     IIC_SCL=0;//时钟输出07 S. t+ V. m" X
  81.     return 0;
    7 e4 m2 `% H7 i, j' z
  82. }
    : C2 E: E& C1 u" C3 p+ ~  H, W

  83. , e/ \/ g/ J7 C7 e
  84. //产生ACK应答
    ' x8 o5 b/ ?8 w4 m0 }0 k
  85. void IIC_Ack(void), Y. f: b" X9 P* s6 D0 ?# D
  86. {
    & n8 T$ r5 ]6 j: a9 e" s
  87.     IIC_SCL=0;
    3 g  C( W# `/ Y+ A( d" |
  88.     SDA_OUT();
    9 \% f; \2 W5 M) C1 \2 u# g
  89.     IIC_SDA=0;# _9 v5 Q0 Z- P
  90.     delay_us(2);
    * l" @) m/ J$ k4 M2 x
  91.     IIC_SCL=1;, {. r8 P; ]2 q/ ]3 Y% A+ q
  92.     delay_us(2);
    7 ~5 ?! ^3 B% z" g, E
  93.     IIC_SCL=0;5 ]8 L& C' [( p; T% ^; a+ l9 _
  94. }
    0 a. M2 l2 i5 {) J

  95. . V7 {2 x. O* a1 i* e5 Y/ O' q9 @6 Y
  96. //不产生ACK应答+ ]0 q0 [  Y; ?- e; C% Y3 T0 h
  97. void IIC_NAck(void)
      R! Y9 G' F7 L+ u# V8 Z
  98. {
    . [; N+ g. E1 f
  99.     IIC_SCL=0;
    , D  j0 t% k$ h% K, E( O
  100.     SDA_OUT();
    " N" z* a6 ~9 n, K0 ?) z; k- }
  101.     IIC_SDA=1;
    : l6 N% E' t7 c  J
  102.     delay_us(2);
    2 q& j3 Z# J9 d6 R3 _' f
  103.     IIC_SCL=1;
      q/ Q, }8 g3 @: L( a5 W2 J7 }1 v
  104.     delay_us(2);. I$ J( k% _" ]+ G  ~- y
  105.     IIC_SCL=0;
    ) i* }; n- I. P* ]" X" A
  106. }) N& q' |0 \% E- x
  107. & R: ?% k$ D" S$ F  ]
  108. //IIC发送一个字节
    3 |3 N+ V: {. k& ?9 H
  109. //返回从机有无应答  G0 S: ]/ w$ @) A: y5 d
  110. //1,有应答, o3 c4 F; M! ^4 J, _6 n
  111. //0,无应答
    ; F- r7 ?9 ^* G* ?
  112. void IIC_Send_Byte(u8 txd)
    & M9 o+ v3 m* X5 E' M
  113. {$ M/ h1 z! V( C$ U
  114.     u8 t;
    . Y. N: |3 D8 A, }2 `2 M
  115.     SDA_OUT();
    : i0 }7 E5 c9 Z: Z: m
  116.     IIC_SCL=0;//拉低时钟开始数据传输
    ( m$ r5 X  [) L* r
  117.     for(t=0; t<8; t++)
    7 C' ?; }8 h5 T& Y
  118.     {
    7 X5 G0 f6 U6 }# d' T/ C+ W
  119.         //IIC_SDA=(txd&0x80)>>7;" P! c2 c5 T* {
  120.         if((txd&0x80)>>7)  b- V0 Z- P5 k7 r! `8 s9 D3 h
  121.             IIC_SDA=1;
    + d! G8 {' ]$ y+ S: |6 o
  122.         else. y2 \' X5 N3 M5 d6 J
  123.             IIC_SDA=0;$ A4 X1 V4 @& a( b4 c/ Z  H
  124.         txd<<=1;- F. K( C) |  i5 k
  125.         delay_us(2);   //对TEA5767这三个延时都是必须的
    1 L- y) u0 }, |' }3 y6 K
  126.         IIC_SCL=1;1 T+ [5 d; c) }2 u  |9 K
  127.         delay_us(2);$ r7 t( p5 A7 Y/ f% A+ v4 H
  128.         IIC_SCL=0;6 _: b3 c/ ]5 D8 \+ Z9 W  [3 T
  129.         delay_us(2);
    5 N# d& I2 x$ r' ^8 N
  130.     }
    0 g& ^8 p# s) T) G
  131. }
    0 A) @& `% q; {' l

  132. 9 X! @; [4 V: a4 C( D
  133. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
    ) B6 g  \  n# v9 E; q% S
  134. u8 IIC_Read_Byte(unsigned char ack)( l' Q6 w* J0 E4 O& j
  135. {* }4 n, _4 z. @* `# j
  136.     unsigned char i,receive=0;
    6 x% f& u0 u: Q) B, c
  137.     SDA_IN();//SDA设置为输入3 g4 i; {8 G( t  G
  138.     for(i=0; i<8; i++ ). O/ t- i/ p% A: v$ T
  139.     {
    . C0 B/ @% v* T6 O% v
  140.         IIC_SCL=0;, A# Q* M; N' k9 g; _2 ]
  141.         delay_us(2);& V4 N! q. C0 {5 y5 F/ t3 ]
  142.         IIC_SCL=1;
    ; G$ a1 m+ i$ E* c5 J( x2 A
  143.         receive<<=1;
    4 k: s8 m. ]/ U; K( \
  144.         if(READ_SDA)receive++;
    ( {& A$ B5 }0 M3 H  b  E! j
  145.         delay_us(1);
    5 r4 J5 k' _2 {7 x# @7 Y/ O
  146.     }
    2 _( p6 m% r2 d( X/ O1 [
  147.     if (!ack)
    ( U+ i2 T- `1 ~
  148.         IIC_NAck();//发送nACK
    # Y* O1 C' U2 z% b7 C, A
  149.     else
    & A+ r  e6 t; N5 ^
  150.         IIC_Ack(); //发送ACK
    ( [2 c/ T& k- b: v8 a7 Q  t! k* Q, m, ]
  151.     return receive;9 ]- p( c; d) I2 k0 @! G- }9 B! ~
  152. }% C+ W/ ]  D3 s. W+ \" E: t4 q
  153. 7 ^: m  Y: A# j
  154. void bh_data_send(u8 command)- S* U+ C0 K: S/ ~1 o& m$ P
  155. {
    6 i# G8 v2 M' e, Q9 U
  156.     do+ n% h9 `# k+ L" f: N/ I
  157.     {5 L+ V6 Z) y0 m- |# S* p! `) Z) o
  158.         IIC_Start();                      //iic起始信号1 f6 ]1 B4 \& b6 a5 s% g
  159.         IIC_Send_Byte(BHAddWrite);       //发送器件地址
    ! k2 R3 ]* L5 |( Z8 v  O% w
  160.     }8 J8 _+ ]! {0 w$ f! @8 E7 h$ D; X
  161.     while(IIC_Wait_Ack());            //等待从机应答
    0 M% M0 Q# n# @$ Z8 V
  162.     IIC_Send_Byte(command);          //发送指令
    9 k: V6 n; H3 L! u3 e
  163.     IIC_Wait_Ack();                   //等待从机应答5 V) _2 \" V0 o4 {4 z+ p  ]" t
  164.     IIC_Stop();                       //iic停止信号1 y+ R: P4 l4 x( b* D  l& v' D
  165. }
    & l. ]4 \& ?' ]" B. |- Q

  166. $ q2 b" a8 x! a7 X% V
  167. u16 bh_data_read(void)
    8 T  c% U& a$ [( E
  168. {
    / j  q1 n  M, J: y" n
  169.     u16 buf;, h3 j' I8 i/ B  F; j
  170.     IIC_Start();                       //iic起始信号" D3 K$ X9 K" Z  Q  Z$ h0 r* X5 |% G
  171.     IIC_Send_Byte(BHAddRead);         //发送器件地址+读标志位6 i( l( ^; ?: a$ Q7 K% l
  172.     IIC_Wait_Ack();                     //等待从机应答# A; a5 U9 q* b$ ?2 F! P
  173.     buf=IIC_Read_Byte(1);              //读取数据9 L$ k4 t; }' x. L2 w3 C- u6 J/ u
  174.     buf=buf<<8;                        //读取并保存高八位数据
    ' c# q) Z, l5 l0 ^. M  w6 O
  175.     buf+=0x00ff&IIC_Read_Byte(0);      //读取并保存第八位数据
    $ P  g) ]: _9 a0 C. f
  176.     IIC_Stop();                        //发送停止信号8 q. h" c3 g$ p) o$ m, a2 N) P5 c
  177.     return buf;2 G1 L! R4 |( r9 X% H' L
  178. }
    ) O6 q! ?5 I% w0 }; l

  179. ) b+ `3 H% E& ]+ K9 J/ o$ r

  180. * O5 I2 R4 i" r# G; U
复制代码
9 P+ J* y& v, z- m( D
赞 收藏 评论0 发布时间:2022-4-11 10:16

举报

0个回答

所属标签

相似技术帖

官网相关资源

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