我是靠谱客的博主 无心仙人掌,最近开发中收集的这篇文章主要介绍ZigBee串口收发数据,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

ZigBee串口收发数据

  

本文转载自:http://blog.chinaunix.net/space.php?uid=20788636&do=blog&id=1841411

 方式,这里主要以中断的方式,来看一下使用串口来发送,接收数据的整个流程。这里以SerialApp例程为例子。

 mian函数中的调用HalDriverInit();函数,在函数中初始化串口,主要是配置管脚和DMA通道
voidHalDriverInit (void)
{
...................................
#if(defined HAL_UART) && (HAL_UART ==TRUE)
 
#endif
....................................
}
 hal_board_cfg.h文件中。
#ifndef HAL_UART
#if (defined ZAPP_P1) ||(defined ZAPP_P2) || (defined ZTOOL_P1) || (definedZTOOL_P2)
#define HAL_UARTTRUE
#else
#define HAL_UARTFALSE
#endif
#endif
 
 
Data reception on theUART is initiatedwhen a 1 is written to the 
The UART will thensearch for a valid start bit on the RXDx input pin and setthe
UxCSR.ACTIVE bit high.When a validstart bit has been detected thereceived 
 UxCSR.RE位将被置1,然后,UART将在RXDx的输入引脚上查找一个有效的开始位,当找到这个开始位时,将设置UxCSR.ACTIVE位为高电平。当一个有效的开始位被查找到,收到的字节将被移动到接收寄存器中。然后,UxCSR.RX_BYTE位设为1.并且,当这个接收操作完成后接收中断会被产生。接收到的数据可以通过操作UxBUF寄存器,当UxBUF寄存器的数据被读出后,UxCSR.RX_BYTE位被硬件清除。串口发生中断首先调用中断的处理函数,这个是接收的中断函数。
#ifHAL_UART_0_ENABLE
HAL_ISR_FUNCTION(halUart0RxIsr, URX0_VECTOR )
{
 
 
 
 
 
 
 
 
 
 
}
#endif
 U0DBUF寄存器,也就是接收到数据的寄存器,把数据读取来放到UART的结构体中的,cfg0->rxBuf[],中,这个数组的内存分配是在HalUARTOpen()函数中。
SerialApp.c中有下面的定义
#if !defined( SERIAL_APP_RX_MAX)
 
 
 
 
 
 
#endif
 
SerialApp_Init()函数中有下面的赋值,
 uartConfig.rx.maxBufSize 
HalUARTOpen()函数中有下面的赋值:所以其cfg->rxMax=128
cfg->rxMax =config->rx.maxBufSize;
 rxHead这个参数始终指向像一个参数被存放到rxBuf的位置。因为硬件串口缓存器U0DBUF只能存放一个字节,如果不及时把这个接收到的转移出去,那么就会被下一个到来的字节覆盖掉,所以rxHead变量就指向了这个存放的地址,当然是基于定义的rxBuf存储空间。
if (cfg0->rxHead == cfg0->rxMax)这一句判断也说明的很清楚,一旦这个计数达到了定义的最大接收数量,也就是说已经把rxBuf存储空间占满了,那么就不能在继续存放了。
 osal_start_system()开始系统后,会循环调用Hal_ProcessPoll()来读取时间和串口,
