使用的协议栈版本信息: ZigBee2006\ZStack-1.4.3-1.2.1
因为用现在这模块SerialApp没做成功,上电后按键没反应……两块无线龙小板子已经买来N年了.
自己想在SampleApp例子基础上修改实现串口透明传输:
串口调试助手1<————>模块1 <-----OTA-----> 模块2<————>串口调试助手2
程序修改主要如下:
****************************************************************************************
****************************************************************************************
1、
宏定义事件 #define UART_RX_CB_EVT 0x0002 (SampleApp.h)
全局变量声明: (SPIMgr.h)
extern uint8 rxlen; //接收数据长度
extern uint8* databuf; //接收数据指针
****************************************************************************************
****************************************************************************************
2、
串口回调函数rxCB: (SPIMgr.c)
#if defined (ZTOOL_P1) || defined (ZTOOL_P2)
uartConfig.callBackFunc = rxCB;
//uartConfig.callBackFunc = SPIMgr_ProcessZToolData; //回调函数
****************************************************************************************
****************************************************************************************
3、十六进制转字符函数 (SampleApp.c) 这两个函数由青竹提供.
uint8 hextoword1(uint8 t )
{
uint8 abc;
uint8 cba;
uint8 xx1;
abc=t;
cba=0xf0;
abc=(abc&cba)>>4;
if(abc<10)
{
xx1=abc+48;
}
else
{
xx1=abc+55;
}
return xx1;
}
uint8 hextoword2(uint8 t)
{
uint8 abc;
uint8 cba;
uint8 xx2;
abc=t;
cba=0x0f;
abc=abc&cba;
if(abc<10)
{
xx2=abc+48;
}
else
{
xx2=abc+55;
}
return xx2;
}
****************************************************************************************
****************************************************************************************
4、定义串口回调函数rxCB() (SPIMgr.c)
static void rxCB( uint8 port, uint8 event )
{
// uint8 rxlen; //接收数据长度
// uint8* dataybuf;//接收数据块指针
extern uint8 SampleApp_TaskID;
uint16 short_ddr;
uint8 short_ddr_H;
uint8 short_ddr_L;
// uint8 *pointer1;
// uint8 word_buffer[8];
short_ddr=NLME_GetShortAddr();
short_ddr_H=(uint8)((short_ddr&0xff00)>>8);
short_ddr_L=(uint8)short_ddr;
rxlen=Hal_UART_RxBufLen(SPI_MGR_DEFAULT_PORT); //接收缓冲区数据长度,字节为单位
databuf=osal_mem_alloc(rxlen+1+2); //多分配3字节,分配如下
databuf[0]=rxlen; //一字节存放数据长度
databuf[1]=short_ddr_H; //一字节存放源地址高8位
databuf[2]=short_ddr_L; //一字节存放源地址低8位
//databuf[rxlen+1]='\n'; //一字节存放换行符
HalUARTRead ( SPI_MGR_DEFAULT_PORT, databuf+3, rxlen); //读接收缓冲区数据到内存databuf+3
/* 回显数据(测试用)
word_buffer[0]='l';
word_buffer[1]='e';
word_buffer[2]='n';
word_buffer[3]=':';
word_buffer[4]=databuf[0]/100+48;
word_buffer[5]=(databuf[0]%100)/10+48;
word_buffer[6]=databuf[0]%10+48;
word_buffer[7]='\n';
pointer1=word_buffer;
// HalUARTWrite()写入串口正确说明数据已经正确地存储在databuf中!
HalUARTWrite ( SPI_MGR_DEFAULT_PORT, pointer1, 8 );
HalUARTWrite ( SPI_MGR_DEFAULT_PORT, databuf+1, rxlen+1 );//把数据送串口输出
*/
if(!rxlen)
osal_mem_free( databuf ); //释放内存
osal_set_event(SampleApp_TaskID,UART_RX_CB_EVT);
// rxCB_to_SampleApp( databuf, rxlen );
}
****************************************************************************************
****************************************************************************************
5、添加:事件处理函数 (SampleApp.c)
uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
{
afIncomingMSGPacket_t *MSGpkt;
// 显示网络地址变量
uint16 short_ddr;
uint8 yy1;
uint8 yy2;
uint8 str_1[ ]="my short address is:";
#if defined(ZDO_COORDINATOR)
uint8 str_2[ ]="build the network successfully";
#else
uint8 str_2[ ]="join the network successfully ";
#endif
uint8 str_3[ ]={'\n'};
uint8 shortaddr[7];
uint8 *pointer1;
uint8 *pointer2;
uint8 *pointer3;
uint8 *pointer4;
…………(省略)
/*1、接收串口信息在SampleApp_MessageMSGCB()上进行修改*/
case AF_INCOMING_MSG_CMD:
SampleApp_MessageMSGCB( MSGpkt );
break;
/*2、设备建网/入网成功则显示本地网络地址*/
case ZDO_STATE_CHANGE:
SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
if ( (SampleApp_NwkState == DEV_ZB_COORD)
|| (SampleApp_NwkState == DEV_ROUTER)
|| (SampleApp_NwkState == DEV_END_DEVICE) )
{
//显示本地网络地址
short_ddr=NLME_GetShortAddr();
yy1=(uint8)((short_ddr&0xff00)>>8);
yy2=(uint8)short_ddr;
shortaddr[0]=48;
shortaddr[1]=120;
shortaddr[2]=hextoword1(yy1);
shortaddr[3]=hextoword2(yy1);
shortaddr[4]=hextoword1(yy2);
shortaddr[5]=hextoword2(yy2);
shortaddr[6]='\n';
pointer1=&shortaddr[0];
pointer2=&str_1[0];
pointer3=&str_2[0];
pointer4=&str_3[0];
HalUARTWrite(0,pointer4,1);
HalUARTWrite(0,pointer3,29);
HalUARTWrite(0,pointer4,1);
HalUARTWrite(0,pointer2,20);
HalUARTWrite(0,pointer1,7);
HalUARTWrite(0,pointer4,1);
//***************************************
}
else
{
// Device is no longer in the network
}
break;
…………(省略)
/*3、对接收的串口数据进行处理*/
if ( events & UART_RX_CB_EVT ) //串口数据处理
{
SampleApp_SPI_SendData( databuf, rxlen+1+2 );
return (events ^ UART_RX_CB_EVT);
}
}
****************************************************************************************
****************************************************************************************
6、定义AF层数据处理函数SampleApp_MessageMSGCB() (SampleApp.c)
默认采用的簇ID为SAMPLEAPP_PERIODIC_CLUSTERID
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
uint16 flashTime;
uint16 short_ddr;
uint8 *pointer1;
uint8 *pointer2;
uint8 *pointer3;
uint8 *pointer4;
uint8 *pointer5;
uint8 *pointer6;
uint8 *pointer7;
uint8 *pointer8;
uint8 *pointer9;
uint8 str_1[ ]="Source address:";
uint8 str_2[ ]="Destination address:";
uint8 str_3[ ]="Data length:";
uint8 str_4[ ]="Data:";
uint8 str_5[ ]={'\n'};
pointer1=&str_1[0];
pointer2=&str_2[0];
pointer3=&str_3[0];
pointer4=&str_4[0];
pointer9=&str_5[0];
uint8 Src_short_ddr_H;
uint8 Src_short_ddr_L;
uint8 Des_short_ddr_H;
uint8 Des_short_ddr_L;
uint8 word_buffer[4];
uint8 Src_shortaddr[7];
uint8 Des_shortaddr[7];
switch ( pkt->clusterId ) //判断簇ID
{
case SAMPLEAPP_PERIODIC_CLUSTERID:
/*####################################################*/
// flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
// HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
pointer5=&(pkt->cmd.Data[3]); //pointer5:具体数据首地址
word_buffer[0]=(pkt->cmd.Data[0])/100+48;
word_buffer[1]=((pkt->cmd.Data[0])%100)/10+48;
word_buffer[2]=(pkt->cmd.Data[0])%10+48;
word_buffer[3]='\n';
pointer6=word_buffer; //pointer6:数据长度
//----------------
Src_short_ddr_H=pkt->cmd.Data[1];
Src_short_ddr_L=pkt->cmd.Data[2];
Src_shortaddr[0]=48;
Src_shortaddr[1]=120;
Src_shortaddr[2]=hextoword1(Src_short_ddr_H);
Src_shortaddr[3]=hextoword2(Src_short_ddr_H);
Src_shortaddr[4]=hextoword1(Src_short_ddr_L);
Src_shortaddr[5]=hextoword2(Src_short_ddr_L);
Src_shortaddr[6]='\n';
pointer7=&Src_shortaddr[0]; //pointer7:源地址
//----------------
short_ddr=NLME_GetShortAddr();
Des_short_ddr_H=(uint8)((short_ddr&0xff00)>>8);
Des_short_ddr_L=(uint8)short_ddr;
Des_shortaddr[0]=48;
Des_shortaddr[1]=120;
Des_shortaddr[2]=hextoword1(Des_short_ddr_H);
Des_shortaddr[3]=hextoword2(Des_short_ddr_H);
Des_shortaddr[4]=hextoword1(Des_short_ddr_L);
Des_shortaddr[5]=hextoword2(Des_short_ddr_L);
Des_shortaddr[6]='\n';
pointer8=&Des_shortaddr[0]; //pointer8:目的地址
//----------------
HalUARTWrite ( 0, pointer1, 15 ); //源地址
HalUARTWrite ( 0, pointer7, 7 );
HalUARTWrite ( 0, pointer2, 20 ); //目的地址
HalUARTWrite ( 0, pointer8, 7 );
HalUARTWrite ( 0, pointer3, 12 ); //数据长度
HalUARTWrite ( 0, pointer6, 4 );
HalUARTWrite ( 0, pointer4, 5 ); //具体数据
HalUARTWrite ( 0, pointer5, pkt->cmd.Data[0] ); //pkt->cmd.Data[0]=rxlen,为原始长度
HalUARTWrite ( 0, pointer9, 1 ); //换行符
HalUARTWrite ( 0, pointer9, 1 );
//pointer1=&(pkt->cmd.Data[3]);
//HalUARTWrite ( 0, pointer1, 6 );
/*####################################################*/
break;
case SAMPLEAPP_FLASH_CLUSTERID://flash
flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
break;
}
}
****************************************************************************************
****************************************************************************************
7、定义串口数据处理函数SampleApp_SPI_SendData() (SampleApp.c)
我只有两个节点,所以这里采用最简单的单点传送方式.下载协调器程序时目标地址改为0x796F,下载终端程序时目标地址改为0x0000.默认ClusterID为SAMPLEAPP_PERIODIC_CLUSTERID.
void SampleApp_SPI_SendData( uint8 *buf, uint8 len )
{
SampleApp_SPI_SendData_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
SampleApp_SPI_SendData_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_SPI_SendData_DstAddr.addr.shortAddr = 0x796F; //0x796F;0x0000
// SampleApp_SendPeriodicMessage(); //测试用
if ( AF_DataRequest( &SampleApp_SPI_SendData_DstAddr,
(endPointDesc_t *)&SampleApp_epDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
len, buf,
&SampleApp_TransID,
0,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
osal_mem_free( databuf ); //必须释放内存,不然造成溢出!
}
else
{
osal_mem_free( databuf );
}
}
****************************************************************************************
****************************************************************************************
编译情况:
通信结果1:(关于开头的乱码说明参考后篇记录)
通信结果2:
最大数据只能达到52字节:(但在修改程序过程中,达到过83字节;等修改完整后只有52字节了):
测试 SampleApp_SPI_SendData()中的osal_mem_free( databuf ).如果不把databuf释放,则数据只能发送几次就停止.下面是添加osal_mem_free( databuf )后两边串口自动发送,测试时间>5分钟,收发一直保持稳定.
实物连接:
****************************************************************************************
****************************************************************************************
说明:
1、本文为个人学习笔记,程序均由个人编写(除十六进制转字符函数由青竹提供外).仅供参考,随时更新.
2、欢迎交流,转载请注明出处,谢谢!