- #ifndef __LIGHT_H
2 E$ j5 _* g- g! ? - #define __LIGHT_H
: y3 i, V* Z( |; e - # m5 q, F9 y0 v# C A
- #include "system.h"4 ]; v2 E. G% @$ _8 \$ U
- #include "delay.h"8 _0 r7 N$ |& I' ]! [" T! j. T9 \. h) Y& u
4 J( h( q' I% o1 L- //IO方向设置
3 ^1 C/ L' W- g F2 I& x/ A - #define SDA_IN() {IIC_SDA_GPIO_Port->CRH&=0XFFFFFF0F;IIC_SDA_GPIO_Port->CRH|=(u32)8<<4;}
' H. \2 }+ [9 R" y - #define SDA_OUT() {IIC_SDA_GPIO_Port->CRH&=0XFFFFFF0F;IIC_SDA_GPIO_Port->CRH|=(u32)3<<4;}
' Q' A: K' U/ ?- I; q4 \% w - % {. u3 v# o4 Q+ b
- #define IIC_SCL PCout(8) //SCL
- I1 e0 S; B- A- D: T - #define IIC_SDA PCout(9) //SDA
2 D: A* ~9 W! e - #define READ_SDA PCin(9) //输入SDA- Z1 U) `: b% y8 I% |* s( G
- #define ADDR 0x23 //0100011
3 `5 h2 W: @7 O1 `- O* P - ' z, E% C. G9 N' D! H. o# h
- #define BHAddWrite 0x46 // 从机地址+最后写方向位6 ?/ p4 O3 _/ R
- #define BHAddRead 0x47 // 从机地址+最后读方向位0 i3 q- c, c' G5 T0 ?2 }
- #define BHPowDown 0x00 // 关闭模块& @: h0 G) J3 l6 s4 a1 t9 b- B
- #define BHPowOn 0x01 // 打开模块等待测量指令
% N& ?7 f# b Y: [5 z6 p - #define BHReset 0x07 // 重置数据寄存器值在PowerOn模式下有效
7 E# @/ V# u+ z - #define BHModeH1 0x10 // 高分辨率 单位1lx 测量时间120ms! G0 Z; A* F: {- y) S# f
- #define BHModeH2 0x11 // 高分辨率模式2 单位0.5lx 测量时间120ms* b, ^: C0 A X) C. ^
- #define BHModeL 0x13 // 低分辨率 单位4lx 测量时间16ms# F: G, P; q/ G( z ^( ~, y
- #define BHSigModeH 0x20 // 一次高分辨率 测量 测量后模块转到 PowerDown模式8 Z3 d; A) N8 y5 C
- #define BHSigModeH2 0x21 // 同上类似
9 ~. D0 Z/ X) b) t3 j" j - #define BHSigModeL 0x23 // 上类似$ [( N! m# ~$ H4 S
' c$ d. Z- d! Q: o) t/ @% d7 s/ H- void Single_Write_BH1750(u8 REG_Address);
( a. }6 s$ j- g0 g" } - void Light_Init(void);% B# l" e8 C* P5 |8 G
- void bh_data_send(u8 command);! f. D1 T1 n) x
- u16 bh_data_read(void);
8 b& X: F8 s$ d4 K" ?8 g - 6 [) b" z9 X5 |3 `8 w
- //IIC所有操作函数
% f, ]- c- c# Y7 {* Z2 D - void IIC_Init(void); //初始化IIC的IO口. q. A3 t( y o% h
- void IIC_Start(void); //发送IIC开始信号( O$ \" {6 E/ o& Q+ X
- void IIC_Stop(void); //发送IIC停止信号 U, j" x2 P/ a& h
- void IIC_Send_Byte(u8 txd); //IIC发送一个字节
/ H& w3 E# y1 J/ Y. ^ - u8 IIC_Read_Byte(u8 ack); //IIC读取一个字节- u3 D ~7 w: P1 A9 b
- u8 IIC_Wait_Ack(void); //IIC等待ACK信号
7 }! H' L* H3 V2 x B5 m P8 _) { - void IIC_Ack(void); //IIC发送ACK信号% {9 s- s+ Z3 ~9 f
- void IIC_NAck(void); //IIC不发送ACK信号7 e# N. `* t. o. `# J7 v& M
m# {2 }& j2 j0 Q2 l; G- void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);2 K+ d# x% X% p+ x
- u8 IIC_Read_One_Byte(u8 daddr,u8 addr);
9 p* u6 p: x$ I# P6 p" n# [" {0 o - u5 {; t& _4 b
- #endif
复制代码- #include "bh1750.h"
8 ~# b6 e- b8 l6 M: U6 V - 3 h& k" ?8 F% j9 o2 [. E: J3 E
- void Single_Write_BH1750(u8 REG_Address)
+ a$ B9 e( |7 ?0 l! { - {
9 H3 A5 J7 F1 O$ n! J2 [# ^+ }" J - IIC_Start(); // 起始信号3 T$ G: s0 W, B) j$ ?
- IIC_Send_Byte(BHAddWrite); // 发送设备地址+写信号8 F% P& S' R2 Z. ~; O8 t
- IIC_Send_Byte(REG_Address); // 内部寄存器地址,
$ r, B& g' `9 F1 w - // BH1750_SendByte(REG_data); // 内部寄存器数据,
) }; @. o) q; d; X/ K6 @# e - IIC_Stop(); // 发送停止信号
% {; Z. F4 C; |- @7 ? - }3 I9 a* Y5 g! o6 @
- $ `+ B# u3 G) N! d+ x
- void Light_Init(void)
e/ l4 p. Y! q: w - {) A8 ~; P7 c# t) ?9 h. N
- GPIO_InitTypeDef GPIO_InitStruct = {0};! j& _1 e' A7 `/ p
6 \. f3 J; Q" q- // 使能GPIOD时钟
, U" ]. [, v* X# S" R5 y, Q - __HAL_RCC_GPIOD_CLK_ENABLE();
, r; S: \2 N5 C - ' P- R( j/ J- U' P0 _" r
- // PD6和7引脚置高 `/ r' c' Y' n# c
- HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET);
8 r! c4 t$ g d5 v8 z
7 F- d3 G8 C* }. H) W4 M6 e$ V3 I- // 初始化引脚+ v0 c7 {3 c5 @$ d' `9 T/ {: J, u/ M
- GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;- l- [4 c- r3 ?. ^6 T
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
% Z+ m8 g; }, J0 l+ T - GPIO_InitStruct.Pull = GPIO_NOPULL;- P( A3 U& [; _5 P, W
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;6 h" W9 @0 v3 i% {3 q9 q1 _: p
- HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);4 o! S f, z8 S9 h% N3 _
' }% i3 r) Y' X0 D% Z+ y- Single_Write_BH1750(0x01);! A: c h* ]4 t& V
- bh_data_send(BHPowOn);& ?9 V; m' Z$ y0 e
- bh_data_send(BHReset);
( p( C: s2 t# q3 S( |* a8 B a - bh_data_send(BHModeL); //选择的是分辨率是4lx,测量时间是16ms的
* v6 N$ R5 x) P, a4 N - delay_ms(180);
+ y4 K8 q; _2 b) P - }
! L( X0 ~: @" S6 ^
$ n, i. Q9 J4 }- //产生IIC起始信号
* ?1 I' z/ L7 y. P( ? - void IIC_Start(void)
6 Z; U) D, V$ X& P - {1 n) ~$ Z7 }6 l0 d3 i
- SDA_OUT(); //sda线输出
8 D' D% L3 q. z) i! _' ~9 V - IIC_SDA=1;
! j `1 {" t9 ~' ~" Z - IIC_SCL=1;3 q2 F8 @6 {6 L0 w$ Z
- delay_us(4);8 D, U# C( h+ _7 P% ^
- IIC_SDA=0;//START:when CLK is high,DATA change form high to low9 S0 ~0 I# w4 {: I
- delay_us(4);' W; \4 {( ]1 x4 m
- IIC_SCL=0;//钳住I2C总线,准备发送或接收数据% P& T1 J: t/ P/ V; L
- }
4 H6 h' o0 C) @0 d
$ V* @+ {5 F2 L1 d/ B6 C- //产生IIC停止信号
1 b0 S$ \( Z# R P; y% k+ Y8 @& I! K - void IIC_Stop(void)
6 m5 s: `! J' I8 m6 | - {
' R- B+ k: g3 v7 A1 E - SDA_OUT();//sda线输出5 {- g2 |/ @/ }/ N' O
- IIC_SCL=0;; s4 @" |; n; V# C, c3 Z
- IIC_SDA=0;//STOP:when CLK is high DATA change form low to high8 M d: o) n6 y% y% F% E
- delay_us(4);
$ B- j' C2 {' T' t( ^ - IIC_SCL=1;0 p G9 M, Y1 z. G9 I
- IIC_SDA=1;//发送I2C总线结束信号 {' @$ b. X- O/ U/ b; C
- delay_us(4);: i5 t0 l0 V- T6 U! S
- }
% N2 l' Z* M1 S0 J8 U7 C - 5 ^4 t! f e2 K0 r. |' Y
- //等待应答信号到来
$ r* [: A2 S1 O) ^( N4 o6 m - //返回值:1,接收应答失败- e8 U2 M" Z- |' C% Y# ^
- // 0,接收应答成功5 s! m1 p% Y/ k [7 @1 P1 e
- u8 IIC_Wait_Ack(void)& v# f& O i/ _) d& ]% Q
- {
7 j7 S1 ?7 T- h - u8 ucErrTime=0;
% ^0 L; \6 Q1 o b# B1 v: M - SDA_IN(); //SDA设置为输入
; u0 w7 l3 g; z9 } - IIC_SDA=1;' S) N; I7 j: ~7 z2 }! c
- delay_us(1);! z" _) k! g7 f! S G& ]" q( D( O! p
- IIC_SCL=1;
K [; |5 \! r! g - delay_us(1);
2 e9 P+ \8 n; ^* I& f- h+ o - while(READ_SDA)
, Y+ g! Q' ~2 r% `, S - {
& I+ h- t* j$ W0 ^" k3 Y - ucErrTime++;
5 h6 _/ m J! ? _- ` - if(ucErrTime>250)
' \4 H/ D0 o& o. ~; v8 N9 v - {- g& R/ V" P" |4 U- w
- IIC_Stop();/ ] ?% h' T8 Y
- return 1;
3 j, M! u! L0 R# R, E p. b" F& y - }
t* s# M% K- K& d1 J# ` - }
: s+ Y) P( I0 e2 ~3 r - IIC_SCL=0;//时钟输出0, M4 F% n$ D9 B/ @, m
- return 0; F4 [8 ~0 w& Q! w& a' [* o9 b
- }8 ?, [, z8 _2 M: a# d* A
5 q' |/ n: w+ X" n' g- //产生ACK应答: M+ {' r( B, e& @) K, u- W% j5 \( D
- void IIC_Ack(void)
\( z& f% ^. u - {$ g; l1 x4 P! D* E' o5 t
- IIC_SCL=0;: g( P) L1 L0 [: I! m ^
- SDA_OUT();
5 g# {8 D! t/ C. `7 M - IIC_SDA=0;
7 l& |/ n7 O; v6 X* @! X - delay_us(2);5 n( y" l9 B4 \: ?2 p" A3 f
- IIC_SCL=1;. A) Z% J& \* W; w
- delay_us(2);# F L4 L( V$ H' v
- IIC_SCL=0;1 K! x: L1 a& U* V2 ]: ?+ n- `. N
- }
9 H& c1 ]" E6 W. Y2 l - % C: W- P; ?; F6 e6 [! v
- //不产生ACK应答: k% p, f7 J0 z
- void IIC_NAck(void)
! |4 Z8 @9 ~3 o; z - {) c" J) G' A" s: V8 Z
- IIC_SCL=0;6 o; L# j! R. N
- SDA_OUT();: b8 Z4 B/ ^0 {6 U* @, w) f
- IIC_SDA=1;; b; _5 p9 |3 C+ x1 T
- delay_us(2);) W" \2 A7 e0 K! \
- IIC_SCL=1;
: b0 g4 N9 ]& l8 p7 F - delay_us(2);* y0 Q6 g% w/ w
- IIC_SCL=0;" [9 v; ^$ G3 C d& m' d' r
- }
( k$ P% G/ n q) p% U" d; S9 @
, d5 j4 }. t) ~' [, F1 H8 Z- //IIC发送一个字节
" Y7 c: c4 d+ \ - //返回从机有无应答! P# e4 g: \4 p& ~2 _4 b
- //1,有应答
; y7 e! p' R+ C, u. W( z - //0,无应答
% B( }7 e a" I$ S; h - void IIC_Send_Byte(u8 txd)/ o4 X& E* ]! S2 h3 H& N9 I% T
- {8 l& b4 n$ E$ L: v$ S
- u8 t;
2 O0 ~. c& b, V3 c) @ - SDA_OUT();
$ R K) j9 s2 ~! J- o - IIC_SCL=0;//拉低时钟开始数据传输* ]2 }( e4 f. B# n2 v) l4 u, {5 P5 Z
- for(t=0; t<8; t++)& w5 d7 @4 R! d
- {7 h; Z+ q1 P; m( t! ]
- //IIC_SDA=(txd&0x80)>>7;$ V4 d# E* E/ K$ d5 m5 _
- if((txd&0x80)>>7)$ t% A! S4 H0 D; b) k" C
- IIC_SDA=1;" u2 @& a: c8 |& x8 ]0 i% D$ s
- else
2 R9 F+ n4 x5 H; Z$ N4 p - IIC_SDA=0;3 y# v, g7 F9 I4 s8 A$ L2 r
- txd<<=1;
. q- t$ o" t" P - delay_us(2); //对TEA5767这三个延时都是必须的
9 `1 m/ ]; \9 o: E7 { - IIC_SCL=1;
9 N5 _! T- h0 c7 g, I( p# D - delay_us(2);
" n3 L! s4 w& ~% A0 j - IIC_SCL=0; r4 M, S% ~7 g; k) S2 Z' W: v
- delay_us(2);
! M# ~+ v# D& R+ a' j - }
U% A; ?5 z8 d" ? - }- w1 j0 `: U3 }/ o8 B
$ x4 s5 a$ k' x2 ]- //读1个字节,ack=1时,发送ACK,ack=0,发送nACK+ K; N0 a9 y$ Q+ ]0 u
- u8 IIC_Read_Byte(unsigned char ack)& v/ y0 l8 a$ Y( @
- {2 i d# {- j; m4 A& r/ M4 e m
- unsigned char i,receive=0;) p3 j0 v, a9 `+ V5 L& i: Y3 r
- SDA_IN();//SDA设置为输入
& k- }0 j0 M/ _' d' g% O Q& Z; a - for(i=0; i<8; i++ )
9 V' Q8 ]$ {: F% v: g - {/ D! k/ y# h3 J# \
- IIC_SCL=0;
7 }9 V. w8 ~3 h - delay_us(2);
! D- D4 [) ~9 l5 F - IIC_SCL=1;
( H+ C, {* s1 J/ x - receive<<=1;$ `( T: p) K; f+ O4 f$ {
- if(READ_SDA)receive++;
# S/ s" y9 S- R - delay_us(1);$ h, L8 X. E* x) [: j0 u
- }
2 A* T0 W0 ` V! h - if (!ack)3 q0 @4 [( C G) l) c; B; U, y
- IIC_NAck();//发送nACK
2 H3 h. I3 e6 ~( H) z! \ - else
& ?' N: v2 R, i' s/ ]9 G5 l- A - IIC_Ack(); //发送ACK0 W/ |3 F; T7 d! v9 R! M
- return receive;$ r# V/ l7 R( [1 s5 G, u. E1 [
- }
! j: r; B" r$ z1 Z$ x5 r
. u6 I t: T) E) B- void bh_data_send(u8 command)
' L* b9 x+ W; k& O+ v - {
+ e2 h; f3 |1 f8 e8 w - do1 s8 l u1 r, Q# R, i
- {, _/ G6 @3 y" e6 G( e4 {4 {
- IIC_Start(); //iic起始信号
! n7 E; y3 Z2 a' g - IIC_Send_Byte(BHAddWrite); //发送器件地址
' \% |. E: W; d5 _" `, c - }
! V+ f$ f* J$ @: U T) a- L+ J - while(IIC_Wait_Ack()); //等待从机应答
. l! T/ Q* D% i - IIC_Send_Byte(command); //发送指令 n5 ~, M+ x+ g4 n/ ^1 G
- IIC_Wait_Ack(); //等待从机应答
$ j" t b8 {. c% J* `, E, @ - IIC_Stop(); //iic停止信号/ p* H& Z2 D4 Z
- }
4 p( \- M8 E2 B+ _3 s - 7 x4 K" @2 L$ u' z
- u16 bh_data_read(void)
. u K" u z2 t; N - {% W. e" S. P( b' ^ B) u
- u16 buf;
! o4 s0 a- e6 R! w! @ - IIC_Start(); //iic起始信号1 q- \3 h5 k7 U; e9 e! N0 L: N
- IIC_Send_Byte(BHAddRead); //发送器件地址+读标志位! i8 l. k; t: T# o$ u
- IIC_Wait_Ack(); //等待从机应答
6 {& {# j* v" o) D; `$ K7 g - buf=IIC_Read_Byte(1); //读取数据
# I# o1 v2 h( H q0 ~( \ - buf=buf<<8; //读取并保存高八位数据
, t. h: Z5 W7 D- j - buf+=0x00ff&IIC_Read_Byte(0); //读取并保存第八位数据$ z7 ^) j: R5 a/ C
- IIC_Stop(); //发送停止信号5 n3 x% J1 \! v% R4 l$ B/ D
- return buf;
" {1 M1 n1 D+ ^+ p# s - }# Y; f( k) o. s0 t
O" g1 t0 S0 @0 V2 _- ' {& y$ i6 N; V% J( d) \9 C" [ |
复制代码
* S" C; j& a! a- E |