原创 【原创】ZigBee学习之42——协议栈中的串口操作

2010-2-27 13:25 5587 6 7 分类: MCU/ 嵌入式

如果要使用协议栈中提供的串口,则需要定义HAL_UARTHAL_UART  TRUEhal_board_cfg.h】。首先初始化串口,在主函数中调用HalDriverInit()时,在函数中初始化串口,主要是配置管脚和DMA通道。然后在osal_start_system()开始系统后,会调用Hal_ProcessPoll()来读取时间和串口,<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


void Hal_ProcessPoll ()


{


  HalTimerTick();


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


  HalUARTPoll();


#endif


}


//来看下串口poll函数,我们只看UART0的,因为我的开发板使用这个串口


void HalUARTPoll( void )


{


#if ( HAL_UART_0_ENABLE | HAL_UART_1_ENABLE )


  static uint8 tickShdw;


  uartCfg_t *cfg;


  uint8 tick;


 


#if HAL_UART_0_ENABLE


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


  if ( cfg0 )


  {


    cfg = cfg0;


  }


#endif


// Use the LSB of the sleep timer (ST0 must be read first anyway).


//系统上电后,睡眠定时器就会自动启动做自增计数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_DMA )


    {


      pollDMA( cfg );


    }


    else


#endif


      {


      pollISR( cfg );


              //中断方式


static void pollISR( uartCfg_t *cfg )


{


//如果串口没有接收到数据,也就是说没有发生过串口接收中断,那么cfg应为是为空的,则cnt=0


//如果发生了串口中断,则cnt计算出串口缓存中还有多少数据没有读出,这个缓存并不是硬件寄存器的缓存,而是程序中开辟一段空间


  uint8 cnt = UART_RX_AVAIL( cfg );


 


  if ( !(cfg->flag & UART_CFG_RXF) )


{


//这里是针对流控制的,如果又有新的数据接收到了那么就要重置超时时间(超时时间由睡眠定时器来控制),而且需要把已经读出的数据数目减去!


    // If anything received, reset the Rx idle timer.


    if ( cfg->rxCnt != cnt )


    {


      cfg->rxTick = HAL_UART_RX_IDLE;


      cfg->rxCnt = cnt;


    }


 


    /* It is necessary to stop Rx flow in advance of a full Rx buffer because


     * bytes can keep coming while sending H/W fifo flushes.


     */


       //当接收缓存超过安全界限的时候停止RX


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


    {


      RX_STOP_FLOW( cfg );


}


//关于安全界限,在程序中有下面一段:


/* Need to leave enough of the Rx buffer free to handle the incoming bytes


 * after asserting flow control, but before the transmitter has obeyed it.


 * At the max expected baud rate of 115.2k, 16 bytes will only take ~1.3 msecs,


 * but at the min expected baud rate of 38.4k, they could take ~4.2 msecs.


 * SAFE_RX_MIN and DMA_RX_DLY must both be consistent according to


 * the min & max expected baud rate.


 */


//如果声明了流控制,为保证数据的正确接收需要在RX缓存区中预留出足够的空间。CC2430可以使用的最大串口波特率为115.2k。这个安全界限的数字跟使用的波特率还有串口tick有关。


#if !defined( SAFE_RX_MIN )


  #define SAFE_RX_MIN  48  // bytes - max expected per poll @ 115.2k


  // 16 bytes @ 38.4 kBaud -> 4.16 msecs -> 138 32-kHz ticks.


  #define DMA_RX_DLY  140


  //  2 bytes @ 38.4 kBaud -> 0.52 msecs ->  17 32-kHz ticks.


  #define DMA_TX_DLY   20


#endif


//超时计数利用的是睡眠定时器,而睡眠定时器是以32Khz时钟计数的,所以1微妙约为33个计数值(如果使用外部32.768KHz晶振)    


// The timeout tick is at 32-kHz, so multiply msecs by 33.


#define RX_MSECS_TO_TICKS  33


//超时时间设为传输一个字节的时间,之所以是6而不是8我觉得是排除掉串口协议中的停止位和起始位的结果


// The timeout only supports 1 byte.


#if !defined( HAL_UART_RX_IDLE )


  #define HAL_UART_RX_IDLE  (6 * RX_MSECS_TO_TICKS)


#endif


  }


}


      }


#elif HAL_UART_DMA


    pollDMA( cfg );


#endif


 


    /* The following logic makes continuous callbacks on any eligible flag


     * until the condition corresponding to the flag is rectified.


     * So even if new data is not received, continuous callbacks are made.


     */


      if ( cfg->rxHead != cfg->rxTail )


      {


//如果接收缓存中有数据,当接收数据时rxHead会增计数,当读取数据时rxTail会增计数,两个标志的初始值都为0,所以这两个标志的差值就指示了缓存中有多少的数据


      uint8 evt;


 


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


      {


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


        evt = HAL_UART_RX_FULL;


      }


      else if ( cfg->rxHigh && (cfg->rxHead >= cfg->rxHigh) )


      {


        evt = HAL_UART_RX_ABOUT_FULL;


      }


        else if ( cfg->rxTick == 0 )


      {


//超时事件


          evt = HAL_UART_RX_TIMEOUT;


      }


      else


      {


          evt = 0;


      }


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


      if ( evt && cfg->rxCB )


      {


          cfg->rxCB( ((cfg->flag & UART_CFG_U<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />1F)!=0), evt );


//(cfg->flag & UART_CFG_U1F)!=0)判读是那个串口,如果是串口1则为1,否则为0


      }


    }


//下面的没看懂,下面的判断好像是没有用一样,不管是哪个条件都break了!


    if ( cfg == cfg0 )


    {


        break;


    }


    else


      break;


  } while ( TRUE );


