|
1 | | -/******************************************************************************** |
2 | | - * 文件名称 :BH1750.c |
3 | | - * 作 者:物联网俱乐部 |
4 | | - * 版 本:V1.0 |
5 | | - * 编写日期 :2018-4-1 |
6 | | - * 功 能:EVB_M/H 光照强度扩展板驱动 |
7 | | -********************************************************************************* |
8 | | - * 说 明 :本例程配套物联网俱乐部EVB_M1开发板使用 |
9 | | - * |
10 | | - * 淘 宝:https://shop128001708.taobao.com/ |
11 | | - * 论 坛:bbs.iot-club.cn |
12 | | -*********************************************************************************/ |
13 | | - |
14 | | -#include "bh1750.h" |
15 | | -#include "stm32l4xx.h" |
16 | | -#include "delay.h" |
17 | | - |
18 | | -float result_lx=0; |
19 | | -uint8_t BUF[2]={0}; |
20 | | -uint16_t result=0; |
21 | | - |
22 | | - |
23 | | -/** |
24 | | - * 函数功能: 配置I2C总线的GPIO,采用模拟IO的方式实现 |
25 | | - * 输入参数: 无 |
26 | | - * 返 回 值: 无 |
27 | | - * 说 明:无 |
28 | | - */ |
29 | | -static void I2C_InitGPIO(void) |
30 | | -{ |
31 | | - GPIO_InitTypeDef GPIO_InitStruct; |
32 | | - |
33 | | - /* 打开GPIO时钟 */ |
34 | | - I2C_GPIO_CLK_ENABLE(); |
35 | | - |
36 | | - GPIO_InitStruct.Pin = I2C_SCL_PIN|I2C_SDA_PIN; |
37 | | - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; |
38 | | - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH ; |
39 | | - HAL_GPIO_Init(I2C_GPIO_PORT, &GPIO_InitStruct); |
40 | | - |
41 | | - I2C_SCL(HIGH); |
42 | | - I2C_SDA(HIGH); |
43 | | -} |
44 | | - |
45 | | -/** |
46 | | - * 函数功能: CPU发起I2C总线启动信号 |
47 | | - * 输入参数: 无 |
48 | | - * 返 回 值: 无 |
49 | | - * 说 明:无 |
50 | | - */ |
51 | | -void I2C_Start(void) |
52 | | -{ |
53 | | - /* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */ |
54 | | - SDA_OUT(); |
55 | | - I2C_SDA(HIGH); |
56 | | - I2C_SCL(HIGH); |
57 | | - delay_us(4); |
58 | | - I2C_SDA(LOW); |
59 | | - delay_us(4); |
60 | | - I2C_SCL(LOW); |
61 | | -} |
62 | | - |
63 | | -/** |
64 | | - * 函数功能: CPU发起I2C总线停止信号 |
65 | | - * 输入参数: 无 |
66 | | - * 返 回 值: 无 |
67 | | - * 说 明:无 |
68 | | - */ |
69 | | -void I2C_Stop(void) |
70 | | -{ |
71 | | - /* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */ |
72 | | - SDA_OUT(); |
73 | | - I2C_SCL(LOW); |
74 | | - I2C_SDA(LOW); |
75 | | - delay_us(4); |
76 | | - I2C_SCL(HIGH); |
77 | | - I2C_SDA(HIGH); |
78 | | - delay_us(4); |
79 | | -} |
80 | | - |
81 | | -/** |
82 | | - * 函数功能: CPU产生一个时钟,并读取器件的ACK应答信号 |
83 | | - * 输入参数: 无 |
84 | | - * 返 回 值: 返回0表示正确应答,1表示无器件响应 |
85 | | - * 说 明:无 |
86 | | - */ |
87 | | -uint8_t I2C_WaitAck(void) |
88 | | -{ |
89 | | - uint8_t ucErrTime=0; |
90 | | - SDA_IN(); |
91 | | - I2C_SDA(HIGH); /* CPU释放SDA总线 */ |
92 | | - delay_us(4); |
93 | | - I2C_SCL(HIGH); /* CPU驱动SCL = 1, 此时器件会返回ACK应答 */ |
94 | | - delay_us(4); |
95 | | - while (I2C_SDA_READ()) /* CPU读取SDA口线状态 */ |
96 | | - { |
97 | | - ucErrTime++; |
98 | | - if(ucErrTime>250) |
99 | | - { |
100 | | - I2C_Stop(); |
101 | | - return 1; |
102 | | - } |
103 | | - } |
104 | | - |
105 | | - I2C_SCL(LOW); |
106 | | - return 0; |
107 | | -} |
108 | | - |
109 | | -/** |
110 | | - * 函数功能: CPU产生一个ACK信号 |
111 | | - * 输入参数: 无 |
112 | | - * 返 回 值: 无 |
113 | | - * 说 明:无 |
114 | | - */ |
115 | | -void I2C_Ack(void) |
116 | | -{ |
117 | | - |
118 | | - I2C_SCL(LOW); |
119 | | - SDA_OUT(); |
120 | | - I2C_SDA(LOW); /* CPU驱动SDA = 0 */ |
121 | | - delay_us(2); |
122 | | - I2C_SCL(HIGH); /* CPU产生1个时钟 */ |
123 | | - delay_us(2); |
124 | | - I2C_SCL(LOW); |
125 | | -} |
126 | | - |
127 | | -/** |
128 | | - * 函数功能: CPU产生1个NACK信号 |
129 | | - * 输入参数: 无 |
130 | | - * 返 回 值: 无 |
131 | | - * 说 明:无 |
132 | | - */ |
133 | | -void I2C_NAck(void) |
134 | | -{ |
135 | | - |
136 | | - I2C_SCL(LOW); |
137 | | - SDA_OUT(); |
138 | | - I2C_SDA(HIGH); /* CPU驱动SDA = 1 */ |
139 | | - delay_us(2); |
140 | | - I2C_SCL(HIGH); /* CPU产生1个时钟 */ |
141 | | - delay_us(2); |
142 | | - I2C_SCL(LOW); |
143 | | -} |
144 | | - |
145 | | -/** |
146 | | - * 函数功能: CPU向I2C总线设备发送8bit数据 |
147 | | - * 输入参数: Byte : 等待发送的字节 |
148 | | - * 返 回 值: 无 |
149 | | - * 说 明:无 |
150 | | - */ |
151 | | -void I2C_SendByte(uint8_t Byte) |
152 | | -{ |
153 | | - uint8_t t; |
154 | | - |
155 | | - SDA_OUT(); //sda??? |
156 | | - I2C_SCL(LOW); //?????????? |
157 | | - for (t = 0; t < 8; t++) |
158 | | - { |
159 | | - I2C_SDA((Byte & 0x80) >> 7); |
160 | | - Byte <<= 1; |
161 | | - delay_us(2); |
162 | | - I2C_SCL(HIGH); |
163 | | - delay_us(2); |
164 | | - I2C_SCL(LOW); |
165 | | - delay_us(2); |
166 | | - } |
167 | | -} |
168 | | - |
169 | | - |
170 | | -/** |
171 | | - * 函数功能: CPU从I2C总线设备读取8bit数据 |
172 | | - * 输入参数: 无 |
173 | | - * 返 回 值: 读到的数据 |
174 | | - * 说 明:无 |
175 | | - */ |
176 | | -uint8_t I2C_ReadByte(uint8_t ack) |
177 | | -{ |
178 | | - uint8_t i; |
179 | | - uint8_t value; |
180 | | - SDA_IN(); |
181 | | - /* 读到第1个bit为数据的bit7 */ |
182 | | - value = 0; |
183 | | -for (i = 0; i < 8; i++) |
184 | | - { |
185 | | - I2C_SCL(LOW); |
186 | | - delay_us(2); |
187 | | - I2C_SCL(HIGH); |
188 | | - value <<= 1; |
189 | | - if (I2C_SDA_READ() ) value++; |
190 | | - delay_us(1); |
191 | | - } |
192 | | - if (!ack) |
193 | | - { |
194 | | - I2C_NAck();//发送nACK |
195 | | - } |
196 | | - else |
197 | | - { |
198 | | - I2C_Ack(); //发送ACK |
199 | | - } |
200 | | - return value; |
201 | | -} |
202 | | - |
203 | | - |
204 | | -/** |
205 | | - * 函数功能: 检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在 |
206 | | - * 输入参数: _Address:设备的I2C总线地址 |
207 | | - * 返 回 值: 返回值 0 表示正确, 返回1表示未探测到 |
208 | | - * 说 明:在访问I2C设备前,请先调用 I2C_CheckDevice() 检测I2C设备是否正常,该函数会配置GPIO |
209 | | - */ |
210 | | -uint8_t I2C_CheckDevice(uint8_t _Address) |
211 | | -{ |
212 | | - uint8_t ucAck; |
213 | | - |
214 | | - I2C_InitGPIO(); /* 配置GPIO */ |
215 | | - I2C_Start(); /* 发送启动信号 */ |
216 | | - /* 发送设备地址+读写控制bit(0 = w, 1 = r) bit7 先传 */ |
217 | | - I2C_SendByte(_Address | I2C_WR); |
218 | | - ucAck = I2C_WaitAck(); /* 检测设备的ACK应答 */ |
219 | | - I2C_Stop(); /* 发送停止信号 */ |
220 | | - return ucAck; |
221 | | -} |
222 | | - |
223 | | -void Cmd_Write_BH1750(uint8_t cmd) |
224 | | -{ |
225 | | - I2C_Start(); //起始信号 |
226 | | - I2C_SendByte(BH1750_Addr+0); //发送设备地址+写信号 |
227 | | - while(I2C_WaitAck()); |
228 | | - delay_us(100); |
229 | | - I2C_SendByte(cmd); //内部寄存器地址 |
230 | | - while(I2C_WaitAck()); |
231 | | - delay_us(100); |
232 | | - I2C_Stop(); //发送停止信号 |
233 | | - delay_ms(5); |
234 | | -} |
235 | | -void Init_BH1750(void) |
236 | | -{ |
237 | | - I2C_InitGPIO(); |
238 | | - Cmd_Write_BH1750(0x01); |
239 | | -} |
240 | | -void Start_BH1750(void) |
241 | | -{ |
242 | | - Cmd_Write_BH1750(BH1750_ON); //power on |
243 | | - Cmd_Write_BH1750(BH1750_CON); |
244 | | -} |
245 | | -void Read_BH1750(void) |
246 | | -{ uint8_t i; |
247 | | - I2C_Start(); //起始信号 |
248 | | - I2C_SendByte(BH1750_Addr+1); //发送设备地址+读信号 |
249 | | - while(I2C_WaitAck()); |
250 | | - for (i=0; i<3; i++) //á?D??áè?6??μ??·êy?Y£?′?′¢?DBUF |
251 | | - { |
252 | | - if (i ==3) |
253 | | - { |
254 | | - BUF[i]=I2C_ReadByte(0); |
255 | | - |
256 | | - } |
257 | | - else |
258 | | - { BUF[i]=I2C_ReadByte(1); //发送ACK |
259 | | - |
260 | | - } |
261 | | - } |
262 | | - |
263 | | - //发送NACK |
264 | | - |
265 | | - I2C_Stop(); //停止信号 |
266 | | - delay_ms(5); |
267 | | -} |
268 | | -float Convert_BH1750(void) |
269 | | -{ |
270 | | - Start_BH1750(); |
271 | | - delay_ms(180); |
272 | | - Read_BH1750(); |
273 | | - result=BUF[0]; |
274 | | - result=(result<<8)+BUF[1]; //合成数据,即光照数据 |
275 | | - result_lx=(float)(result/1.2); |
276 | | - return result_lx; |
277 | | -} |
278 | | - |
279 | | - |
| 1 | +/******************************************************************************** |
| 2 | + * 文件名称 :BH1750.c |
| 3 | + * 作 者:物联网俱乐部 |
| 4 | + * 版 本:V1.0 |
| 5 | + * 编写日期 :2018-4-1 |
| 6 | + * 功 能:光照强度扩展板驱动 |
| 7 | +********************************************************************************* |
| 8 | + * 说 明 :本例程配套物联网俱乐部开发板使用 |
| 9 | + * |
| 10 | + * 淘 宝:https://shop128001708.taobao.com/ |
| 11 | + * 论 坛:bbs.iot-club.cn |
| 12 | +*********************************************************************************/ |
| 13 | + |
| 14 | +#include "bh1750.h" |
| 15 | +#include "stm32l4xx.h" |
| 16 | +#include "i2c.h" |
| 17 | + |
| 18 | + |
| 19 | +float result_lx; |
| 20 | +uint8_t BUF[2]; |
| 21 | +int result; |
| 22 | + |
| 23 | + |
| 24 | +/*************************************************************** |
| 25 | +* 函数名称: Init_BH1750 |
| 26 | +* 说 明: 写命令初始化BH1750 |
| 27 | +* 参 数: 无 |
| 28 | +* 返 回 值: 无 |
| 29 | +***************************************************************/ |
| 30 | +void Init_BH1750(void) |
| 31 | +{ |
| 32 | + uint8_t t_Data = 0x01; |
| 33 | + HAL_I2C_Master_Transmit(&hi2c1,BH1750_Addr,&t_Data,1,0xff); |
| 34 | +} |
| 35 | + |
| 36 | +/*************************************************************** |
| 37 | +* 函数名称: Start_BH1750 |
| 38 | +* 说 明: 启动BH1750 |
| 39 | +* 参 数: 无 |
| 40 | +* 返 回 值: 无 |
| 41 | +***************************************************************/ |
| 42 | +void Start_BH1750(void) |
| 43 | +{ |
| 44 | + uint8_t t_Data = 0x10; |
| 45 | + HAL_I2C_Master_Transmit(&hi2c1,BH1750_Addr,&t_Data,1,0xff); |
| 46 | +} |
| 47 | + |
| 48 | + |
| 49 | + |
| 50 | +/*************************************************************** |
| 51 | +* 函数名称: Convert_BH1750 |
| 52 | +* 说 明: 数值转换 |
| 53 | +* 参 数: 无 |
| 54 | +* 返 回 值: 光强值 |
| 55 | +***************************************************************/ |
| 56 | +float Convert_BH1750(void) |
| 57 | +{ |
| 58 | + Start_BH1750(); |
| 59 | + HAL_Delay(180); |
| 60 | + HAL_I2C_Master_Receive(&hi2c1, BH1750_Addr+1,BUF,2,0xff); |
| 61 | + result=BUF[0]; |
| 62 | + result=(result<<8)+BUF[1]; //合成数据,即光照数据 |
| 63 | + result_lx=(float)(result/1.2); |
| 64 | + return result_lx; |
| 65 | +} |
| 66 | + |
0 commit comments