问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何在Zstack中使用串口

发布网友 发布时间:2022-05-09 22:53

我来回答

1个回答

热心网友 时间:2023-05-19 00:12

网上和论坛里面很多帖子都把精力集中到分析协议栈的串口工作机制上,比如分析DMA
工作原理,中断工作原理,然后分析输入和输出Buffer的处理等内容,学习者跟着协议栈的
串口底层一直到顶层转圈、转圈、再转圈,蒙圈了。
实际上,从应用角度讲,我们根本就没有必要去深入的追究Zstack中串口的工作机制,
也没有必要去搞清楚到底是怎么DMA和Interrupt的,我们只要调用几个简单函数就可以正
常使用串口了。其实协议栈已经把使用串口的条件准备好了,我们何必再纠结硬件底层实现
呢?应用者应该把协议栈看作一个平台,平台之上的应用才是我们的目标。下面我就讲一下
如何利用协议栈现有平台来实现自己的串口应用。这里我所提及的现有平台即是Zstack自带
的MT包,其实Zstack中的这个MT包功能相当强大,通过TI提供的ZTOOL工具可以用串
口的方式同整个协议栈进行交互,在我们编写Zigbee应用程序的过程中,很多不知道该如何
调用的函数都能在MT中找到参考!这个不多说了,有兴趣的同学可以去专门研究一下MT
包。
二、使用方法
在MT包中,已经有了串口初始化即串口数据处理函数可用,关键的几个函数出现在
MT_Uart.c文件中。我们拿出来几个关键函数说明一下(我捡重要语句注释):
第一个函数
void MT_UartInit ()
{ // 这个是MT中的一个串口初始化函数,主要作用是初始化串口工作的一些规矩
halUARTCfg_t uartConfig;

App_TaskID = 0; //处理串口数据的任务ID,可以先不管

uartConfig.configured = TRUE;
uartConfig.baudRate = MT_UART_DEFAULT_BAUDRATE;
//默认38400波特率;可以更改,但是可能有新问题,具体解释内容比较多,我不说;
uartConfig.flowControl = FALSE;//MT_UART_DEFAULT_OVERFLOW;
//禁止硬件流控,如果你的串口只有RXD,TXD和GND三条线,必须这么做;
uartConfig.flowControlThreshold= MT_UART_DEFAULT_THRESHOLD;
uartConfig.rx.maxBufSize = MT_UART_DEFAULT_MAX_RX_BUFF;
uartConfig.tx.maxBufSize = MT_UART_DEFAULT_MAX_TX_BUFF;
uartConfig.idleTimeout = MT_UART_DEFAULT_IDLE_TIMEOUT;
uartConfig.intEnable = TRUE;
#if defined (ZTOOL_P1) || defined (ZTOOL_P2)
uartConfig.callBackFunc = MT_UartProcessZToolData;
//如果编译的时候选择使用ZTOOL,那么MT_UartProcessZtoolData将会处理串口接到的数
//据串
#elif defined (ZAPP_P1) || defined (ZAPP_P2)
uartConfig.callBackFunc = MT_UartProcessZAppData;
//如果编译的时候没有选择ZTOOL,而是选择使用了ZAPP,则由MT_UartProcessZAppData
//函数来处理串口数据串
(*如果是用CC2530的P0口那两根串口引脚,你就要define ZTOOL_P1,如果是P1口的那
两根串口引脚,你就要define ZTOOL_P2,对于ZAPP_P1和ZAPP_P2也是一个情况*)
#else
uartConfig.callBackFunc = NULL;
//这个地方,如果你有兴趣自己写一个串口处理函数,那么你实现一个My_UartProcessData
//函数,然后填到这里,替换NULL。
#endif

#if defined (MT_UART_DEFAULT_PORT)
HalUARTOpen (MT_UART_DEFAULT_PORT, &uartConfig);
//如果定义了默认串口,(0或者1),打开串口,这个HalUartOpen函数会做一大堆工作,具
//体说来就是初始化呗。。。,我没有必要展开。需要注意的是这个函数把前面哪一堆初始化
//的uartConfig做为参数传进去了噢!
#else

(void)uartConfig;
#endif

#if defined (ZAPP_P1) || defined (ZAPP_P2)

MT_UartMaxZAppBufLen = 1;
MT_UartZAppRxStatus = MT_UART_ZAPP_RX_READY;
//这两句,如果是不想使用MT_UartProcessZToolData来处理串口数据,就。。。。
//再说就要深入串口机制了,网上讲解文章太多了,自己看吧,我一会儿使用
//MT_UartProcessZToolData。
#endif
}
第二个函数
void MT_UartRegisterTaskID( byte taskID )
{
App_TaskID = taskID;
}

