项目里需要获得光照强度,之前用的是光敏电阻,但是光敏电阻实在不精确,换用BH1750数字光照传感器。网上购买后,送的资料都是单片机的,移植到ZigBee协议栈里面,时序有些问题,在网上找的一些资料,很杂乱。主要出现两个问题:一、读取不到数据;二、读取到的数据是乱的。
仔细研究之后,发现,第一个问题读不到数据,八成是延时函数有差别;第二个问题,一直以为是时序的问题,纠结了很久还是没弄好,后来突然想把数据处理的地方单独弄出来测试,结果正是这里,采集到数据,转为字符串的时候,数据类型跟所需要的数据类型有差,最大范围不同,可能每个人宏或者自定义的数据类型都不太一样,所以移植过来的时候,虽然名字一样,但是实际上定义的时候不一样,导致使用的时候不容易发现问题。
下面贴上代码。(之前在网上看到别人做的bh1750,想问他买代码,结果告诉我一个代码要我80,瞬间无语,还好自己弄出来了 ,共享给大家,也给自己提个醒,最是觉得没有问题的地方,往往就是问题所在,需时刻抱有怀疑的态度)
BH1750.h:
#ifndef __BH1750_H
#define __BH1750_H
#include 《ioCC2530.h》
#define st(x) do { x } while (__LINE__ == -1)
#define HAL_IO_SET(port, pin, val) HAL_IO_SET_PREP(port, pin, val)
#define HAL_IO_SET_PREP(port, pin, val) st( P##port##_##pin## = val; )
#define HAL_IO_GET(port, pin) HAL_IO_GET_PREP( port,pin)
#define HAL_IO_GET_PREP(port, pin) ( P##port##_##pin)
#define LIGHT_SCK_0() HAL_IO_SET(1,3,0)
#define LIGHT_SCK_1() HAL_IO_SET(1,3,1)
#define LIGHT_DTA_0() HAL_IO_SET(1,1,0)
#define LIGHT_DTA_1() HAL_IO_SET(1,1,1)
#define LIGHT_DTA() HAL_IO_GET(1,1)
#define LIGHT_SCK() HAL_IO_GET(1,3)
#define SDA_W() (P1DIR |=(1 《《 1) )
#define SDA_R() (P1DIR &=~(1 《《 1) )
#define LIGHT_INIT() \
do{ \
P1SEL &= ~0x08; \
P1DIR |=0x08; \
P1_3 = 1; \
\
P1SEL &= ~0x02; \
P1DIR |= 0x02; \
P1_1 = 1; \
}while(0)
extern unsigned short get_light(void);
#endif // __BH1750_H
BH1750.c:
#include “BH1750.h”
#include “OnBoard.h”
void halMcuWaitUs(uint16 usec)
{
while(usec--)
{
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
}
}
//以ms延时
void halMcuWaitMs(uint16 msec)
{
while(msec--)
halMcuWaitUs(1000);
}
void delay_us()
{
halMcuWaitUs(1);
// MicroWait(1);
}
void delay_5us()
{
halMcuWaitUs(5);
//MicroWait(5);
}
void delay_10us()
{
halMcuWaitUs(10);
//MicroWait(10);
}
void delay_nms(int n)
{
halMcuWaitMs(n);
}
/****************************/
{
SDA_W() ;
LIGHT_DTA_1();//
LIGHT_SCK_1() ;//
delay_us() ;
LIGHT_DTA_0() ;
delay_us() ;
LIGHT_SCK_0() ;
delay_us() ;
//delay() ;
}
static void stop_i2c(void)
{
SDA_W() ;
LIGHT_DTA_0() ;
delay_us();
LIGHT_SCK_1() ;
delay_us();
LIGHT_DTA_1() ;
delay_us();
LIGHT_SCK_0() ;
delay_us();
}
static char i2c_send(unsigned char val)
{
int i;
char error=0;
SDA_W();
for(i=0x80;i》0;i/=2)
{
if(val&i)
LIGHT_DTA_1();
else
LIGHT_DTA_0();
delay_us();
LIGHT_SCK_1() ;
delay_us();
LIGHT_SCK_0() ;
delay_us();
}
LIGHT_DTA_1();
SDA_R();
delay_us();
//delay_us();
LIGHT_SCK_1() ;
delay_us();
if(LIGHT_DTA())
error=1;
delay_us();
LIGHT_SCK_0() ;
return error;
}
static char i2c_read(char ack)
{
int i;
char val=0;
LIGHT_DTA_1();
//SDA_R();
for(i=0x80;i》0;i/=2)
{
LIGHT_SCK_1() ;
delay_us();
SDA_R();
//SDA_W();
//LIGHT_DTA_0();
//LIGHT_DTA_0() ;
//delay_us();
if(LIGHT_DTA())
val=(val|i);
delay_us();
//SDA_R();
LIGHT_SCK_0() ;
delay_us();
}
SDA_W();
if(ack)
LIGHT_DTA_0();
else
LIGHT_DTA_1();
delay_us();
LIGHT_SCK_1() ;
delay_us();
LIGHT_SCK_0() ;
LIGHT_DTA_1();
return val;
}
unsigned short get_light(void)
{
unsigned char ack1=1;
unsigned char ack2=1;
unsigned char ack3=1;
unsigned char ack4=1;
unsigned char ack5=1;
unsigned char ack6=1;
unsigned char ack7=1;
unsigned char t0;
unsigned char t1;
unsigned short t;
P1DIR |= (1 《《 1);
delay_nms(200);
start_i2c();
ack1=i2c_send(0x46);
if(ack1)
return 255;
ack2=i2c_send(0x01);
if(ack2)
return 254;
stop_i2c(); //init
start_i2c();
ack3=i2c_send(0x46);
if(ack3)
return 253;
ack4=i2c_send(0x01);
if(ack4)
return 252;
stop_i2c();//power
start_i2c();
ack5=i2c_send(0x46);
if(ack5)
return 251;
ack6=i2c_send(0x10);
if(ack6)
return 250;
stop_i2c();
delay_nms(1500);
start_i2c();
ack7=i2c_send(0x47);
if(ack7)
return 249;
t0 = i2c_read(1);
t1 = i2c_read(0);
stop_i2c();
t = ((short)t0)《《8;
t |= t1;
return t;
}
在主函数中加入以下函数(注意,此处就是最容易忽视的地方,uint应该是unsigned int,不能是范围太小的类型):
char wan,qian,bai,shi,ge;
void conversion(unsigned int temp_data)
{
wan=(uint)temp_data/10000 ;
temp_data=temp_data%10000;
qian=(uint)temp_data/1000 ;
temp_data=temp_data%1000;
bai=(uint)temp_data/100;
temp_data=temp_data%100;
shi=(uint)temp_data/10;
temp_data=temp_data%10;
ge=(uint)temp_data;
}
调用光照获取函数,讲数据转为字符串:
uint32 w;
w = get_light()/1.2;
conversion(w);
char buf[5];
buf[0] = wan + 48;
buf[1] = qian + 48;
buf[2] = bai + 48;
buf[3] = shi + 48;
buf[4] = ge + 48;