#else


  return;


#endif


}


//在来看一下串口中断,就是将U0DBUF的数据存放到cfg0->rxBuf里面,并且更改rxHead标志


HAL_ISR_FUNCTION( halUart0RxIsr, URX0_VECTOR )


{


  cfg0->rxBuf[cfg0->rxHead] = U0DBUF;


 


  if ( cfg0->rxHead == cfg0->rxMax )


  {


    cfg0->rxHead = 0;


  }


  else


  {


    cfg0->rxHead++;


  }


}


//cfg和回调函数在HalUARTOpen (SERIAL_APP_PORT, &uartConfig)中配置

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户1328825 2010-4-1 09:26

谢谢你的经验!
相关推荐阅读
huotingtu_505472073 2014-01-12 22:18
嵌入式程序员面试问题集锦
这个测试适于不同水平的应试者,大多数初级水平的应试者的成绩会很差,经验丰富的程序员应该有很好的成绩。为了让你能自己决定某些问题的偏好,每个问题没有分配分数,如果选择这些考题为你所用,请自行按你的意...
huotingtu_505472073 2011-04-14 23:24
【转】一种实用的步进电机驱动电路
1 引言步进电动机是一种将电脉冲信号转换成角位移或线位移的精密执行元件,由于步进电机具有控制方便、体积小等特点,所以在数控系统、自动生产线、自动化仪表、绘图机和计算机外围设备中得到广泛应用。微电子学的...
huotingtu_505472073 2011-04-14 23:22
【转】几种微型电机驱动电路分析
 以下所述电路用于3V供电的微型直流电机的驱动,这种电机有两根引线,更换两根引线的极性,电机换向。该驱动电路要求能进行正反转和停止控制。 电路一: 如下图所示,这电路是作者最初设计的电路,P1.3、P...
huotingtu_505472073 2011-02-18 19:57
【转】集成运放组成的电压比较器
1. 功能及应用:主要用来判断输入信号电位之间的相对大小,它至少有两个输入端及一个输出端,通常用一个输入端接被比较信号Ui,另一个则接基准电压VR 定门限电压(或称阀值)的UT。输出通常仅且仅有二...
huotingtu_505472073 2011-01-26 08:05
【转】直流无刷电动机工作原理与控制方法12
研究结果表明,在半导体薄片上产生的霍尔电动势E可用下式表示: 式中RH ——霍尔系数(  );IH——控制电流(A);B——磁感应强度(T);d——薄片厚度(m);p——材料电阻率(Ω*s);...
huotingtu_505472073 2011-01-26 07:55
【转】直流无刷电动机工作原理与控制方法1
序言   由于直流无刷电动机既具有交流电动机的结构简单、运行可靠、维护方便等一系列优点,又具备直流电动机的运行效率高、无励磁损耗以及调速性能好等诸多优点,故在当今国民经济各领域应用日益普及。   一个...
EE直播间
更多
我要评论
1
6
关闭 站长推荐上一条 /3 下一条