|
RS232,也称标准串口,是目前最常用的一种串行通讯接口,因其成本低廉,应用广泛而被很多嵌入式系统所采用。在CC2530开发板上,由于LCD、LED等基本外接显示信息量有限,同时串口也方便了与其他系统进行通讯,所以它无疑成为了开发者最重要的一个调试手段。
本章的重点,就是以Zstack 2007中提供的例程--SerialApp为基础,对CC2530的串口部分进行详细的介绍。
[注:本文源自www.feibit.com--“飞比”Zigbee论坛,为尊重劳动者成果,如需转载请保留此行,并通知作者]
例3.基于Zstack 2007的串口通讯
在之前的“奥特曼Zigbee读书日记(三)和(四)”中,其实已经利用TI提供的基本库,从零开始,一步步地搭建了一个“老王”和“老张”打招呼的例程,但是由于他们俩说的所有话都是程序规定的,所以他们只能简单地说两句话“吃了吗”和“吃了”,然后不停地重复,我们中国人自然没有这么呆啦~~在本实验中,看看中国小伙是如何“远程”泡美国MM的~~~
在这个场景中,“中国小伙”通过QQ,向美国MM申请加为好友(申请绑定),在美国MM验证后(绑定成功)后,双方你一句我一句地就聊起来了(串口终端1<==>Zigbee节点1 <==>Zigbee节点2 <==>串口终端2)。如下图(1)所示:
图(1)
注:“日记”中的例程的串口通讯部分其实是抛开Zstack的串口程序而重新写的,但实际上Zstack已经做过这部分工作了,在本例程中,我们不对ZStack做任何修改,只是分析下其程序功能与原理。读者可以在安装ZStack-CC2530-2.3.0-1.4.0后,在C:\Texas Instruments\ZStack-CC2530-2.3.0-1.4.0\Projects\zstack\Utilities\SerialApp\CC2530DB目录下,打开SerialApp这个工程进行实验。
[一]程序功能
实现两个节点之间的绑定与通讯,同时每个节点可与其“上位机”--所边接的PC串口终端,进行通讯。示意如下:
图(2)
[二]操作说明
分别将Coordinator与EndDevice程序编译、下载至两套开发板后,按Reset键后,屏幕显示如下:
(图3)
(图4)
如果显示信息如上图所示,则表示网络初始化成功。
此时,按下任意一个节点的摇杆(Joystick)右键进行绑定申请,然后立即按下另外一个节点的Joystick右键进行绑定确认。此时,两个节点的红色LED灯--LED1,同时点亮,表示绑定成功,可以开始通信。
打开串口调试助手(注:可以在一台电脑上打开两个,或者在两台电脑上分别打开),分别对两个节点的串口进行设置,具体设置请参见图(1)中左边的设置,其中:串口的名称请在“设备管理器”中查找,波特率设为38400。
至此,准备工作已经做好。然后在任何一个串口终端上发送数据,此时另外一个终端即可接收此数据,即完成了一个(串口终端1==>Zigbee节点1 ==>Zigbee节点2 ==>串口终端2)的数据传输过程。
另外,在整个过程中,异常情况的LED显示:
1. LED1闪烁,表示在规定的绑定申请时间内,无设备对其进行绑定确认
2. LED3闪烁,表示连接节点丢失,如对方节点产生掉电等异常情况
[三]系统解析
本例程采用的是OSAL的系统,其原理读者可参考如下几篇文章,如有疑问请跟贴进行讨论:
1. 奥特曼Zigbee读书日记(二)--OSAL系统框架专题(作者:outman)
2. 深入浅出Z-Stack 2006 OSAL多任务资源分配机制(作者:cyril3 )
3. 我心目中的Zstack OSAL & Message(作者:ssls18years )
在此不做赘述,仅对此例程中的按键处理过程进行简单的讲解:
1. 申请绑定与绑定确认
首先,由某节点触发Joystick右键,即HAL_KEY_SW_2,对如何通过查询电平、确认按键事件,并调用相应的按键处理函数的过程有疑问的读者请参见上述文章。在按键处理函数--SerialApp_HandleKeys中,
if ( keys & HAL_KEY_SW_2 )
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
// Initiate an End Device Bind Request for the mandatory endpoint
txAddr.addrMode = Addr16Bit;
txAddr.addr.shortAddr = 0x0000; // Coordinator
ZDP_EndDeviceBindReq( &txAddr, NLME_GetShortAddr(),
SerialApp_epDesc.endPoint,
SERIALAPP_PROFID,
SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList,
SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList,
FALSE );
}
此处发起绑定请求,等待其他节点应答,而如果有一个节点也按了Joystick右键,同样发出了绑定请求,则本节点收到一个End_Device_Bind_rsp的信息,并在SerialApp_ProcessZDOMsgs函数中进行了处理,如下代码:
/*********************************************************************
* @fn SerialApp_ProcessZDOMsgs()
*
* @brief Process response messages
*
* @param none
*
* @return none
*/
static void SerialApp_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg )
{
switch ( inMsg->clusterID )
{
case End_Device_Bind_rsp:
if ( ZDO_ParseBindRsp( inMsg ) == ZSuccess )
{
// Light LED
HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );
}
break;
...
}
}
至此,中国小伙已经成功加美国MM为好友了~
接下来的事,大家想必都知道了。。。
看看他们是怎么发送信息,怎么接收信息的吧?
1. “串口终端1”的数据,如何被“节点1”所接收,并且发送出去的?
串口数据是由哪层来负责的呢?--HAL。。。恩,猜对了。但这个肯定不是靠猜的,其中的过程就不讲了。让我们从主循环(osal_start_system)的Hal_ProcessPoll函数找下去(用source insight的同学可以用ctrl +),Hal_ProcessPoll ==> HalUARTPoll ==> HalUARTPollDMA
这个HalUARTPollDMA函数里最后有这样一句话:dmaCfg.uartCB(HAL_UART_DMA-1, evt); 对dmaCfg.uartCB这个函数进行了调用,ctrl / 搜索这个dmaCfg.uartCB,发现SerialApp_Init函数有两句话:
uartConfig.callBackFunc = SerialApp_CallBack;
HalUARTOpen (SERIAL_APP_PORT, &uartConfig);
此处将dmaCfg.uartCB这个函数注册成为SerialApp_CallBack,也就是说SerialApp_CallBack函数每次循环中被调用一次,对串口的内容进行查询,如果DMA中接收到了数据,则调用HalUARTRead,将DMA数据读至数据buffer并通过AF_DataRequest函数发送出去,注意:送出去的信息的CLUSTERID(信息簇ID)号为SERIALAPP_CLUSTERID1。
总结一下这个过程:串口数据==>DMA接收==>主循环中通过SerialApp_CallBack查询==>从DMA获取并发送到空中。
2. 节点2在收到空中的信号后,如何传递给与其相连的串口终端?
节点2从空中捕获到信号后,在应用层上首先收到信息的就是SerialApp_ProcessEvent这个函数了,它收到一个AF_INCOMING_MSG_CMD的事件,并通知SerialApp_ProcessMSGCmd,执行以下代码
switch ( pkt->clusterId )
{
// A message with a serial data block to be transmitted on the serial port.
case SERIALAPP_CLUSTERID1:
... ...
// Transmit the data on the serial port.
if ( HalUARTWrite( SERIAL_APP_PORT, pkt->cmd.Data+1, (pkt->cmd.DataLength-1) ) )
{
// Save for next incoming message
SerialApp_RxSeq = seqnb;
stat = OTA_SUCCESS;
}
... ...
这样就将从空中获取到的信息,传给了串口终端2--美国MM,第一句话终于传到美国了~至于后面的事情嘛,我们就不关注了,看小伙自己的造化了~~~
另外,此例程中还有一种模式,就是这个中国小伙可以按条件搜索(Joystick左键,profileID与clusterID相同者响应),但这种条件找出的MM都比较有个性--只接受你的信息,但不给你发。想想也是,明显没诚意嘛~ 这种模式的细节,本教程不再涉及,有兴趣的读者可自行了解。
声明一点,要真想泡美国MM,只用我们所谈的Zigbee是暂时搞不定的,它最大的传输距离能有几公里就相当不易了,不过隔壁办公室的MM,倒是可以考虑送她一个~~~
[四]网络结构及协议解析
本例程的重点是串口的应用,其中涉及的组网及绑定等网络层细节,暂不详细阐述,将在后续的“奥特曼Zigbee读书日记”中进行深入分析。
[五]扩展思考
1. DMA方式与ISR方式的UART传输,有什么区别?分别如何实现?
2. ZDO_CB_MSG与AF_INCOMING_MSG_CMD等事件的产生机制?
3. 如何完成“多对一”或者“一对多”的通信?
4. 绑定表的存储位置与生命周期? |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|