基于Zigbee采集DS18B20的数字温度计设计代码
代码共有三部分组成:1、cc2530读取ds18b20的驱动程序;2、终端节点读取温度无线发送至协调器程序;3、协调器接收节点数据并长传串行通信接口以及判断是否发出超出预设阀值的警告信号的程序
1、cc2530读取ds18b20的驱动程序
#include”iocc2530.h”
#include”OnBoard.h”
#include “ds18b20.h”
#define Ds18b20IO P0_7 //温度传感器引脚
void Ds18b20Delay(unsigned int k);
void Ds18b20InputInitial(void);
void Ds18b20OutputInitial(void);
unsigned char Ds18b20Initial(void);
void Ds18b20Write(unsigned char infor);
unsigned char Ds18b20Read(void);
void Ds18b20Delay(unsigned int k)
{
MicroWait(k); //这是协议栈内的1us函数
}
void Ds18b20InputInitial(void)//设置端口为输入
{
P0DIR &= 0x7f;
}
void Ds18b20OutputInitial(void)//设置端口为输出
{
P0DIR |= 0x80;
}
//ds18b20初始化 初始化成功返回0x00,失败返回0x01
unsigned char Ds18b20Initial(void)
{
unsigned char Status = 0x00;
unsigned int CONT_1 = 0;
unsigned char Flag_1 = 1;
Ds18b20OutputInitial();
Ds18b20IO = 1; //DQ复位
Ds18b20Delay(260); //粗略延时:260us
Ds18b20IO = 0; //单片机将DQ拉低
Ds18b20Delay(750); //精确延时 大于 480us 小于960us
Ds18b20IO = 1; //拉高总线
Ds18b20InputInitial();//设置IO输入
while((Ds18b20IO != 0)&&(Flag_1 == 1))//等待ds18b20响应,具有防止超时功能
{ //等待约60ms左右
CONT_1++;
Ds18b20Delay(10);
if(CONT_1 > 8000)Flag_1 = 0;
Status = Ds18b20IO;
}
Ds18b20OutputInitial();
Ds18b20IO = 1;
Ds18b20Delay(100);
return Status; //返回初始化状态
}
void Ds18b20Write(unsigned char infor)
{
unsigned int i;
Ds18b20OutputInitial();
for(i=0;i<8;i++)
{
if((infor & 0x01))//若写
{
Ds18b20IO = 0;
Ds18b20Delay(15);//6
Ds18b20IO = 1;
Ds18b20Delay(45);//50
}
else
{
Ds18b20IO = 0;
Ds18b20Delay(45);
Ds18b20IO = 1;
Ds18b20Delay(15);
}
infor >>= 1;//移位至最低位
}
}
unsigned char Ds18b20Read(void)
{
unsigned char Value = 0x00;
unsigned int i;
Ds18b20OutputInitial();
Ds18b20IO = 1;
Ds18b20Delay(2);
for(i=0;i<8;i++)
{
Value >>= 1;
Ds18b20OutputInitial();
Ds18b20IO = 0;// 给脉冲信号
Ds18b20Delay(6);
Ds18b20IO = 1;// 给脉冲信号
Ds18b20Delay(4);
Ds18b20InputInitial();
if(Ds18b20IO == 1) Value |= 0x80;
Ds18b20Delay(30);
}
return Value;
}
//温度读取函数
unsigned char ReadDs18B20(void)
{
unsigned char V1,V2; //定义高低8位 缓冲
unsigned char temp; //定义温度缓冲寄存器
Ds18b20Initial();
Ds18b20Write(0xcc); // 跳过读序号列号的操作
Ds18b20Write(0x44); // 启动温度转换
Ds18b20Initial();
Ds18b20Write(0xcc); //跳过读序号列号的操作
Ds18b20Write(0xbe); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
V1 = Ds18b20Read(); //低位
V2 = Ds18b20Read(); //高位
temp = ((V1 >> 4)+((V2 & 0x07)*16)); //转换数据
return temp;
}
//温度读取函数 带1位小数位
float floatReadDs18B20(void)
{
unsigned char V1,V2; //定义高低8位 缓冲
unsigned int temp; //定义温度缓冲寄存器
float fValue;
Ds18b20Initial();
Ds18b20Write(0xcc); // 跳过读序号列号的操作
Ds18b20Write(0x44); // 启动温度转换
Ds18b20Initial();
Ds18b20Write(0xcc); //跳过读序号列号的操作
Ds18b20Write(0xbe); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
V1 = Ds18b20Read(); //低位
V2 = Ds18b20Read(); //高位
//temp = ((V1 >> 4)+((V2 & 0x07)*16)); //转换数据
temp=V2*0xFF+V1;
fValue = temp*0.0625;
return fValue;
}
2、终端节点读取温度无线发送至协调器程序/*********************************************************************
* @fn SampleApp_Send_P2P_Message
*
* @brief point to point.
*
* @param none
*
* @return none
*/
void SampleApp_Send_P2P_Message( void )
{
unsigned char str[7];
char strTemp[10];
float T=0.0;
int temp;
LED1_display_on(0);
T = floatReadDs18B20(); //读取温度数据
temp=T*10; //数据处理
str[0] = temp/100+48;
str[1] = temp%100/10+48;
str[2] = 46;
str[3] = temp%100%10+48;
str[4] = ‘ ‘;
str[5] = ‘C’;
str[6] = ‘\0’;
HalUARTWrite(0, “TEMP:”, 5); //节点串口输出提示信息
HalUARTWrite(0, str, 2);
HalUARTWrite(0, “\n”,1);
osal_memcpy(strTemp, “TEMP:”, 5);
osal_memcpy(&strTemp[5], str, 5);
//HalLcdWriteString(strTemp, HAL_LCD_LINE_3); //LCD显示
if ( AF_DataRequest( &SampleApp_P2P_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_P2P_CLUSTERID,
7,
str,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}
/*********************************************************************
*********************************************************************/
3、协调器接收节点数据并长传串行通信接口以及判断是否发出超出预设阀值的警告信号的程序
/*********************************************************************
* @fn SampleApp_MessageMSGCB
*
* @brief Data message processor callback. This function processes
* any incoming data – probably from other devices. So, based
* on cluster ID, perform the intended action.
*
* @param none
*
* @return none
*/
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
uint16 flashTime;
unsigned char buffer[2];
switch ( pkt->clusterId )
{
case SAMPLEAPP_P2P_CLUSTERID:
LED1_display_on(0);
HalUARTWrite(0, “TEMP:”, 5); //提示接收到数据
HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength); //输出接收到的数据
HalUARTWrite(0, “\n”, 1); // 回车换行
osal_memcpy(buffer,pkt->cmd.Data,2);
if(buffer[0]>50)
{
HalUARTWrite(0,”warning”, 7); //输出接收到的数据
HalUARTWrite(0, “\n”, 1);
LED2_display();
}
else if(buffer[0]<=(2+48))
LED2_display_on(0);//灯灭
break;
}
注:以上为全部重要程序。鉴于zigbee协议栈的程序量大且zigbee底层函数复杂且部分程序不开源,所以这里只展出了重要程序。