- #ifndef __LIGHT_H
8 R; w& C- l& o; F* f- n. N# c - #define __LIGHT_H
! _) P/ U2 p! E! z5 q - . x% P+ D/ P+ S0 k
- #include "system.h"
+ r7 o# h3 n, J/ p - #include "delay.h"
0 m6 U2 y% Y9 l* X - ( C6 K- p* `7 \" c
- //IO方向设置
# h- d- E4 R! d$ ~ - #define SDA_IN() {IIC_SDA_GPIO_Port->CRH&=0XFFFFFF0F;IIC_SDA_GPIO_Port->CRH|=(u32)8<<4;}
( n T8 P8 }7 U - #define SDA_OUT() {IIC_SDA_GPIO_Port->CRH&=0XFFFFFF0F;IIC_SDA_GPIO_Port->CRH|=(u32)3<<4;}- Y7 P7 W" i! s
- + t3 u5 I u f% N; _8 D8 [
- #define IIC_SCL PCout(8) //SCL
% I$ J0 R4 c0 t4 Y - #define IIC_SDA PCout(9) //SDA Y1 Y# I8 Q# @7 r
- #define READ_SDA PCin(9) //输入SDA1 X% u3 _, }6 g8 V% c
- #define ADDR 0x23 //0100011
# N: M+ v9 |; y; _. [. ~/ _/ r( ?
9 ^. f1 w+ L3 A- #define BHAddWrite 0x46 // 从机地址+最后写方向位6 P7 _- E% n% [/ W
- #define BHAddRead 0x47 // 从机地址+最后读方向位
5 h( h2 P! |9 r" b - #define BHPowDown 0x00 // 关闭模块
2 r% ]# F. G4 E& a T - #define BHPowOn 0x01 // 打开模块等待测量指令: L9 J- n# W/ {
- #define BHReset 0x07 // 重置数据寄存器值在PowerOn模式下有效
; l) {+ _, [1 s- _ - #define BHModeH1 0x10 // 高分辨率 单位1lx 测量时间120ms+ _8 v! W4 n1 j- D
- #define BHModeH2 0x11 // 高分辨率模式2 单位0.5lx 测量时间120ms
* \& G( L5 y" E; b! p - #define BHModeL 0x13 // 低分辨率 单位4lx 测量时间16ms1 ~6 l3 q+ n' J+ q; y
- #define BHSigModeH 0x20 // 一次高分辨率 测量 测量后模块转到 PowerDown模式2 b; J" l; w9 }8 s
- #define BHSigModeH2 0x21 // 同上类似
: u4 N0 u) n% Y% c - #define BHSigModeL 0x23 // 上类似8 r8 v) T7 Q1 O J( }/ s
( T( x9 @9 R0 s' ]9 j+ P- void Single_Write_BH1750(u8 REG_Address);8 ?: X: g% j8 a! G1 a3 B) u4 q
- void Light_Init(void);
5 R( e( `8 I8 s5 {$ I8 k - void bh_data_send(u8 command);; K& o5 U" u5 W v/ `$ R ^
- u16 bh_data_read(void);
) ~2 ~2 ?, ^. J w1 W1 _7 i* _3 k - 5 P! l# B3 l9 C
- //IIC所有操作函数
( ?- V1 v* P' ] N" _8 \! [4 n - void IIC_Init(void); //初始化IIC的IO口
+ L3 N+ r* \# h/ F7 `+ U* O5 Q - void IIC_Start(void); //发送IIC开始信号6 B* d7 L& W5 J6 G
- void IIC_Stop(void); //发送IIC停止信号) d) v: z# Y- N9 U1 t
- void IIC_Send_Byte(u8 txd); //IIC发送一个字节
) i3 V+ e0 n- m& G' f( ]) ?; S - u8 IIC_Read_Byte(u8 ack); //IIC读取一个字节
9 K& G" d, a7 ?; C, [" t; r" V - u8 IIC_Wait_Ack(void); //IIC等待ACK信号) U8 u/ @( j- O- C, S
- void IIC_Ack(void); //IIC发送ACK信号
9 M( h+ o, Z! ~7 f, a - void IIC_NAck(void); //IIC不发送ACK信号- `& m! o' b: C. g9 d6 M, q
- 4 ] n& {6 {2 H5 s
- void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);" R9 ]2 T2 t) N% b( ?5 `
- u8 IIC_Read_One_Byte(u8 daddr,u8 addr);
9 J' T+ N1 o: R; i3 j0 N8 C
# \. \; V+ G$ a$ V `- #endif
复制代码- #include "bh1750.h"$ X8 b# E8 W. K3 ^- V/ j! N
- $ _5 N8 } c: ~
- void Single_Write_BH1750(u8 REG_Address)
7 y7 A! _& C5 a1 ?& z/ a/ q: y! O! H% v - {
3 _7 j, ^+ x/ D& i% J) p( h - IIC_Start(); // 起始信号
" z$ c! D, r. k, b - IIC_Send_Byte(BHAddWrite); // 发送设备地址+写信号
" D4 l8 J5 w& f4 ~ - IIC_Send_Byte(REG_Address); // 内部寄存器地址,
: i" |2 ^% I% |& I' U2 }1 b - // BH1750_SendByte(REG_data); // 内部寄存器数据,. a" v$ J, T. o) k1 w
- IIC_Stop(); // 发送停止信号
$ g3 a' g- ` p- m - }
6 X) z$ [' V! n9 ~5 M) f - : F7 c) o3 P8 j, ]. R
- void Light_Init(void)' t3 b5 W& J) y O/ s: [
- {; K S1 o1 n, I
- GPIO_InitTypeDef GPIO_InitStruct = {0};# P2 E, l, p" H- T Z! P- j
% p2 f" s, v& M q8 t% ] B- // 使能GPIOD时钟1 s& _4 T' `' M1 `# W( s
- __HAL_RCC_GPIOD_CLK_ENABLE();& B4 R2 A H, S! Y% h. |
- / \2 Q) H5 y" K {3 ]
- // PD6和7引脚置高 |; f# T! Q7 H
- HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET);
& j8 B2 W' f9 W6 @ - 3 d: C* r3 P! F, n
- // 初始化引脚: ~9 i5 t) `& I/ B' U6 W9 Z
- GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;( |) S8 d+ ~% {' k3 O$ v1 l
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
0 d! s9 r% Z$ K G) x% W - GPIO_InitStruct.Pull = GPIO_NOPULL;6 g# Y3 A7 r1 i4 H% f, o* x0 s
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
8 Q( |$ N2 d, f: z! @2 r - HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);* i* V) ]8 g5 n% J, v
- 6 a; Y" Y, i" V: D, ?& T
- Single_Write_BH1750(0x01);2 f( d @$ H8 d7 M! [ I* w
- bh_data_send(BHPowOn);! P0 o) L. l8 F4 C4 T2 T; h- C
- bh_data_send(BHReset);
$ a) k' k" k# X* \- p$ T - bh_data_send(BHModeL); //选择的是分辨率是4lx,测量时间是16ms的
$ F" J- S5 {( f" U - delay_ms(180);
l8 G7 ?2 i2 Q: ? e - }( Z+ O& v A2 x7 H, m! }' s K
" s/ G" _( b$ A7 }) K. Y" W, i4 U- //产生IIC起始信号
, U0 _5 ?: F( F - void IIC_Start(void)! t" e) N( d3 a! e
- {
, K# h# I# O/ e# J2 w* Z - SDA_OUT(); //sda线输出- _: z! q2 Z9 P' d" C
- IIC_SDA=1;
' u$ f$ w) W' ]8 l7 G4 N& H4 A - IIC_SCL=1;, Z+ m3 Q8 z; ^0 H$ N. y, |2 T
- delay_us(4);
7 o# }& r& t- w+ U - IIC_SDA=0;//START:when CLK is high,DATA change form high to low2 P- ?- F9 g6 K4 G. ~
- delay_us(4);
0 \# \& ^" s7 Y% J - IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
0 K7 R8 O# H& o) i# @* G - }- d" t' p6 ?" Y/ @4 Q5 \
, |' a) C4 `. G1 V6 N6 i- //产生IIC停止信号
% y; j: g# ^! q C, f - void IIC_Stop(void)* p% C! \& P* z
- {4 Z# [8 `) e0 ]6 l- L% [5 `
- SDA_OUT();//sda线输出
( X3 \9 F2 [/ [" {0 e4 G' E9 E2 V - IIC_SCL=0;
6 W2 t; }% ~0 a5 t7 e - IIC_SDA=0;//STOP:when CLK is high DATA change form low to high& {9 N1 {' `+ T- }( S3 Z/ D
- delay_us(4);
i3 i$ y# V+ B7 A% E8 E1 ~ - IIC_SCL=1;
6 T8 m" n& A! s9 B. B - IIC_SDA=1;//发送I2C总线结束信号
* l( N0 ^4 N3 t& W- x: f: s# z- U8 L - delay_us(4);, P$ Y: W. y) \2 j0 o2 B
- }
0 J6 p9 c* d7 r! h - 1 ?; J& D6 a9 ^, X
- //等待应答信号到来" m! N' A$ [5 x+ p; n
- //返回值:1,接收应答失败
1 `5 G O8 S( m. e$ @ Y - // 0,接收应答成功
( f- | p9 K; }& P1 B) m/ X) t$ P - u8 IIC_Wait_Ack(void)! y2 `9 ^0 F, Z# D+ x
- {
5 |9 m, D3 ^8 \+ S. C5 d2 h - u8 ucErrTime=0;- W7 l g9 t% @
- SDA_IN(); //SDA设置为输入+ A* B0 {, B8 w- P' Q, W, e
- IIC_SDA=1;
; }7 U# [8 L5 E4 C: N4 Y* i - delay_us(1);6 _ T4 n' O# M3 O3 p( N' X
- IIC_SCL=1;
. ?( m* k7 M! f/ x - delay_us(1);9 p# p3 t$ H2 t3 n/ [# ?/ U
- while(READ_SDA)8 V- z# o3 M2 S6 c4 E' ]6 p4 b
- {
8 \& y* b( X$ z/ F* V - ucErrTime++;
# p3 } f) R2 q; c6 e - if(ucErrTime>250)2 P4 T; g' d; P9 g4 b
- {
0 |7 D6 `9 v& d7 a1 M - IIC_Stop();
- G8 Q; C' Z) e3 } - return 1;5 ~# f) E0 d5 j0 {* U7 Z
- }
$ D; V0 [, t1 @ - }
+ o5 U7 g" q9 I) H: m ` - IIC_SCL=0;//时钟输出03 S- d) @$ d, d8 J7 o
- return 0;
5 j7 b; Y$ O3 D/ h5 | - } [$ t; L) a Z/ c9 s9 v( r: u, h5 r
- ( u6 {% r- U$ F# Z6 n4 o2 d" f }6 [
- //产生ACK应答
: Z( d" m& M* K - void IIC_Ack(void)
5 ?, ~- l8 [& ~" O0 X5 _ - {
* j/ j3 ^6 x: P - IIC_SCL=0;
: N; G" G1 n+ H6 Y) H8 B - SDA_OUT();
8 {- X/ R( U' x6 j5 l+ N6 b - IIC_SDA=0;$ b& W7 w. ~; ]/ h$ [8 @
- delay_us(2);% d/ v( N* R3 @4 ?! L6 z. j
- IIC_SCL=1;
& U! O- g$ l- b! ~( N - delay_us(2);% G1 e9 ~# n/ k* A# l3 c. O
- IIC_SCL=0;
, C3 {# ~; d0 r/ A( M2 H - }
! \( ~) C2 _. n3 c3 i9 Y# u( L
/ x( Z* O* s+ x3 x1 b c, U- //不产生ACK应答- s- J+ }; n4 Q; z% D
- void IIC_NAck(void)5 g: H, I1 j, h* E2 D; z
- {
6 Y; l+ Q2 W4 s& ^+ w1 f5 K - IIC_SCL=0;$ o+ j2 \ m0 H# A9 |
- SDA_OUT();6 R, m( V8 i6 ^& q! Z/ l
- IIC_SDA=1;
0 T& F+ ?$ H8 t$ i r3 i6 o+ ~% k# B - delay_us(2);
+ g: x8 q2 I1 P+ N% I9 W - IIC_SCL=1;
; c) v% B% E6 V) Q4 ~* Y# q) a - delay_us(2);& @, i+ D7 F4 ~
- IIC_SCL=0;
5 N3 X5 s1 b) @2 a - }- Q. l0 b8 n8 l4 E+ a* A
- X) u1 y/ {8 j3 X+ b
- //IIC发送一个字节6 r2 E0 \+ w" t' |4 O
- //返回从机有无应答
# J2 ^" ^" n; S9 v, w* J. U - //1,有应答
# M& @' _% k$ k - //0,无应答% i+ ]* L3 J. w3 n; \
- void IIC_Send_Byte(u8 txd)6 @7 f- J( f m' J
- {, A7 H2 {( E4 T/ P' E: S
- u8 t;5 R/ G1 k, N, C
- SDA_OUT();8 t2 o3 b: l# l9 b
- IIC_SCL=0;//拉低时钟开始数据传输1 [! m% [1 A2 O" n, G
- for(t=0; t<8; t++)+ t K6 a- W1 T8 m( E- Q5 f
- {
; f$ H! ~8 a; M) }. n" P5 q( m0 R# Z - //IIC_SDA=(txd&0x80)>>7;
% E* Q5 K- e3 C9 y. Z - if((txd&0x80)>>7)* w6 x Q# d" s4 J/ u( \9 g2 e, Q
- IIC_SDA=1;
. _! X5 k, @& R+ ` - else
: r; p2 ]- V4 g+ z! E - IIC_SDA=0;# f! }5 u' |" l) r' [
- txd<<=1;) J7 _6 Q& ] A0 v
- delay_us(2); //对TEA5767这三个延时都是必须的
) ~! ?( u! c+ s" p L! T - IIC_SCL=1;
/ w; _8 K) Q# a - delay_us(2);: R5 M/ G' r5 B+ f1 T: k2 }
- IIC_SCL=0;, E% M6 @; Q9 a6 T" g0 d
- delay_us(2);- V4 x; @/ L2 z7 t( j/ s
- }# ~, P' k0 ~; m. R+ s
- }
( T/ s+ a3 w' \% |. h- {* U7 B
' B" K5 l* m5 T+ |! R6 y+ J- //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
0 W9 P' z- Y" P - u8 IIC_Read_Byte(unsigned char ack)
9 H5 `$ C9 [: U- {2 \0 d! \" J$ s$ ? - {
& i; L/ B/ g( b4 F - unsigned char i,receive=0;
3 J) [# C7 C' [. ?1 L$ C# x - SDA_IN();//SDA设置为输入
! G4 S2 }0 {& @3 ~/ d1 D* e( @6 U: A - for(i=0; i<8; i++ )
' D, G8 H# }5 W1 B0 D% q - {
+ z; H. x0 }" B0 Y - IIC_SCL=0;/ [3 b$ O! q& O
- delay_us(2);( {/ U9 y! q* V% |0 V I! c
- IIC_SCL=1;
1 u, Z6 {1 \" f# J& T; E - receive<<=1;% Y& E* `& G6 _0 i3 Z
- if(READ_SDA)receive++;" k1 S3 ~' q# @' z7 e) P: D. C
- delay_us(1);2 d: q+ _4 N1 U7 A0 r" P" f
- }
, ^+ t, ~9 w- y) } - if (!ack), K% X, F' l# l& U ]" [6 o5 B0 e
- IIC_NAck();//发送nACK& s( J& @$ m5 D. ~3 `* i6 S( O
- else
# j. b. R9 ^/ J/ X/ D6 _- w( e- x, X+ w - IIC_Ack(); //发送ACK3 Z3 K( p; h" d& N- u5 U( N
- return receive;
4 [. Z2 u) V' h, h) V* a+ {/ K - }
( Q+ E$ e. O% i# x, U
1 V I- L# @" ]- void bh_data_send(u8 command), R0 G0 y$ L9 g/ K) C
- {
% z" o2 k" [( x* ` - do
/ Y, `5 ^- g5 A7 \2 x0 e5 F - {' x! V; V, ~& @, {( P0 t
- IIC_Start(); //iic起始信号" ^' \/ A; k$ B$ ]
- IIC_Send_Byte(BHAddWrite); //发送器件地址
\/ P* ]+ i# i$ I4 K9 G& z - }
" R: `% Z) m# o' ~4 Z2 r - while(IIC_Wait_Ack()); //等待从机应答: {$ a ]4 c; ? C+ a7 b% f- q" V- ?
- IIC_Send_Byte(command); //发送指令4 j! D7 R: W6 X$ j) ? E8 E; W
- IIC_Wait_Ack(); //等待从机应答
3 x: y7 k" k; C - IIC_Stop(); //iic停止信号
# u/ z% i v! M/ v7 _ - }7 w' `- c; e3 [2 w2 O( x+ J
" r: }0 c: S. A% R2 C3 ?- J& w3 S- u16 bh_data_read(void)' J: _9 l' _7 L) [6 u) ^+ u# B
- {
7 O$ F0 R" f* N y; ~ - u16 buf;
! k1 d' u/ X9 e5 s9 e8 I4 ` - IIC_Start(); //iic起始信号
# B+ g" ?2 O- d& g l - IIC_Send_Byte(BHAddRead); //发送器件地址+读标志位; G; ^' m/ J8 U) ~0 Z
- IIC_Wait_Ack(); //等待从机应答
1 F+ h/ Q5 Y2 J- a% r* P t, d. g - buf=IIC_Read_Byte(1); //读取数据2 B; T7 F; R+ T* J
- buf=buf<<8; //读取并保存高八位数据
2 @' K) }1 t9 }/ r5 | - buf+=0x00ff&IIC_Read_Byte(0); //读取并保存第八位数据( J& D" A, o/ c E% d# s4 d- n( X
- IIC_Stop(); //发送停止信号! B. L5 b" z7 d' }0 X% }
- return buf;
2 |% x. h$ B0 f$ J( x - }
' M; o: A: ? z9 j3 p' w. c+ Y - & ^" l1 j" @* i/ L
4 @( p7 u* }: E- T
复制代码
( T) b$ m; U: r |