第三个函数
void MT_UartProcessZToolData ( uint8 port, uint8 event )

osal_msg_deallocate ( (uint8 *)pMsg );
}
我们往上看看这个Message是什么?MT_UartProcessZToolData函数开始不远的地方有以下程
序段:
if (pMsg)
{

pMsg->hdr.event = CMD_SERIAL_MSG;
pMsg->msg = (uint8*)(pMsg+1);
pMsg->msg[MT_RPC_POS_LEN] = LEN_Token;
state = CMD_STATE1;
}
从这里看到,这个函数建立了一个消息头,用CMD_SERIAL_MSG做为消息,那么
osal_msg_send给任务的那个消息将会以CMD_SERIAL_MSG出现。。。。。。。
好了,以上三个函数看完,我们试着使用一下:
以GenericApp例子为例:
void GenericApp_Init( byte task_id )

XXXXXXXXXXXXX
XXXXXXXXXXXXX
(这个函数的最后,其实放在这个函数的哪里都行)
MT_UartInit(); //added by kennan
MT_UartRegisterTaskID(GenericApp_TaskID);


再看一下MT_UartRegisterTaskID(GenericApp_TaskID):
void MT_UartRegisterTaskID( byte taskID )
{
App_TaskID = taskID;
}

好了,这样,我们顺利地把串口发来的数据用MT_UartProcessZToolData来处理,并且把处理
后的数据打包发给了任务GenericApp_TaskID。
接下来,我们看一下在GenericApp_TaskID中如何处理吧。
在GenericApp的主处理函数中:
UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events )

if ( events & SYS_EVENT_MSG )
{
MSGpkt = (afIncomingMSGPacket_t*)osal_msg_receive( GenericApp_TaskID );
while ( MSGpkt )
{
switch ( MSGpkt->hdr.event )
{
case ZDO_CB_MSG:
GenericApp_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
break;
case KEY_CHANGE:
GenericApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t
*)MSGpkt)->keys );
break;
//增加
Case CMD_SERIAL_MSG:
ProcessUartData((mtOSALSerialData_t *)MSGpkt);
//这个函数你自己实现吧,想做啥呢?想做啥就做啥。如果想把接
//到的数据发回串口,调用HalUARTWrite就行了。

如果你不知道如何提取串口消息并处理,我就好人做到底,帮你实现一个ProcessUartData()
函数吧。这个函数的作用是把接收到的数据从CM0开始一直到payload的最后一个字节发送
给串口回显,不包括校验字节噢。
ProcessUartCommand((mtOSALSerialData_t *)MSGpkt)
{ //为了正确地进行下面工作,用mtOSALSerialData_t类型来指向整个zigbee数据包(不是串
//口数据包)
uint8 *pMsg;
pMsg = MSGpkt->msg;
//定义一个指针,指向真正的串口接收数据存放位置,MSGptk里面还有一些别的Header噢。
switch ( MSGpkt->hdr.event )
{
case CMD_SERIAL_MSG://如果是串口消息。。。。
HalLedSet( HAL_LED_RED, HAL_LED_MODE_FLASH );
//用LED灯指示一下收到数据啦
uint8 *pBuffer;
uint8 datalength;
uint8 i;
//定义几个变量,为从接收到的串口包里面提取数据以及写回串口做准备
datalength = *pMsg++;
//串口包中第一个字节是数据长度噢
pBuffer = osal_mem_alloc(datalength);
//分配一块内存准备把串口消息数据拿出来
if(pBuffer != NULL)
{
for(i = 0;i < datalength; i++)
*pBuffer++ = *pMsg++;
//把消息中的串口数据按照datalength数量挨个捞出来放血(放血啥意思?把池子
//里面那东西捞出来放血,明白不?
HalUARTWrite(0,pBuffer,datalength);
//捞出来放血的串口数据再写回串口,也就是送到串口助手显示
Osal_memfree(pBuffer);
//动态申请的内存记得用完了free一下噢
}
break;
default:
break;
}
}
说明:因为ZTOOL发过来的数据是有格式的,所以如果你用串口助手来测试,那么发的数
据要按照格式来,如果你不想按那个格式,你可以自己去修改MT_UartProcessZToolData里面
的相关程序。这种方法对于想要通过PC来控制zigbee的应用场合非常实用,因为你PC发过
来的一般也会有命令和数据,如果不用MT的格式,你自己也要规范一个格式,既然MT已
经有了,我们就借用就好。
对于MT_UartProcessZAppData这个处理方法,也就是你define了ZAPP_P1或ZAPP_P2
的情况,其机制也是类似的,只不过没有规定格式,你更自由,这里我就不多说了。
再有,如果你真的在测试的时候不知道那么一长串数据的xor 结果是多少,也可以去
MT_UartProcessZToolData函数中,找到:

