第十六讲 ZigBee串口透传
一、 串口透明传输工程说明
串口透明传输工程是在SampleApp工程基础之上进行修改而成,主要功能是完成简单的串口透明传输,功能要求:
1、设备上电后自动选择设备类型。第一个启动的设备为协调器,后续启动的为路由器。(所有设
备中程序相同)
2、路由器的232串口接收到数据后将数据以单播的形式发送到协调器。当路由器接收到来自空
中的数据包将数据写入232串口。
3、协调器的232串口接收到数据后将数据以广播的形式发送到网络中所有的设备。当协调器接
收到来自空中的数据包将数据写入232串口。
路由器 传感器 PC 机 协调器
路由器 传感器 路由器 图X 串口透明传输应用
传感器 二、 编译选项说明
串口透明传输工程在SampleApp工程基础之上进行修改,但是编译选项使用原SampleApp工程的编译选项,SampleApp工程编译选项具体如下:
CC2430EB、ZTOOL_P1、MT_TASK、SOFT_START 通过编译选项ZTOOL_P1 编译选项SOFT_START。
三、 工程初始化与事件处理函数
串口透明传输工程来源于对SampleApp工程的修改,工程初始化函数与SampleApp工程的初始化函数完全相同,读者可以参见前面章节。串口透明传输工程事件处理函数在SampleApp工程事件处理函数的基础之上添加了对事件UART_RX_CB_EVT的处理,具体代码如下。
程序代码:
uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) {
if ( events & SYS_EVENT_MSG ) {
while ( MSGpkt )
1
{
switch ( MSGpkt->hdr.event ) {
case KEY_CHANGE:
……
break;
case AF_INCOMING_MSG_CMD: …… break;
case ZDO_STATE_CHANGE:
……
break; default: break; } }
return (events ^ SYS_EVENT_MSG); }
if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ) {
……
return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT); }
if ( events & UART_RX_CB_EVT ) //串口有数据需要处理 {
SampleApp_SPI_SendData( rbuf, rxlen+1); //调用处理函数,将信息发送出去 return (events ^ UART_RX_CB_EVT); }
return 0; }
四、 工程修改
1、添加事件
串口透明传输工程在SampleApp工程基础上添加事件UART_RX_CB_EVT,当串口回调函数有接收到数据后将触发该事件,该事件在SampleApp.h中被定义,具体代码如下。
程序代码:
#define UART_RX_CB_EVT 0x0002
2、回调函数
编译选项中的ZTOOL_P1说明原SampleApp工程默认使用Z-Tool,我们这里对其修改,将其在串口初始化中的回调函数函数进行修改。
程序代码:
2
void SPIMgr_Init () {
……
#if defined (ZTOOL_P1) || defined (ZTOOL_P2) uartConfig.callBackFunc = rxCB; …… }
相应我们在SPIMgr.c文件中添加该回调函数rxCB( uint8 port, uint8 event ),具体代码如下。
程序代码
static void rxCB( uint8 port, uint8 event ) {
extern uint8 SampleApp_TaskID;
rxlen=Hal_UART_RxBufLen(SPI_MGR_DEFAULT_PORT); //接收缓冲区数据长度,字节为单位 rbuf=osal_mem_alloc(rxlen+1); //多分配1字节,分配如下 rbuf[0]=rxlen; //一字节存放数据长度
HalUARTRead ( SPI_MGR_DEFAULT_PORT, rbuf+1, rxlen); //读接收缓冲区数据到内存databuf+1
if(!rxlen)
osal_mem_free( rbuf ); //释放内存
osal_set_event(SampleApp_TaskID,UART_RX_CB_EVT); }
3、发送函数
当串口接收到数据在串口回调函数中触发事件UART_RX_CB_EVT,应用层对其处理,并最终调用数据发送函数将串口接收到的数据发送出去。为此我们在SampleApp工程基础之上添加了数据发送函数SampleApp_SPI_SendData(),该函数具体如下。
程序代码
void SampleApp_SPI_SendData( uint8 *buf, uint8 len ) {
if ( devStartMode == MODE_HARD )//如果启动的时候是协调器,则用广播 {
SampleApp_SPI_SendData_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast; SampleApp_SPI_SendData_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_SPI_SendData_DstAddr.addr.shortAddr = 0xFFFF; }
else//其它设备类型则用单播 {
SampleApp_SPI_SendData_DstAddr.addrMode = (afAddrMode_t)Addr16Bit; SampleApp_SPI_SendData_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_SPI_SendData_DstAddr.addr.shortAddr = 0x0000; }
3
if ( AF_DataRequest ( &SampleApp_SPI_SendData_DstAddr,
(endPointDesc_t *)&SampleApp_epDesc, SAMPLEAPP_FLASH_CLUSTERID, len, buf,
&SampleApp_TransID, 0,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) {
osal_mem_free( rbuf ); //必须释放内存,不然造成溢出! } else {
osal_mem_free( rbuf ); //必须释放内存,不然造成溢出! } }
五、 数据流程
该串口透明传输工程与同为串口透明传输的SerialApp工程相比数据流程有很大的区别。该工程主要实现了多对一的数据透明传输,即协调器向所有路由广播,而路由器单播发送数据到协调器。数据流可分为两大部分,协调器到路由器和路由器到协调器。
下面我们梳理协调器到路由器数据流程,而路由器到协调器数据流程与其类似,读者可以自行对其梳理。协调器到路由器数据流程的流程图如图X所示。
PC机232串口设备串口回调函数写入串口触发事件处理事件发送数据触发事件 图X 协调器到路由器数据流程图
1、回调函数
当与协调器连接的设备(通常为PC机)向协调器通过232串口写入数据时,协调器的串口回调函数将处理相关信息,并在串口回调函数中触发事件UART_RX_CB_EVT通知应用层进行处理。串口回
4
调函数代码如下。
程序代码
static void rxCB( uint8 port, uint8 event ) {
extern uint8 SampleApp_TaskID;
rxlen=Hal_UART_RxBufLen(SPI_MGR_DEFAULT_PORT); //接收缓冲区数据长度,字节为单位 rbuf=osal_mem_alloc(rxlen+1); //多分配3字节,分配如下 rbuf[0]=rxlen; //一字节存放数据长度
HalUARTRead ( SPI_MGR_DEFAULT_PORT, rbuf+1, rxlen); //读接收缓冲区数据到内存databuf+3
if(!rxlen)
osal_mem_free( rbuf ); //释放内存
osal_set_event(SampleApp_TaskID,UART_RX_CB_EVT); }
2、处理事件UART_RX_CB_EVT
当接收到来自串口的信息后,在串口回调函数的最后触发了事件UART_RX_CB_EVT,而该事件的任务ID为SampleApp_TaskID,即应用层任务ID,所以会被SampleApp工程应用层的事件处理函数SampleApp_ProcessEvent()处理,具体程序如下。
程序代码
uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) {
……
if ( events & UART_RX_CB_EVT ) //串口有数据需要处理 {
SampleApp_SPI_SendData( rbuf, rxlen+1); //调用处理函数,将信息发送出去 return (events ^ UART_RX_CB_EVT); } …… }
3、数据发送函数SampleApp_SPI_SendData( )
在处理事件UART_RX_CB_EVT时,协议栈调用了函数SampleApp_SPI_SendData()将串口数据发送到空中,具体代码如下。
程序代码
void SampleApp_SPI_SendData( uint8 *buf, uint8 len ) {
if ( devStartMode == MODE_HARD )//如果启动的时候是协调器,则用广播 {
SampleApp_SPI_SendData_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;
5
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说教育文库ZigBee简易串口透传在线全文阅读。
相关推荐: