ZigBee串口收发数据.docx

上传人:b****1 文档编号:313602 上传时间:2022-10-08 格式:DOCX 页数:21 大小:34.15KB
下载 相关 举报
ZigBee串口收发数据.docx_第1页
第1页 / 共21页
ZigBee串口收发数据.docx_第2页
第2页 / 共21页
ZigBee串口收发数据.docx_第3页
第3页 / 共21页
ZigBee串口收发数据.docx_第4页
第4页 / 共21页
ZigBee串口收发数据.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

ZigBee串口收发数据.docx

《ZigBee串口收发数据.docx》由会员分享,可在线阅读,更多相关《ZigBee串口收发数据.docx(21页珍藏版)》请在冰豆网上搜索。

ZigBee串口收发数据.docx

ZigBee串口收发数据

本文转载自:

 串口接收发送数据有两种方式,一种是中断的模式,另一种是DMA方式,这里主要以中断的方式,来看一下使用串口来发送,接收数据的整个流程。

这里以SerialApp例程为例子。

  在mian函数中的调用HalDriverInit();函数,在函数中初始化串口,主要是配置管脚和DMA通道

voidHalDriverInit(void)

{

...................................

#if(definedHAL_UART)&&(HAL_UART==TRUE)

 HalUARTInit();

#endif

....................................

}

 从程序中可以看出要想使用协议栈中串口,初始化串口必须定义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

#endif

#endif

   然后在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)

 {

   cfg0->rxHead=0;

 }

 else

 {

   cfg0->rxHead++;

 }

}

#endif

   该中断函数主要是把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

   

   #defineSERIAL_APP_RX_MAX 64

 #endif

#endif

 

SerialApp_Init()函数中有下面的赋值,

        =SERIAL_APP_RX_MAX;

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()来读取时间和串口,

voidHal_ProcessPoll()

{

 

 HalTimerTick();

 

#if(definedHAL_UART)&&(HAL_UART==TRUE)

 HalUARTPoll();

#endif

}

下面是HalUARTPoll();函数的源代码,在这里有对接收到的数据进行处理的程序。

voidHalUARTPoll(void)

{

#if(HAL_UART_0_ENABLE|HAL_UART_1_ENABLE)

 staticuint8tickShdw;

 uartCfg_t*cfg;

 uint8tick;

 

#ifHAL_UART_0_ENABLE

 //当发生串口接收中断时cfg0就会改变,如果串口没有数据输入cfg0为空,当接收到数据时cfg0将在串口中断服务程序中被改变

 if(cfg0)

 {

   cfg=cfg0;

 }

#endif

#ifHAL_UART_1_ENABLE

 if(cfg1)

 {

   cfg=cfg1;

 }

#endif

 

 //UsetheLSBofthesleeptimer(ST0mustbereadfirstanyway).

//系统上电后,睡眠定时器就会自动启动做自增计数ST0即睡眠定时器启动到现在计算值的最低8位

 tick=ST0-tickShdw;

 tickShdw=ST0;

 //下面是一个无限循环

 do

 {

 //------------发送超时时间

   if(cfg->txTick>tick)

   {

     cfg->txTick-=tick;

   }

   else

   {

     cfg->txTick=0;

   }

 //---------------------接收超时时间

   if(cfg->rxTick>tick)

   {

     cfg->rxTick-=tick;

   }

   else

   {

     cfg->rxTick=0;

   }

//是使用DMA方式还是使用中断方式

#ifHAL_UART_ISR

#ifHAL_UART_DMA

   if(cfg->flag&UART_CFG_DMA)

{

     pollDMA(cfg);

   }

   else//中断方式

#endif

     {

     pollISR(cfg);

     }

#elifHAL_UART_DMA

   pollDMA(cfg);

#endif

 

   

 

     if(cfg->rxHead!

=cfg->rxTail)//不相等表示有数据

     {

     uint8evt;

 

     if(cfg->rxHead>=(cfg->rxMax-SAFE_RX_MIN))

     {

//已保存的数据已经超过了安全界限,发送接收满事件

       evt=HAL_UART_RX_FULL;

     }

     elseif(cfg->rxHigh&&(cfg->rxHead>=cfg->rxHigh))

     {

//rxBuf[]接收到预设值(默认80字节),则触发事件,为什么是80,在上一篇转载的文章中有介绍,这里重点关注执行的流程。

       evt=HAL_UART_RX_ABOUT_FULL;

   }

     elseif(cfg->rxTick==0)

{

//超时事件

       evt=HAL_UART_RX_TIMEOUT;

   }

   else

   {

       evt=0;

   }

//如果发生事件,并且配置了回调函数则调用回调函数

   if(evt&&cfg->rxCB)

{

//(cfg->flag&UART_CFG_U1F)!

=0)判读是那个串口,如果是串口1则为1,否则为0

       cfg->rxCB(((cfg->flag&UART_CFG_U1F)!

=0),evt);

   }

   }

 

#ifHAL_UART_0_ENABLE

   if(cfg==cfg0)

   {

#ifHAL_UART_1_ENABLE

     if(cfg1)

     {

       cfg=cfg1;

     }

     else

#endif

       break;

   }

   else

#endif

     break;

 

 }while(TRUE);

#else

 return;

#endif

}

 

说明:

(1)下面我们看一下pollISR()函数

staticvoidpollISR(uartCfg_t*cfg)

{

//计算rxBuf[]中还有多少数据没有读出(以字节为单位)

 uint8cnt=UART_RX_AVAIL(cfg);

//如果串口没有接收到数据,也就是说没有发生过串口接收中断,那么cfg应为是为空的,则cnt=0如果发生了串口中断,则cnt计算出串口缓存中还有多少数据没有读出,这个缓存并不是硬件寄存器的缓存,而是程序中开辟一段空间

 if(!

(cfg->flag&UART_

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 高中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1