当前位置: 代码迷 >> 综合 >> CC2530下ZigBee协议栈中添加BH1750数字光照传感器
  详细解决方案

CC2530下ZigBee协议栈中添加BH1750数字光照传感器

热度:28   发布时间:2023-10-01 04:11:19.0

项目里需要获得光照强度,之前用的是光敏电阻,但是光敏电阻实在不精确,换用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);
}
/****************************/
static void start_i2c(void)
{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();elseLIGHT_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();elseLIGHT_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();           //initstart_i2c();ack3=i2c_send(0x46);if(ack3)return 253;ack4=i2c_send(0x01);if(ack4)return 252;stop_i2c();//powerstart_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;
得到字符数组后,就很随意了。