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

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

[复制链接]
STMCU小助手 发布时间:2022-4-11 10:16
  1. #ifndef __LIGHT_H
    ) g4 C9 R% H" V5 J" Z6 \5 ]; H
  2. #define __LIGHT_H
    5 d/ b. E! F; `1 Z. K9 r
  3. # W5 [, b4 }* F* E: Q' m4 Z* K
  4. #include "system.h"
    $ n9 |+ F, d* r: j& Z6 z
  5. #include "delay.h"
    4 j" q. G) A8 ]2 y) P4 }2 U
  6. " \# N8 l( W) h' e' w& {; f& s
  7. //IO方向设置9 o( w5 W8 s% ~' [- j4 n* T
  8. #define SDA_IN()  {IIC_SDA_GPIO_Port->CRH&=0XFFFFFF0F;IIC_SDA_GPIO_Port->CRH|=(u32)8<<4;}
    % g1 f6 w' T! _4 S$ X
  9. #define SDA_OUT() {IIC_SDA_GPIO_Port->CRH&=0XFFFFFF0F;IIC_SDA_GPIO_Port->CRH|=(u32)3<<4;}" u% z0 k8 |5 _" n# l, z; C

  10. * \& N% W% A! o9 r+ r6 }# s+ k
  11. #define IIC_SCL    PCout(8) //SCL5 _( t- B8 U. R" [2 U3 A
  12. #define IIC_SDA    PCout(9) //SDA         + [- G4 }3 o. A
  13. #define READ_SDA   PCin(9)  //输入SDA6 o9 x# R4 I# U" T- x5 M0 U( E1 q
  14. #define ADDR 0x23                        //0100011
    . Y# M, }2 [. }1 v) n; X
  15. . D2 p' H: V8 H3 K7 ^) c+ b! f
  16. #define BHAddWrite     0x46      // 从机地址+最后写方向位
    " q4 C& ~+ P  |$ N' Z
  17. #define BHAddRead      0x47      // 从机地址+最后读方向位7 k  Y$ v) B$ Y+ X
  18. #define BHPowDown      0x00      // 关闭模块' F  V  E, z5 c* g: U
  19. #define BHPowOn        0x01      // 打开模块等待测量指令
    ' r+ Y4 w" l; m, ^
  20. #define BHReset        0x07      // 重置数据寄存器值在PowerOn模式下有效" y( |; q- f1 U; O2 u! m# m# F
  21. #define BHModeH1       0x10      // 高分辨率 单位1lx 测量时间120ms9 h* K; i- s* u8 I
  22. #define BHModeH2       0x11      // 高分辨率模式2 单位0.5lx 测量时间120ms" P7 u$ |: P* e% Z' g; g: B
  23. #define BHModeL        0x13      // 低分辨率 单位4lx 测量时间16ms
    9 u! \6 H1 x# _+ T7 J
  24. #define BHSigModeH     0x20      // 一次高分辨率 测量 测量后模块转到 PowerDown模式6 U' w7 a: v% s. ~: N) R: q
  25. #define BHSigModeH2    0x21      // 同上类似: T0 x6 p9 ?* `; ?8 J! t
  26. #define BHSigModeL     0x23      // 上类似
    ( ^6 D; x" q/ d& T2 Z
  27. % `. b, k& N! C! F
  28. void Single_Write_BH1750(u8 REG_Address);
    ' n. d7 N1 s, u0 e! c7 T/ H
  29. void Light_Init(void);
    . w7 L( o& v9 J8 U/ Z, h! x
  30. void bh_data_send(u8 command);
    9 {3 ?/ y$ D3 A8 e4 d2 }" D
  31. u16 bh_data_read(void);
    % s2 m4 q2 C- q! e3 a! e" ?
  32. , r  r* a- e% h4 l
  33. //IIC所有操作函数
    7 Q( T% |& ?0 i7 G
  34. void IIC_Init(void);                //初始化IIC的IO口
    ; w$ L6 h4 {4 ^
  35. void IIC_Start(void);                                //发送IIC开始信号
    # O. r1 ~. N# {# ]/ z
  36. void IIC_Stop(void);                                  //发送IIC停止信号+ D/ K& C4 f2 i
  37. void IIC_Send_Byte(u8 txd);                        //IIC发送一个字节4 Q; t3 W2 W: m* P
  38. u8 IIC_Read_Byte(u8 ack);                        //IIC读取一个字节
    0 S# m4 h7 z5 @1 B# `7 R
  39. u8 IIC_Wait_Ack(void);                                 //IIC等待ACK信号) B+ K* V- ~2 A& D# G% k
  40. void IIC_Ack(void);                                        //IIC发送ACK信号9 [: \2 y# J. Z# K4 r
  41. void IIC_NAck(void);                                //IIC不发送ACK信号
    2 U/ z! C; N9 }2 o

  42. & I) E: j* Q1 q
  43. void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);0 I2 h7 R% Q* q) F" z/ P) F* X! B& J
  44. u8 IIC_Read_One_Byte(u8 daddr,u8 addr);5 ~3 {4 @. z' l8 P# b8 F6 s5 d1 x

  45. ! f$ k  U7 z/ {0 I; i; S* Z# j) Z
  46. #endif
复制代码
  1. #include "bh1750.h"( R* R+ k& ~0 m+ A. ?4 X* s6 X. ~

  2. - i) L1 B' a+ f" p$ M# [, @. O, O6 k
  3. void Single_Write_BH1750(u8 REG_Address)9 D% V, \7 m9 y% M
  4. {
      ]1 y8 a6 [0 i
  5.     IIC_Start();                  // 起始信号
    2 t% ~0 L7 q* `! u7 M
  6.     IIC_Send_Byte(BHAddWrite);    // 发送设备地址+写信号2 {& z: J9 e& r* c) R
  7.     IIC_Send_Byte(REG_Address);   // 内部寄存器地址,
    % s+ s* J8 o$ h" h5 m
  8. //  BH1750_SendByte(REG_data);       // 内部寄存器数据,/ D, J5 i  \9 u: V- n5 ^1 K( N
  9.     IIC_Stop();                   // 发送停止信号
    # {) Y! ^6 W/ D$ J6 R2 J/ i
  10. }4 z$ |) E# Z% V9 G9 Y5 j$ f5 _& X

  11. . X- M/ a3 K# u7 g  p# r! l+ I
  12. void Light_Init(void)) O0 ^# B; `' b& x( ?
  13. {
    0 w" l8 f  ]2 i$ \) K9 ?
  14.     GPIO_InitTypeDef GPIO_InitStruct = {0};
    % w# F% h* r# J6 D( ?

  15. : ?) {; ]. B& t& s7 j& q6 _: \- m
  16.     // 使能GPIOD时钟( E8 p8 Q2 b+ D
  17.     __HAL_RCC_GPIOD_CLK_ENABLE();
    4 Z* c* u% [0 X/ H3 C6 X

  18. + w9 e- ^7 B8 [6 o9 X* N/ r! }' v
  19.     // PD6和7引脚置高
    / C% C) |/ l2 R6 D
  20.     HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET);% P4 b5 B% B$ `! r9 v+ ?% x
  21. ! o9 Z- b5 V- r1 s; T. ~! W8 Y" o+ l
  22.     // 初始化引脚
    , _1 ^( [& ~. \( y+ b7 `; _$ M0 W
  23.     GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;* n8 s  m6 i& [% k5 L  m
  24.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    ) @* H7 }  g- s8 t' f- m
  25.     GPIO_InitStruct.Pull = GPIO_NOPULL;
    7 Q# ^* q; b' c7 T! M( j
  26.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    " Q4 S3 }  Z% W. I
  27.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
    . P4 S" \5 L( j. H) I1 C

  28. 0 D# E, f* H, A  X/ p
  29.     Single_Write_BH1750(0x01);
    $ k/ z& i5 y- E  ^6 w  I5 u
  30.     bh_data_send(BHPowOn);
    7 b) f! v. j- Y# v9 R+ F
  31.     bh_data_send(BHReset);: x. h; k: e: m8 C% i- }' ~
  32.     bh_data_send(BHModeL);                        //选择的是分辨率是4lx,测量时间是16ms的9 a! a' _% V7 ]: C2 r
  33.     delay_ms(180);0 y+ F) p+ U5 _' {" Y5 Q6 D
  34. }# J$ s0 A, }% L$ H! e# j6 s' d. K" }2 }
  35. , Y, f+ P# i* @2 z$ w
  36. //产生IIC起始信号
    5 f; U- m, ~1 y9 P5 j4 ~. ~) D
  37. void IIC_Start(void)- U1 H% Z1 W- f" e! G
  38. {) l- p) G; v. P: ?7 n
  39.     SDA_OUT();     //sda线输出
    ( @9 Q. d5 `  W: [
  40.     IIC_SDA=1;: J6 \3 z" J  I, u' N7 {; }
  41.     IIC_SCL=1;- X" j  ]! x0 |( \7 `
  42.     delay_us(4);
    ! }% F: m/ z4 X: e7 N# J9 F# f
  43.     IIC_SDA=0;//START:when CLK is high,DATA change form high to low! f" Y( x1 t- t: s* ?
  44.     delay_us(4);5 p) i/ o- W/ B: |4 N& G
  45.     IIC_SCL=0;//钳住I2C总线,准备发送或接收数据: I4 q" Z/ Y1 o1 a7 z
  46. }/ Q, x$ ~$ x' `. l0 K

  47. 1 H) z$ O  L9 u; T
  48. //产生IIC停止信号" O' U, Q. _3 G
  49. void IIC_Stop(void)1 z: J3 }' d# `) ]) v: z9 }& |
  50. {
    - b; j  J. a8 O4 H4 }; V$ ~
  51.     SDA_OUT();//sda线输出
      H0 o: ?# E6 _' E
  52.     IIC_SCL=0;3 B$ ^+ m. Z- ~7 c: d+ @+ g( c
  53.     IIC_SDA=0;//STOP:when CLK is high DATA change form low to high4 h; i+ d# M3 ?! M% Q+ r' x
  54.     delay_us(4);& f; y/ o/ {/ X: o4 f
  55.     IIC_SCL=1;, e# m$ y9 u& v; ?" u
  56.     IIC_SDA=1;//发送I2C总线结束信号" s7 g" K" m6 n7 r
  57.     delay_us(4);
    7 \7 D) Y/ x/ d
  58. }
    ; K9 a3 {2 B, A2 ^+ c

  59. + T1 V2 Q  a* v/ b
  60. //等待应答信号到来  `' f' b( I" N4 e* |2 R
  61. //返回值:1,接收应答失败
    + T4 e! I% Y' d
  62. //        0,接收应答成功
    1 a6 ?1 Z3 l& |2 H- @, d, u0 ^6 s
  63. u8 IIC_Wait_Ack(void); A$ t- I* n* l9 ~
  64. {
    ( e' L' D) V" y/ p
  65.     u8 ucErrTime=0;9 T8 T! Y2 y1 j) e( O0 B( e
  66.     SDA_IN();      //SDA设置为输入
    5 A  \- J2 W9 R
  67.     IIC_SDA=1;
    , d6 ?* O! c4 l9 n* _
  68.     delay_us(1);
    * }- u' _* p9 L
  69.     IIC_SCL=1;
    8 L5 T8 _; O# g( _9 e4 ^
  70.     delay_us(1);
    1 ~6 e/ R6 N6 D% _* f+ I  |& Z
  71.     while(READ_SDA)& J% i% z! c, P8 e
  72.     {
    8 b9 r; K+ g: C
  73.         ucErrTime++;
    : P3 ]9 O% `$ j. `* `
  74.         if(ucErrTime>250)
    8 F0 W: U1 k& {/ m% ], |
  75.         {
    5 a' w" r+ Y" q4 Q, n1 c
  76.             IIC_Stop();
    & S) ~' l" k! [  p1 z  r) W  Q) z- J
  77.             return 1;
    * j) q. |. O* \. l5 u) U
  78.         }5 r% }  W' j* Z) ~) x* k/ k
  79.     }% D# E2 |& }* ?; ^7 V0 c2 x
  80.     IIC_SCL=0;//时钟输出03 N% B* z$ i) h2 z1 k
  81.     return 0;
    ) X9 ?. I+ R4 q) c+ b+ \
  82. }
      ]$ V2 N. R2 \' z' ]9 E. D+ q

  83. ' q2 C, y9 o& M7 a9 S5 F
  84. //产生ACK应答
    ( m3 I4 }5 \0 \7 ]0 n! J
  85. void IIC_Ack(void)
    ' Y: P# X4 x( T! `( c* q
  86. {- |9 P$ U1 b$ v( x
  87.     IIC_SCL=0;4 _& Z& O* `# h- b4 C# Z% p( D
  88.     SDA_OUT();' T5 m8 }9 Q4 g. g7 a
  89.     IIC_SDA=0;  q) b4 E+ R& D
  90.     delay_us(2);
    9 L  M3 i, j7 q- D
  91.     IIC_SCL=1;
    8 @6 N$ j! L: }: Z
  92.     delay_us(2);
    " W- Q8 Z! L" b8 u
  93.     IIC_SCL=0;
    ' [9 l* ?& d3 p8 Y' }
  94. }
    & e9 O: ]8 o% [' i  s
  95. , P1 `. B! ^: f
  96. //不产生ACK应答
    3 d" Z: ~. O8 @- A/ y
  97. void IIC_NAck(void)
    , q) T/ O, V, d8 ~: E9 ~4 t
  98. {# D# \0 u) R- N5 s& i# M
  99.     IIC_SCL=0;0 N; ^2 ^4 V! j9 P3 a: p1 d8 q
  100.     SDA_OUT();
    1 K2 e! o7 i0 u- h! v
  101.     IIC_SDA=1;) V2 O, F9 |3 z; {
  102.     delay_us(2);( l% q) F  C. T# [
  103.     IIC_SCL=1;
    ) j8 r9 g5 E- a. I; r, a
  104.     delay_us(2);
    $ \9 `9 S; m6 q1 y
  105.     IIC_SCL=0;
    5 L7 J3 S5 Q5 R' K3 ]6 M2 l+ ~
  106. }* Z/ C- v, D* _$ y# o/ _
  107. - N8 N) x7 J+ s% \' E# u2 N
  108. //IIC发送一个字节+ W  j" L  _) d# ]7 ]. M" b
  109. //返回从机有无应答! A$ U& k7 A0 c: N4 a9 J
  110. //1,有应答
    1 A6 s9 y$ W0 y* L
  111. //0,无应答# J! a( [. @$ b' I, [% R
  112. void IIC_Send_Byte(u8 txd)
    ! c! w' q: x9 O3 p3 c# Q5 x, O/ E
  113. {0 P6 n% u* q& l2 [" j: h' M% U" L" e- {
  114.     u8 t;
    & j1 J  ~6 a) U- {
  115.     SDA_OUT();
    " B( W& z$ w9 m( Z
  116.     IIC_SCL=0;//拉低时钟开始数据传输2 L' c% i* d( w: V; b9 x/ x6 \
  117.     for(t=0; t<8; t++): S6 x' t5 F, O/ V- ?/ p  F2 V
  118.     {" E2 r" X+ r" L* `
  119.         //IIC_SDA=(txd&0x80)>>7;. x) p! ~) r2 v2 n! S- N; c5 g
  120.         if((txd&0x80)>>7)
    ( ]. O( {; M9 y+ a- D4 W
  121.             IIC_SDA=1;# f' z+ t2 S8 m+ N$ O" a- u  h- }* H
  122.         else
    & ?( `) S0 }" t
  123.             IIC_SDA=0;
    $ s9 r8 ^6 \- Q0 N* X
  124.         txd<<=1;: R9 ?6 O( T. B7 B2 X! l
  125.         delay_us(2);   //对TEA5767这三个延时都是必须的
    5 [# h5 @( \/ d. y' G' [: d* U0 O
  126.         IIC_SCL=1;' U) `% _! V' S3 L4 ~
  127.         delay_us(2);
    % h/ o2 V1 s$ B2 u3 u) @
  128.         IIC_SCL=0;
    . d1 b0 }5 L+ D7 D$ h9 [
  129.         delay_us(2);1 q6 g) X4 N' L" q
  130.     }$ b7 I  S  k% U$ A2 s+ H1 r' s5 m" r
  131. }5 `! \0 r0 |6 u: v
  132. : b/ |* a% m1 @% u5 M; `
  133. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK9 K$ L7 U7 t9 l8 \. {
  134. u8 IIC_Read_Byte(unsigned char ack)6 E0 w0 r* {9 e' G3 W9 {- w; [$ M
  135. {7 b7 X! R+ z4 l2 Z
  136.     unsigned char i,receive=0;
    % ?& G8 l' H% q- @& b3 @
  137.     SDA_IN();//SDA设置为输入
    + c* o. T; k4 @
  138.     for(i=0; i<8; i++ )
    0 z4 c+ T% c: b% {' r, |5 J9 m7 k
  139.     {
    3 y+ e3 t9 @( u% @0 s' j- S
  140.         IIC_SCL=0;
    $ f8 H' \" p2 J" b, E: \' r5 D+ Q
  141.         delay_us(2);
    2 M. [0 Q8 u! |5 |
  142.         IIC_SCL=1;+ x4 A( v$ `8 @
  143.         receive<<=1;9 y7 v2 c2 r! P( N& w" j2 M
  144.         if(READ_SDA)receive++;
    ' ?; ^6 G! S- _0 c1 H- H
  145.         delay_us(1);
    # w% U6 F3 Q2 J# s
  146.     }9 I) @' F& y+ N( F
  147.     if (!ack)
    7 ~" _  O; F- r( {! O) _% m
  148.         IIC_NAck();//发送nACK9 [9 f6 {. I1 v' U/ e2 V; O
  149.     else& B; u( C  c0 [. Q7 ?
  150.         IIC_Ack(); //发送ACK1 B: n7 N% D; I3 f- j
  151.     return receive;
    5 H, B( ?# B2 `" ^7 `
  152. }
    3 ^1 f6 G; a; |( ]- ~6 y
  153. & P' t) G4 O$ P; X1 w% q. I
  154. void bh_data_send(u8 command)
    % Z. t2 I5 ?; o; p8 g" B
  155. {# Z9 j. x/ T- j9 q+ Y, R6 o+ j( ~2 u
  156.     do0 h5 e1 y8 s1 C1 J
  157.     {, S/ q% s- f/ N! I: A
  158.         IIC_Start();                      //iic起始信号% |& v3 @6 W6 s& d& U- w
  159.         IIC_Send_Byte(BHAddWrite);       //发送器件地址% G- k3 q( s. L5 ]. w9 W2 H( ^
  160.     }
    * n8 `# ^' [* ?3 F+ ^. r
  161.     while(IIC_Wait_Ack());            //等待从机应答
    " u# }9 V* K2 r; ~
  162.     IIC_Send_Byte(command);          //发送指令
    7 C6 C9 j+ k# Q) v& l5 k& f. V/ M
  163.     IIC_Wait_Ack();                   //等待从机应答" h9 k/ j) |  b0 X" N4 `
  164.     IIC_Stop();                       //iic停止信号& ^8 `9 ~( S& ?& ?& o2 L
  165. }
    % Q# c3 H$ C6 H3 e3 a8 h
  166. 9 G; f* ~0 l7 O6 b
  167. u16 bh_data_read(void)- w, W! b3 Y7 a9 l# D
  168. {
    4 m; B& N7 |6 z" G8 j) U- C7 z& W
  169.     u16 buf;1 t# O1 M6 ?: r0 S$ p  P! Q4 H) a
  170.     IIC_Start();                       //iic起始信号6 R. ^  Z8 g4 h& P
  171.     IIC_Send_Byte(BHAddRead);         //发送器件地址+读标志位
    * p( c, M) Z7 u' Z& x
  172.     IIC_Wait_Ack();                     //等待从机应答# v" Y& w, b4 f' I+ Y9 \: l4 S
  173.     buf=IIC_Read_Byte(1);              //读取数据, i6 J' k  _1 P2 m& o" s
  174.     buf=buf<<8;                        //读取并保存高八位数据6 [$ d# `* m$ @* \/ [8 a: \8 g
  175.     buf+=0x00ff&IIC_Read_Byte(0);      //读取并保存第八位数据: q8 k* o' S' Q+ P
  176.     IIC_Stop();                        //发送停止信号" U5 i! U! ~7 k! J- f& L
  177.     return buf;
    0 y- N" N: i2 W% E
  178. }
    ) |2 ?9 R' N8 o8 J6 g, i  N' I2 t

  179. & m, ]+ ]; \- i; o* V# \

  180. ) E) W2 X) e* N% N2 D+ r
复制代码

  Z# r% x" q' Y" e6 B
收藏 评论0 发布时间:2022-4-11 10:16

举报

0个回答

所属标签

相似分享

官网相关资源

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