ZigBee串口收发数据Word文档格式.docx
《ZigBee串口收发数据Word文档格式.docx》由会员分享,可在线阅读,更多相关《ZigBee串口收发数据Word文档格式.docx(21页珍藏版)》请在冰豆网上搜索。
![ZigBee串口收发数据Word文档格式.docx](https://file1.bdocx.com/fileroot1/2022-10/8/dc3858ef-304c-49c7-80cf-751604cbf7d3/dc3858ef-304c-49c7-80cf-751604cbf7d31.gif)
....................................
}
从程序中可以看出要想使用协议栈中串口,初始化串口必须定义HAL_UART和HAL_UART
TRUE在hal_board_cfg.h文件中。
#ifndefHAL_UART
#if(definedZAPP_P1)||(definedZAPP_P2)||(definedZTOOL_P1)||(definedZTOOL_P2)
#defineHAL_UARTTRUE
#else
#defineHAL_UARTFALSE
然后在osal_start_system()开始系统后,会调用Hal_ProcessPoll()来读取时间和串口。
在CC2430的数据手册中有这样一段话。
DatareceptionontheUARTisinitiatedwhena1iswrittentothe
UxCSR.REbitTheUARTwillthensearchforavalidstartbitontheRXDxinputpinandsettheUxCSR.ACTIVEbithigh.Whenavalidstartbithasbeendetectedthereceived
byteisshiftedintothereceiveregister.The
UxCSR.RX_BYTEbitissetandareceiveinterruptisgeneratedwhentheoperationhascompleted.ThereceiveddatabyteisavailablethroughtheUxBUFregister.WhenUxBUFisread,
UxCSR.RX_BYTEisclearedbyhardware.
当有数据接收时,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)
cfg0->
rxBuf[cfg0->
rxHead]=U0DBUF;
if(cfg0->
rxHead==cfg0->
rxMax)
{
rxHead=0;
}
else
rxHead++;
该中断函数主要是把U0DBUF寄存器,也就是接收到数据的寄存器,把数据读取来放到UART的结构体中的,cfg0->
rxBuf[],中,这个数组的内存分配是在HalUARTOpen()函数中。
SerialApp.c中有下面的定义
#if!
defined(SERIAL_APP_RX_MAX)
#if(defined(HAL_UART_DMA))&
HAL_UART_DMA
#defineSERIAL_APP_RX_MAX
128
#else
64
#endif
SerialApp_Init()函数中有下面的赋值,
=SERIAL_APP_RX_MAX;
HalUARTOpen()函数中有下面的赋值:
所以其cfg->
rxMax=128,
cfg->
rxMax=config->
rx.maxBufSize;
其中rxHead这个参数始终指向像一个参数被存放到rxBuf的位置。
因为硬件串口缓存器U0DBUF只能存放一个字节,如果不及时把这个接收到的转移出去,那么就会被下一个到来的字节覆盖掉,所以rxHead变量就指向了这个存放的地址,当然是基于定义的rxBuf存储空间。
而if(cfg0->
rxMax)这一句判断也说明的很清楚,一旦这个计数达到了定义的最大接收数量,也就是说已经把rxBuf存储空间占满了,那么就不能在继续存放了。
中断函数执行完后,就应该跳到发生中断时执行的地方,这时程序继续执行,然后在osal_start_system()开始系统后,会循环调用Hal_ProcessPoll()来读取时间和串口,
voidHal_ProcessPoll()
HalTimerTick();
HalUARTPoll();
下面是HalUARTPoll();
函数的源代码,在这里有对接收到的数据进行处理的程序。
voidHalUARTPoll(void)
#if(HAL_UART_0_ENABLE|HAL_UART_1_ENABLE)
staticuint8tickShdw;
uartCfg_t*cfg;
uint8tick;
//当发生串口接收中断时cfg0就会改变,如果串口没有数据输入cfg0为空,当接收到数据时cfg0将在串口中断服务程序中被改变
if(cfg0)
cfg=cfg0;
#ifHAL_UART_1_ENABLE
if(cfg1)
cfg=cfg1;
//UsetheLSBofthesleeptimer(ST0mustbereadfirstanyway).
//系统上电后,睡眠定时器就会自动启动做自增计数ST0即睡眠定时器启动到现在计算值的最低8位
tick=ST0-tickShdw;
tickShdw=ST0;
//下面是一个无限循环
do
//------------发送超时时间
if(cfg->
txTick>
tick)
cfg->
txTick-=tick;
txTick=0;
//---------------------接收超时时间
rxTick>
rxTick-=tick;
rxTick=0;
//是使用DMA方式还是使用中断方式
#ifHAL_UART_ISR
#ifHAL_UART_DMA
flag&
UART_CFG_DMA)
pollDMA(cfg);
else//中断方式
pollISR(cfg);
#elifHAL_UART_DMA
rxHead!
=cfg->
rxTail)//不相等表示有数据
uint8evt;
rxHead>
=(cfg->
rxMax-SAFE_RX_MIN))
//已保存的数据已经超过了安全界限,发送接收满事件
evt=HAL_UART_RX_FULL;
elseif(cfg->
rxHigh&
(cfg->
rxHigh))
//rxBuf[]接收到预设值(默认80字节),则触发事件,为什么是80,在上一篇转载的文章中有介绍,这里重点关注执行的流程。
evt=HAL_UART_RX_ABOUT_FULL;
rxTick==0)
//超时事件
evt=HAL_UART_RX_TIMEOUT;
evt=0;
//如果发生事件,并且配置了回调函数则调用回调函数
if(evt&
rxCB)
//(cfg->
UART_CFG_U1F)!
=0)判读是那个串口,如果是串口1则为1,否则为0
rxCB(((cfg->
=0),evt);
if(cfg==cfg0)
break;
}while(TRUE);
return;
说明:
(1)下面我们看一下pollISR()函数
staticvoidpollISR(uartCfg_t*cfg)
//计算rxBuf[]中还有多少数据没有读出(以字节为单位)
uint8cnt=UART_RX_AVAIL(cfg);
//如果串口没有接收到数据,也就是说没有发生过串口接收中断,那么cfg应为是为空的,则cnt=0如果发生了串口中断,则cnt计算出串口缓存中还有多少数据没有读出,这个缓存并不是硬件寄存器的缓存,而是程序中开辟一段空间
if(!
(cfg->
UART_