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

来源:互联网 发布:淘宝消保怎么交 编辑:程序博客网 时间:2024/05/16 15:53
学习 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.cds18b20.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; 






0 0
原创粉丝点击