//if ((MT_UartCalcFCS ((uint8*)&pMsg->msg[0], MT_RPC_FRAME_HDR_SZ +
LEN_Token) == FSC_Token))
{
osal_msg_send( App_TaskID, (byte *)pMsg );
}
else
//{

//osal_msg_deallocate ( (uint8 *)pMsg );
//}
把我标红的几个位置注释掉,就不会校验了,你也不用算xor结果了,不过发数据的时候
这个位置还是要的,你随便填个0好了。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
NBA下赛季常规赛MVP和总决赛MVP会是谁 吴前当选CBA常规赛MVP,他是实至名归吗? 如何申请安电表 如何申请独立电表 用电量大可以增加电表吗 出租他人铺面,原先房东已经安装过电表,因为用电量大,我想自己装电表可以... 梦见有个老人送佛画给我、让我在家供佛 ...分之一米还剩多少米如果截去四分之一还剩几分之几还剩多少米?_百度... 一根竹竿长四米,截去它的四分之三后,这根竹竿还剩全长的几分之几? ...这根绳子的几分之几后还剩下他的3/1,用去了( )m,还剩下( )_百度知... 如何在Zstack 中使用串口 一个电脑,一个手机可以同时登陆一个吗? 空调室外机一般直接挂在外墙上还是买架子? 东莞哪里有学工业机器人编程的地方?机器人维护培训有没有靠谱的? 简述ABB工业机器人tooldata、wobjdata和oaddata的含义? 三个关键的程序数据分别是 模拟人生3创造世界教做灰图点那 tooldataempty什么意思 沈阳哪能学习工业机器人? ABB机器人中抓手属于工具还是有效负载,抓取的物料属于什么 工业机器人实操与应用技巧的图书目录 robotstudio程序数据welddata的作用 空调外机架子怎么选? abb机械人,,工具数据tooldata的设定,,怎样设施的 相思这首诗怎么读 撷怎么读favicon.ico 关于和田籽玉的一些问题 高手来 和田玉白变红什么原因 潮州卢侗公墓 卢侗是卢植公第几世孙? 涂鸦智能app苹果闪退 用和密码能在电脑上登陆微信吗? iPhone在照片、截屏上涂鸦,新建涂鸦的app 一个手机和笔记本电脑可以共同使用吗? 怎么在电脑上直接登录 涂鸦app怎么取消一键登录 电脑怎么登录两个 涂鸦王国手机app怎么上传作品 “子”字的含义,150字 想向大家请教,古人表字中“子”字的含义 赵简子的“子”是什么意思? 看到史记中,赵简子、赵襄子,“子”字有什么特殊的含义么? wps文字的分栏符怎么设置颜色 WPS表格分页符的线怎么样加粗或者换颜色? 想知道怎么设置wps中,分页符线条的颜色与粗细。。如下图所示,是怎么设置出来的呢?求解 小皮筋戴在手上为什么会莫名其妙变大? 你知道啥叫橡皮筋管理? 求一个魔术 我问他为什么要带小皮筋 他说怕我的皮筋哪天突然断了 他好随时给我捆头发? 一个男孩明明没有女朋友却故意买个小皮筋带着,而且还故意露给你看,什么意思? 为什么我煮的西米露是碎的?