您的位置:首页 > 其它

ZigBee组网学习笔记(八)--温度传感器

2014-12-05 22:45 316 查看
学习 zigbee 的最终目的是采集传感器信息,建立起无线传感网。
首先,采用最熟悉的温度传感器DS18B20



DS18B20硬件电路图

节点通过采集 DS18B20 温度信息,实时发送到协调器。协调器通过串口打印方式展示当前温度。
一:在裸机上完成对 DS18B20 的驱动。

二:将程序添加到协议栈代码中

三:将数据打包并按指定的方式发送给指定设备。

一:在裸机上完成对 DS18B20 的驱动

---------------------------------------------------

ds18b20.h
#ifndef __DS18B20_H__

#define __DS18B20_H__

extern unsigned char temp;

extern unsigned char Ds18b20Initial(void);

extern void Temp_test(void);

#endif

---------------------------------------------------
ds18b20.c

#include"uart.h"

#include"iocc2530.h"

#define uint unsigned int

#define uchar unsigned char

#define Ds18b20Data P0_6 //温度传感器引脚

#define ON 0x01 //读取成功返回0x00,失败返回0x01

#define OFF 0x00

unsigned char temp; //储存温度信息

//时钟频率为32M

void Ds18b20Delay(uint k)

{

uint i,j;

for(i=0;i<k;i++)

for(j=0;j<2;j++);

}

void Ds18b20InputInitial(void)//设置端口为输入

{

P0DIR &= 0xbf;

}

void Ds18b20OutputInitial(void)//设置端口为输出

{

P0DIR |= 0x40;

}

//ds18b20初始化

//初始化成功返回0x00,失败返回0x01

uchar Ds18b20Initial(void)

{

uchar Status = 0x00;

uint CONT_1 = 0;

uchar Flag_1 = ON;

Ds18b20OutputInitial();

Ds18b20Data = 1;

Ds18b20Delay(260);

Ds18b20Data = 0;

Ds18b20Delay(750);

Ds18b20Data = 1;

Ds18b20InputInitial();

while((Ds18b20Data != 0)&&(Flag_1 == ON))//等待ds18b20响应,具有防止超时功能

{ //等待约60ms左右

CONT_1++;

Ds18b20Delay(10);

if(CONT_1 > 8000)
Flag_1 = OFF;

Status = Ds18b20Data;

}

Ds18b20OutputInitial();

Ds18b20Data = 1;

Ds18b20Delay(100);

return Status;

}

void Ds18b20Write(uchar infor)

{

uint i;

Ds18b20OutputInitial();

for(i=0;i<8;i++)

{

if((infor & 0x01))

{

Ds18b20Data = 0;

Ds18b20Delay(6);

Ds18b20Data = 1;

Ds18b20Delay(50);

}

else

{

Ds18b20Data = 0;

Ds18b20Delay(50);

Ds18b20Data = 1;

Ds18b20Delay(6);

}

infor >>= 1;

}

}

uchar Ds18b20Read(void)

{

uchar Value = 0x00;

uint i;

Ds18b20OutputInitial();

Ds18b20Data = 1;

Ds18b20Delay(10);

for(i=0;i<8;i++)

{

Value >>= 1;

Ds18b20OutputInitial();

Ds18b20Data = 0;

Ds18b20Delay(3);

Ds18b20Data = 1;

Ds18b20Delay(3);

Ds18b20InputInitial();

if(Ds18b20Data == 1)
Value |= 0x80;

Ds18b20Delay(15);

}

return Value;

}

void Temp_test(void) //温度读取函数

{

uchar V1,V2;

Ds18b20Initial();

Ds18b20Write(0xcc);

Ds18b20Write(0x44);

Ds18b20Initial();

Ds18b20Write(0xcc);

Ds18b20Write(0xbe);

V1 = Ds18b20Read();

V2 = Ds18b20Read();

temp = ((V1 >> 4)+((V2 & 0x07)*16));

}

---------------------------------------------------

二:将程序添加到协议栈代码中

接下来我们需要做的工作就是移植到协议栈z-stack 上面,这个过程要注意的是要了解协议栈上的 IO 口用途和晶振工作频率。

通过点播方式发送到协调器,协调器通过串口发送到上位机,在串口调试助手上面显示。这就实现了无线温度采集。
(使用点播的原因是终端设备有针对性地发送数据给指定设备,不像广播和组播可能会造成数据冗余)

1、将裸机程序里面的
ds18b20.c和 ds18b20.h 文件复制到SampleApp/Source 文件夹下。

2、在协议栈的 App 目录树下点击右键--Add--添加 DS18B20.C 文件



3、整个实验以点播为依托,实验也就是在点播例程的基础上完成,故函数编程也是像以前一样在SampleApp.c上进行,先包含 ds18b20.h 文件。



4、初始化传感器引脚 P0.6 。



SampleApp.c

//温度传感器初始化 P0.6

P0SEL &= 0xbf ;

5、借用周期性点播函数, 1s 读取温度传感器 1 次,通过串口打印并点对点发送给协调器 。

SampleApp.c

uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
// Send a message out - This event is generated by a timer

// (setup in SampleApp_Init()).

if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )

uint8 T[5]; //温度+提示符

Temp_test(); //温度检测

T[0]=temp/10+48;

T[1]=temp%10+48;

T[2]=' ';

T[3]='C';

T[4]='\0';

/*******串口打印 *********/

HalUARTWrite(0,"temp=",5);

HalUARTWrite(0,T,2);

HalUARTWrite(0,"\n",1);

SampleApp_SendPointToPointMessage();//此处点播函数



6、ds18b20.c 文件需要修改一个地方。打开该文件, 将原来的延时函数改成协议栈自带的延时函数,保证时序的正确。

//时钟频率为32M

void Ds18b20Delay(uint k)

{

//uint i,j;

//for(i=0;i<k;i++)

//for(j=0;j<2;j++);
MicroWait(k);//毫秒延时

}

同时要包含 #include "OnBoard.h" , 去掉 #include"uart.h"。

另外,协议栈里面是要求每个定义了的函数都必须在文件添加声明,否则报错。

所以给 ds18b20.c 里面的函数都添加声明:

void Ds18b20Delay(uint k); //延时

void Ds18b20InputInitial(void); //设置端口为输入

void Ds18b20OutputInitial(void); //设置端口为输出

uchar Ds18b20Initial(void);

void Ds18b20Write(uchar infor);

uchar Ds18b20Read(void);

void Temp_test(void); //温度读取函数



三:将数据打包并按指定的方式发送给指定设备。
上一个步骤,完成了 DS18B20 基于协议栈的驱动,接下来,实现数据发送和接收就可以了。
在 EndDevice 的点播发送函数中将温度信息发送出去。

SampleApp.c

void SampleApp_SendPointToPointMessage( void )

{

uint8 T[2]; //温度

T[0]=temp/10+48; //格式转换

T[1]=temp%10+48;

if ( AF_DataRequest( &Point_To_Point_DstAddr,

&SampleApp_epDesc,

SAMPLEAPP_POINT_TO_POINT_CLUSTERID,

2,

T,

&SampleApp_TransID,

AF_DISCV_ROUTE,

AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )

{

}

else

{

// Error occurred in request to send.

}

}

协调器:
SampleApp.c

void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )

case SAMPLEAPP_POINT_TO_POINT_CLUSTERID:

HalUARTWrite(0,"Temp is:",8); //提示接收到数据

HalUARTWrite(0,&pkt->cmd.Data[0],2); //ASCII 码发给 PC 机

HalUARTWrite(0,"\n",1); // 回车换行

break;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: