1、ZigBee串口收发数据本文转载自: 串口接收发送数据有两种方式,一种是中断的模式,另一种是DMA方式,这里主要以中断的方式,来看一下使用串口来发送,接收数据的整个流程。这里以SerialApp例程为例子。 在mian函数中的调用HalDriverInit();函数,在函数中初始化串口,主要是配置管脚和DMA通道void HalDriverInit (void)#if (defined HAL_UART) & (HAL_UART = TRUE) HalUARTInit();#endif 从程序中可以看出要想使用协议栈中串口,初始化串口必须定义HAL_UART和HAL_UART TRUE 在ha
2、l_board_cfg.h文件中。#ifndef HAL_UART#if (defined ZAPP_P1) | (defined ZAPP_P2) | (defined ZTOOL_P1) | (defined ZTOOL_P2)#define HAL_UART TRUE#else#define HAL_UART FALSE#endif#endif 然后在osal_start_system()开始系统后,会调用Hal_ProcessPoll()来读取时间和串口。 在CC2430的数据手册中有这样一段话。Data reception on the UART is initiatedwhen a
3、 1 is written to the UxCSR.RE bitThe UART will then search for a valid start bit on the RXDx input pin and set theUxCSR.ACTIVE bit high. When a validstart bit has been detected the received byte is shifted into the receive register .The UxCSR.RX_BYTE bit is set and a receive interrupt is generated w
4、hen the operation has completed. The received data byte is available through the UxBUF register. When UxBUF is read, UxCSR.RX_BYTE is cleared by hardware. 当有数据接收时,UxCSR.RE位将被置1,然后,UART将在RXDx的输入引脚上查找一个有效的开始位,当找到这个开始位时,将设置UxCSR.ACTIVE位为高电平。当一个有效的开始位被查找到,收到的字节将被移动到接收寄存器中。然后,UxCSR.RX_BYTE位设为1.并且,当这个接收操作
5、完成后接收中断会被产生。接收到的数据可以通过操作UxBUF寄存器,当UxBUF寄存器的数据被读出后,UxCSR.RX_BYTE位被硬件清除。串口发生中断首先调用中断的处理函数,这个是接收的中断函数。#if HAL_UART_0_ENABLEHAL_ISR_FUNCTION( halUart0RxIsr, URX0_VECTOR ) cfg0-rxBufcfg0-rxHead = U0DBUF; if ( cfg0-rxHead = cfg0-rxMax ) cfg0-rxHead = 0; else cfg0-rxHead+; #endif 该中断函数主要是把U0DBUF寄存器,也就是接收到数
6、据的寄存器,把数据读取来放到UART的结构体中的,cfg0-rxBuf,中,这个数组的内存分配是在HalUARTOpen()函数中。SerialApp.c中有下面的定义#if !defined( SERIAL_APP_RX_MAX ) #if (defined( HAL_UART_DMA ) & HAL_UART_DMA #define SERIAL_APP_RX_MAX 128 #else #define SERIAL_APP_RX_MAX 64 #endif#endifSerialApp_Init()函数中有下面的赋值, = SERIAL_APP_RX_MAX;HalUARTOpen()函
7、数中有下面的赋值:所以其cfg-rxMax=128,cfg-rxMax = config-rx.maxBufSize; 其中rxHead这个参数始终指向像一个参数被存放到rxBuf的位置。因为硬件串口缓存器U0DBUF只能存放一个字节,如果不及时把这个接收到的转移出去,那么就会被下一个到来的字节覆盖掉,所以rxHead变量就指向了这个存放的地址,当然是基于定义的rxBuf存储空间。而if ( cfg0-rxHead = cfg0-rxMax )这一句判断也说明的很清楚,一旦这个计数达到了定义的最大接收数量,也就是说已经把rxBuf存储空间占满了,那么就不能在继续存放了。 中断函数执行完后,就应
8、该跳到发生中断时执行的地方,这时程序继续执行,然后在osal_start_system()开始系统后,会循环调用Hal_ProcessPoll()来读取时间和串口,void Hal_ProcessPoll () HalTimerTick();#if (defined HAL_UART) & (HAL_UART = TRUE) HalUARTPoll();#endif下面是HalUARTPoll();函数的源代码,在这里有对接收到的数据进行处理的程序。void HalUARTPoll( void )#if ( HAL_UART_0_ENABLE | HAL_UART_1_ENABLE ) sta
9、tic uint8 tickShdw; uartCfg_t *cfg; uint8 tick;#if HAL_UART_0_ENABLE /当发生串口接收中断时cfg0就会改变,如果串口没有数据输入cfg0为空,当接收到数据时cfg0将在串口中断服务程序中被改变 if ( cfg0 ) cfg = cfg0; #endif#if HAL_UART_1_ENABLE if ( cfg1 ) cfg = cfg1; #endif / Use the LSB of the sleep timer (ST0 must be read first anyway)./系统上电后,睡眠定时器就会自动启动做自
10、增计数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方式还是使用中断方式#if HAL_UART_ISR#if HAL_UART_DMA if ( cfg-flag & UART_CFG_D
11、MA ) pollDMA( cfg ); else/中断方式#endif pollISR( cfg ); #elif HAL_UART_DMA pollDMA( cfg );#endif if ( cfg-rxHead != cfg-rxTail ) /不相等表示有数据 uint8 evt; if ( cfg-rxHead = (cfg-rxMax - SAFE_RX_MIN) ) /已保存的数据已经超过了安全界限,发送接收满事件 evt = HAL_UART_RX_FULL; else if ( cfg-rxHigh & (cfg-rxHead = cfg-rxHigh) ) /rxBuf
12、接收到预设值(默认80字节),则触发事件,为什么是80,在上一篇转载的文章中有介绍,这里重点关注执行的流程。 evt = HAL_UART_RX_ABOUT_FULL; else if ( 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), ev
13、t ); #if HAL_UART_0_ENABLE if ( cfg = cfg0 ) #if HAL_UART_1_ENABLE if ( cfg1 ) cfg = cfg1; else#endif break; else#endif break; while ( TRUE );#else return;#endif说明:(1)下面我们看一下pollISR()函数static void pollISR( uartCfg_t *cfg )/计算rxBuf中还有多少数据没有读出(以字节为单位) uint8 cnt = UART_RX_AVAIL( cfg );/如果串口没有接收到数据,也就是说没有发生过串口接收中断,那么cfg应为是为空的,则cnt=0如果发生了串口中断,则cnt计算出串口缓存中还有多少数据没有读出,这个缓存并不是硬件寄存器的缓存,而是程序中开辟一段空间 if ( !(cfg-flag & UART_
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1