項(xiàng)目里需要獲得光照強(qiáng)度,之前用的是光敏電阻,但是光敏電阻實(shí)在不精確,換用BH1750數(shù)字光照傳感器。網(wǎng)上購(gòu)買(mǎi)后,送的資料都是單片機(jī)的,移植到ZigBee協(xié)議棧里面,時(shí)序有些問(wèn)題,在網(wǎng)上找的一些資料,很雜亂。主要出現(xiàn)兩個(gè)問(wèn)題:一、讀取不到數(shù)據(jù);二、讀取到的數(shù)據(jù)是亂的。
仔細(xì)研究之后,發(fā)現(xiàn),第一個(gè)問(wèn)題讀不到數(shù)據(jù),八成是延時(shí)函數(shù)有差別;第二個(gè)問(wèn)題,一直以為是時(shí)序的問(wèn)題,糾結(jié)了很久還是沒(méi)弄好,后來(lái)突然想把數(shù)據(jù)處理的地方單獨(dú)弄出來(lái)測(cè)試,結(jié)果正是這里,采集到數(shù)據(jù),轉(zhuǎn)為字符串的時(shí)候,數(shù)據(jù)類(lèi)型跟所需要的數(shù)據(jù)類(lèi)型有差,最大范圍不同,可能每個(gè)人宏或者自定義的數(shù)據(jù)類(lèi)型都不太一樣,所以移植過(guò)來(lái)的時(shí)候,雖然名字一樣,但是實(shí)際上定義的時(shí)候不一樣,導(dǎo)致使用的時(shí)候不容易發(fā)現(xiàn)問(wèn)題。
下面貼上代碼。(之前在網(wǎng)上看到別人做的bh1750,想問(wèn)他買(mǎi)代碼,結(jié)果告訴我一個(gè)代碼要我80,瞬間無(wú)語(yǔ),還好自己弄出來(lái)了 ,共享給大家,也給自己提個(gè)醒,最是覺(jué)得沒(méi)有問(wèn)題的地方,往往就是問(wèn)題所在,需時(shí)刻抱有懷疑的態(tài)度)
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延時(shí)
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;
}
在主函數(shù)中加入以下函數(shù)(注意,此處就是最容易忽視的地方,uint應(yīng)該是unsigned int,不能是范圍太小的類(lèi)型):
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;
}
調(diào)用光照獲取函數(shù),講數(shù)據(jù)轉(zhuǎn)為字符串:
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;