void Hal_ProcessPoll()
{
 
 
 
#if (defined HAL_UART)&& (HAL_UART == TRUE)
 
#endif
}
下面是HalUARTPoll();函数的源代码,在这里有对接收到的数据进行处理的程序。
void HalUARTPoll( void)
{
#if ( HAL_UART_0_ENABLE |HAL_UART_1_ENABLE )
 
 
 
 
#ifHAL_UART_0_ENABLE
 
 
 
 
 
#endif
#ifHAL_UART_1_ENABLE
 
 
 
 
#endif
 
  // Use the LSB of the sleep timer (ST0 must be read firstanyway).
//系统上电后,睡眠定时器就会自动启动做自增计数ST0即睡眠定时器启动到现在计算值的最低8位
 
 
 下面是一个无限循环
 
 
 //------------发送超时时间
 
 
 
 
 
 
 
 
 //---------------------接收超时时间
 
 
 
 
 
 
 
 
//是使用DMA方式还是使用中断方式
#if HAL_UART_ISR
#if HAL_UART_DMA
 
{
 
 
 //中断方式
#endif
 
 
 
#elif HAL_UART_DMA
 
#endif
 
 
 
 //不相等表示有数据
 
 
 
 
 
//已保存的数据已经超过了安全界限,发送接收满事件
 
 
 
 
//rxBuf[]接收到预设值(默认80字节),则触发事件,为什么是80,在上一篇转载的文章中有介绍,这里重点关注执行的流程。
 
 
 
{
//超时事件
 
 
 
 
 
 
//如果发生事件,并且配置了回调函数则调用回调函数
 
{
//(cfg->flag& UART_CFG_U1F)!=0)判读是那个串口,如果是串口1则为1,否则为0
 
 
 
 
#ifHAL_UART_0_ENABLE
 
 
#ifHAL_UART_1_ENABLE
 
 
 
 
 
#endif
 
 
 
#endif
 
 
 
#else
 
#endif
}
 
说明:(1)下面我们看一下pollISR()函数
static void pollISR( uartCfg_t*cfg )
{
//计算rxBuf[]中还有多少数据没有读出(以字节为单位)
 
//如果串口没有接收到数据,也就是说没有发生过串口接收中断,那么cfg应为是为空的,则cnt=0如果发生了串口中断,则cnt计算出串口缓存中还有多少数据没有读出,这个缓存并不是硬件寄存器的缓存,而是程序中开辟一段空间
 
 
//这里是针对流控制的,如果又有新的数据接收到了那么就要重置超时时间(超时时间由睡眠定时器来控制),而且需要把已经读出的数据数目减去!
 
 
 
 
 
 
 
 
 
 
 
 
 
}
#endif
pollISR()函数主要作用就是设置rxTick和rxCn,
//关于安全界限,在程序中有下面一段:
//如果声明了流控制,为保证数据的正确接收需要在RX缓存区中预留出足够的空间。CC2430可以使用的最大串口波特率为115.2k。这个安全界限的数字跟使用的波特率还有串口tick有关。具体参考《Z-STACK问题之串口结构uartCfg_t乱说》文章。
 寄存器中的数据传送到rxbuf[]中,这时rxHead和rxTail的值不在相等,其中,rxHead是rxBuf[]接收到数据的个数,rxTail是rxBuf[]移出的数据个数,再根据两者的差值,判断具体的事件evt。然后,根据evt和设置的回调函数,通过cfg->rxCB调用相应的回调函数。代码也是体显在下面一句。
cfg->rxCB(((cfg->flag & UART_CFG_U1F)!=0), evt);
第一个参数主要是判断,是UART1还是UART0.第二个参数是触发的事件类型,那个个回调函数,具体是指向函数呢?
 void SerialApp_Init( uint8 task_id )初始化函数中,对串口进行了配置,其中下面两句中有关于回调函数的。
#else
 
#endif
 
其中,在HalUARTOpen()函数中,有下面的一条语句,
uint8 HalUARTOpen( uint8 port,halUARTCfg_t *config )
{
 ...................
cfg->rxCB =config->callBackFunc;
...................
}
 也就是调用下面的rxCB函数。程序中定义了两个串口接收缓冲区:otaBufotaBuf2.otaBuf中无数据时,处于空闲状态时,由otaBuf接收串口数据;当otaBuf中保留有数据时,下等待接收节点发送接收数据响应或由于某些正在重新给接收节点发送数据时,可通过otaBuf2接收数据,当otaBufotaBuf2都没有处于空闲状态时,说明数据没有及时发送给接收节点,发生了数据累积,缓冲区被占用,需要进行流量控制,所以直接退出接收回调函数,暂不接收数据。
static void rxCB( uint8 port,uint8 event )
{
 
 
 
 //缓冲区被占用
 
 
 
 
 
 
 
 
 
 
 
 
  // Length is not expectedto ever be zero.
 
 
 
 
 
 
 //otaBuf正在被占用
 
 //otaBuf2接收数据
 
 
 
 
 //otaBuf接收数据
 
 
 
 
}
#endif
在事件处理函数中,有下面的判断。
UINT16 SerialApp_ProcessEvent(uint8 task_id, UINT16 events )
{
........................
if ( events &SERIALAPP_MSG_SEND_EVT )
 
 
 
 
.........................
}
 SerialApp_SendData()函数的源代码,调用AF_DataRequest(),通过OTA发送数据。由于在数据包之前增加了序列号SerialApp_SeqTx,多次重发的数据不会被接收节点重复发送到串口。
static void SerialApp_SendData(uint8 *buf, uint8 len )
{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//在设定的时间内没有发送成功,则重新发送。
 
 
 
 
 
 
 重发的次数
 
}
 
void SerialApp_ProcessMSGCmd(afIncomingMSGPacket_t *pkt )
{
 
 
 
 
 
 
 
 //接收节点收到的接收数据命令,
 
 
 
 // Keep message if not a repeatpacket
 
 
 
 // Transmit the data on the serialport.接收到的发送到串口
 
 
 
 // Save for next incomingmessage
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 // Select approproiate OTA flow-controldelay.
 
 
 // Build & send OTA responsemessage.发送响应消息
 
 
 
rspBuf[3] = HI_UINT16( delay);
//发送接收数据响应命令
 
 
 
 
 
 
 
 
 
 
 
 
 // Store the address for the timeout retry.存储发送超时的,目的地址
 
 
 
 
 接收到接收数据响应命令
 
 
 
 //目的设备接收数据的状态
 
 // Remove timeout waiting for response fromother device.接收到返回的状态后,关闭定时器
 
 释放缓存区
 
 
 
 
 
 
 
 
 
 
 
 
}
 
UINT16 SerialApp_ProcessEvent(uint8 task_id, UINT16 events )
{
 //ZDO层接收到注册过的消息
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 //接收到命令,然后执行,zigbee协议信息的传递有两种方式:消息和命令,消息长度不限,命令的大小则严格规定
 
//执行发送过来消息命令的回调函数
SerialApp_ProcessMSGCmd(MSGpkt );
 
 
 
 
 
 
 
 
 // Return unprocessedevents
 
 
//发送数据的事件,这里是串口通过CC2430发送数据到另一个设备
 
 
 
 
 
 
//重发数据的事件,如果发送数据没有成功的话
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//发送接收数据响应的重发事件
 
 
 
 
 
 
 
   
 
 
 
 
 
 
 
 
 
 
 
 
#ifSERIAL_APP_LOOPBACK
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#endif
 
 
}
 SERIALAPP_MSG_RTRY_EVT重发数据,重发的次数由rtyCnt设定。由于在数据包之前增加了序列号SerialApp_SeqTx,多次生发的数据不会被接收节点重复发送到串口。别外,加入了数据接收响应机制,发送节点在发送完数据后,等待接收节点返回接收数据响应,收到返回接收数据响应的命令SERIALAPP_CLUSTERID2:后,判断信息包中的接收状态参数。若接收状态为OTA_DUP_MSG,表明接收节点串口繁忙,应启动重发机制,延时后产生重发数据事件,若接收状态为OTA_SUCCESS,表明接收节点将数据成功发送到串口,就释放缓存区,等待串口接收下一包数据。
 
 

最后

以上就是无心仙人掌为你收集整理的ZigBee串口收发数据的全部内容,希望文章能够帮你解决ZigBee串口收发数据所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论