Zigbee协议栈开发笔记(二)无线温度收发实验
<h2>无线温度实验</h2><p>协调器建立网络,终端加入网络后周期性采集温度数据发送到协调器,协调器通过串口发送到pc</p><h5>协调器编程</h5><ol class=" list-paddingleft-2"><li><div style="text-align: justify">使用结构体将温度数据包含起来</div></li><li><div style="text-align: justify">接受无线数据包,拷贝到变量中</div></li><li><div style="text-align: justify">将变量内的数据发送到串口</div></li></ol><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5caf502691342358853310.png" alt=""/></p><p> </p><pre class="prism-highlight prism-language-c">void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
unsigned char buffer[2] = {0x0A,0x0D);//换行的ASCII码
TEMPERATURE temperature;定义TEMPERATURE类型变量temperature
switch(pkt->clusterId)
{
case GENERICAPP_CLUSTERID:
osal_memcpy(&temperature,pkt->cmd.Data,sizeof(temperature));
//使用osal_memcpy函数将收到的数据拷贝到变量中
HalUARTWrite(0,(uint 8*)&temperature,sizeof(temperature));//因为该函数的第二个参数是uint 8*类型的指针,所以需要类型强转
HalUARTWrite(0,buffer,2);//输出回车换行
break;
}
}</pre><p>协调器做的改动只是把发过来的数据包推到串口上,除了需要将定义数据包的共用体写到程序里需要注意,协调器编程没有什么要注意的,不过不这样做会报错,也没法完成实验。</p><h5>终端编程</h5><p>本例终端编程才是重点哒,主要实现两个功能,编写监测温度函数和修改无线发送函数,此时我们将与温度传感器有关的程序单独拿出来创建.c和.h文件各一个,并add到应用层文件夹中</p><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5caf5026b9254229303774.png" alt=""/></p><p>此时,发现书上有个错漏的地方,需要在终端程序文件中将Sensor.h文件包含进去,此时才能有效调用Sensor.c文件中的函数</p><p>Sensor.h:</p><pre class="prism-highlight prism-language-c">/*该文件是对温度读取函数的说明,以及包括一个定义一些数据类型的文件*/
#ifndef SENSOR_H
#define SENSOR_H
#include<hal_types.h>
extern int8 readTemp(void);
#endif</pre><p> </p><p>Sensor.c</p><pre class="prism-highlight prism-language-c">#include "Sensor.h"
#include <ioCC2530.h>
#define HAL_ADC_REF_115V 0x00
#define HAL_ADC_DEC_256 0x20
#define HAL_ADC_CHN_TEMP 0x0e
/*************
使能温度传感器
连接温度传感器
初始化ADC,确定参考电压,分辨率等,启动ADC
*************/
int8 readTemp(void)
{
static uint16 reference_voltage;
static uint8 bCalibrate = TRUE;
uint16 value;
int8 temp;
ATEST = 0x01;//使能温度传感器
TR0 |= 0x01;//连接温度传感器
ADCIF = 0;
ADCCON3 = (HAL_ADC_REF_115V | HAL_ADC_DEC_256 | HAL_ADC_CHN_TEMP);
while(! ADCIF);
ADCIF = 0;
value = ADCL;
value |= ((uint16)ADCH)<<8;
value>>=4;
if(bCalibrate)
{
reference_voltage=value;
bCalibrate=FALSE;
}
temp = 22+((value - reference_voltage)/4);//温度矫正
return temp;
}
//注意,CC2530内部温度传感器很难校正,不考虑数字正确性</pre><p> </p><p>之后,再修改无线发送函数至此形式</p><pre class="prism-highlight prism-language-c">void GenericApp_SendTheMessage(void)
{
//unsigned char theMessageData[10] = "EndDevice";//用于存放要发送的数据
uint8 tvalue;
TEMPERATUER temperature;
temperature.BUF.Head = '&';
tvalue = readTemp();
temperature.BUF.value[0] = tvalue/10+'0';
temperature.BUF.value[1] = tvalue%10+'0';
temperature.BUF.Tail = 'C';
afAddrType_t my_DstAddr;//为满足AF_DataRequest第一个参数定义的变量
my_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;//何种方式发送(单播)
my_DstAddr.endPoint = GENERICAPP_ENDPOINT;//初始化端口号
my_DstAddr.addr.shortAddr = 0x0000;//协调器地址固定为0x0000
AF_DataRequest( &my_DstAddr, //目的地节点的网络地址和发送数据的格式
&GenericApp_epDesc,//端口号
GENERICAPP_CLUSTERID,//命令号
sizeof(temperature),//数据长度
(uint8*)&temperature,//指向数据缓冲区的指针
&GenericApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS);
}
/*数据类型afAddrType和函数AF_DataRequest原型都在书上*/</pre><p> </p><p>学习到这里大家对无线收发函数结构已经比较熟悉了,很容易理解</p><p>同协调器编程时一样,需要定义TEMPERATURE共用体,这也是书上遗漏的地方,或者该共用体应该定义再其他地方,目前还不知道。</p><p>顺便一提(在协调器代码中),我使用串口调试助手里</p><pre class="prism-highlight prism-language-c">HalUARTWrite(0,buffer,1);//输出回车换行</pre><p>这一行并不能实现换行,也就是buffer[2] = {0x0A,0x0D}不行</p><p>而HalUARTWrite函数第二个参数必须是int8*,所以目前实现换行的实际方法是</p><pre class="prism-highlight prism-language-c">int a = '\n';
HalUARTWrite(0,(int8*)&a,1);</pre><p>实验结果因为板子不在手边了就不展示了,效果是触摸终端核心板中间芯片部分可以看到串口助手上温度数值在上升。</p><p> </p><p><img src="{#ZC_BLOG_HOST#}zb_users/upload/2019/04/5caf5026efb9c267606834.png" alt=""/></p><p>Ps.书上后面的NV操作和扩展阅读就暂时跳过了,明天花点时间学习无线网络管理部分(第六章),再然后就着手根据自己项目的需求改程序了。</p>
Q.E.D.