浅析CC2530下ZigBee协议栈中添加BH1750数字光照传感器
数字传感器 数字传感器就是指将传统化的数字模拟感应器历经改装或更新改造A/D变换控制模块,使之輸出讯号为数据量(或数字记忆法)的感应器,关键包含:放大仪、A/D转化器、微控制器(CPU)、储存器、通信插口、温度检测电源电路等,在微控制器和感应器越来越更加划算的今日,自动式或全自动(根据人力命令开展高端实际操作,全自动解决基层实际操作)系统软件能够包括大量智能化男性性功能,能从其条件中获取并解决大量不一样的主要参数。 特性 1、优秀的A/D变换技术性和智能化数字滤波,在满度的情形下仍可确保輸出码的平稳。 2、行得通的数据储存技术性,确保控制模块主要参数不容易遗失。 3、优良的电磁兼容测试特性。 4、感应器的特性选用智能化偏差弥补技术性和高宽比一体化电子元器件,用系统完成感应器的线形、零点、温漂、应力松弛等技术参数的综合性赔偿,清除了人为要素对赔偿的危害,进一步提高了感应器综合性精密度和稳定性。 5、感应器的輸出一致性偏差能够做到0.02%之内甚至于高些,感应器的性能主要参数可完全一致,因此有着优良的公差配合。 6、选用A/D变换电源电路、智能化数据信号传递和数字滤波技术性,感应器的抗干扰性提升,数据信号传送距离较远,提升 了温度传感器的可靠性。 7、数字传感器能自行采集数据并可预备处理、储存和记忆力,具备唯一标识,有利于故障检测。 8、感应器选用规范的数据通讯插口,可立即连接电子计算机,也可与规范工业控制系统系统总线联接,便捷灵便。 9, 数字传感器是将AD,EPROM,DIE(指还未封裝的感应器集成ic,归属于裸片,尺寸处于cell和chip中间),封裝在一块用PCB,金属材料块或陶瓷纤维板上的集成化。根据各种各样溫度,工作压力点的校正,测算出DIE的线形,再运用AD去赔偿的办法生产而成的。 运用及市场前景 在微控制器和感应器越来越更加划算的今日,自动式或全自动(根据人力命令开展高端实际操作,全自动解决基层实际操作)系统软件能够包括大量智能化男性性功能,能从其条件中获取并解决大量不一样的主要参数。尤其是MEMS(微型计算机电系统软件)技术性,它使数字传感器的大小十分细微而且耗能与费用也很低。以纳米碳管或其他纳米复合材料做成的微米感应器一样有着很大的发展潜力 [1] 。 即便 在萌发环节,大家依然觉得在一段时间的未来数字传感器对电子城具备关键的促进功效。制做数字传感器的插口及其适用用以数字传感器互联网的多种形式的通信协议全是对工艺加工工艺的很大挑戰。感应器的非匀质特点和其实际操作标准的多样性也对工艺加工工艺提到了很大的挑戰。 如今系统软件设计室涵盖的感应器和CPU愈来愈多。伴随着感应器和处理器价格的持续减少,替代机械设备系统结构的阀值也在不断地转变 。在操作系统中挑选准确的感应器组成和解决优化算法能够明显地减少原料及能源消耗的成本并增强操作系统的整体特性。现阶段,持续增强使用的优化水平和增加电力能源的使用期越来越更加关键,尤其是现在愈来愈多的无线传感器动则就配备1000或大量的感应器连接点。
新项目里必须得到光照度,以前用的是光敏二极管,可是光敏二极管确实不精准,改用BH1750数据阳光照射感应器。网上订购后,送的材料全是单片机设计的,移殖到ZigBeetcp协议里边,时钟频率有一些难题,在网络上找的一些材料,很杂乱无章。关键发生2个难题:一、载入不上数据信息;二、载入到的数据信息是乱的。
细心分析以后,发觉,第一个难题读不上数据信息,八成是延时函数有区别;第二个难题,一直认为是时钟频率的难题,担心了许久或是没弄好,之后忽然想把数据处理方法的地区独立弄出检测,結果恰好是这儿,收集到数据信息,变为字符串数组的情况下,基本数据类型跟所须要的基本数据类型有差,较大范畴不一样,很有可能每一个人宏或是修改的基本数据类型也不太一样,因此移殖回来的情况下,尽管名称一样,可是事实上界定的情况下不一样,造成 应用的情况下不易发现问题。
下边贴上编码。(以前网上看见其他人做的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();
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_data000;
qian=(uint)temp_data/1000 ;
temp_data=temp_data00;
bai=(uint)temp_data/100;
temp_data=temp_data0;
shi=(uint)temp_data/10;
temp_data=temp_data;
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;