ZIGBEE(CC2530,ZSTACK)串口波特率自适应

本文介绍了一种ZigBee模块CC2530实现自适应波特率的方法,通过检测连接的不同单片机(分别设置为38400bps和115200bps)来动态调整波特率,确保数据正确传输。

  在使用ZigBee进行数据透传的时候,我遇到了这样的情况:负责采集数据的两个单片机之间的波特率不相同,一个是38400,另一个是115200,但是负责传输数据的CC2530除了波特率之外,其它的代码都一样,所以使CC2530可以自适应波特率的话,那么只需要准备一份代码,一种ZCC2530模块,可以方便使用。
  处理的逻辑是这样的:38400波特率的单片机上电之后不停给CC2530发送数据“0x55”,CC2530上电默认波特率38400,如果收到“0x55”,则返回一个字符“#”,此单片机收到“#”后不再发送0x55,开始处理自己的业务。
  如果与CC2530加入网络后一定时间内(比如3s)没有收到“#”,则说明与之相连的不是38400波特率的单片机,则把自己的波特率改为115200。
CC2530的串口初始化:

static  halUARTCfg_t uartConfig;//将串口的配置结构体申请为全局的
  uartConfig.configured           = TRUE;              // 2x30 don't care - see uart driver.
  uartConfig.baudRate             = HAL_UART_BR_38400;
  uartConfig.flowControl          = FALSE;
  uartConfig.flowControlThreshold = SERIAL_APP_THRESH; // 2x30 don't care - see uart driver.
  uartConfig.rx.maxBufSize        = SERIAL_APP_RX_SZ;  // 2x30 don't care - see uart driver.
  uartConfig.tx.maxBufSize        = SERIAL_APP_TX_SZ;  // 2x30 don't care - see uart driver.
  uartConfig.idleTimeout          = SERIAL_APP_IDLE;   // 2x30 don't care - see uart driver.
  uartConfig.intEnable            = TRUE;              // 2x30 don't care - see uart driver.
  uartConfig.callBackFunc         = SerialApp_CallBack;
  HalUARTOpen (SERIAL_APP_PORT, &uartConfig);

串口接收数据的处理函数。使用bdrOKflag来标记是否已经确定波特率。

static void SerialApp_CallBack(uint8 port, uint8 event)
{
  (void)port;
  if ((event & (HAL_UART_RX_FULL | HAL_UART_RX_ABOUT_FULL | HAL_UART_RX_TIMEOUT)) &&
#if SERIAL_APP_LOOPBACK
      (SerialApp_TxLen < SERIAL_APP_TX_MAX))
#else
      !SerialApp_TxLen)
#endif
  {
    SerialApp_TxLen = HalUARTRead(SERIAL_APP_PORT, SerialApp_TxBuf, SERIAL_APP_TX_MAX); //将串口数据读入buf
    if(SerialApp_TxLen > 0)
    {
      if(bdrOKflag)//波特率的确定标志
      {
        HalLedBlink(HAL_LED_2,2,50,200);//转发消息  绿灯闪2下
         SerialApp_OTAData(&SerialApp_TxAddr,SERIALAPP_CLUSTERID1,SerialApp_TxBuf, SerialApp_TxLen);
      }
         if (0x55 == SerialApp_TxBuf[0])
      {
        HalLedBlink(HAL_LED_1,2,50,200);//红灯闪两下  说明是38400的波特率
          uint8 a = '#';
          HalUARTWrite(SERIAL_APP_PORT, &a, 1); //通过串口发送给网关         
          bdrOKflag = 1;
      }
    }
    SerialApp_TxLen = 0;
  }
}

  设置一个事件用于改变波特率。在ZDO_STATE_CHANGE,也就是设备加入网络的时候设置一个事件定时器,3s后执行。
  在3s后触发事件CHANGEBAUDRATE_EVT ,如果bdrOKflag 没被标记为1,则更换波特率。

UINT16 SerialApp_ProcessEvent( uint8 task_id, UINT16 events )
{
  (void)task_id;  // Intentionally unreferenced parameter

  if ( events & SYS_EVENT_MSG )
  {
    afIncomingMSGPacket_t *MSGpkt;

    while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SerialApp_TaskID )) )
    {
      switch ( MSGpkt->hdr.event )
      {         
。。。。。。。。
      case ZDO_STATE_CHANGE:
          SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
          if(SampleApp_NwkState == DEV_END_DEVICE) //判定当前设备类型
          {
            HalLedSet(HAL_LED_1,HAL_LED_MODE_ON);//红灯亮。绿灯闪烁5下
            HalLedBlink(HAL_LED_2,5,50,200);
            osal_start_timerEx(SerialApp_TaskID, CHANGEBAUDRATE_EVT, 3000);
          }
        break;
      default:
        break;
      }

      osal_msg_deallocate( (uint8 *)MSGpkt );
    }
。。。。。。。。。。
    return ( events ^ SYS_EVENT_MSG );
  }
。。。。。。。。。。。。。
    if ( events & CHANGEBAUDRATE_EVT ) //切换波特率的事件
  {
    if (bdrOKflag == 0)
    {
      uartConfig.baudRate             = HAL_UART_BR_115200;
      HalUARTOpen (SERIAL_APP_PORT, &uartConfig);
      bdrOKflag = 1;
      }
      return ( events ^ CHANGEBAUDRATE_EVT );
  }
。。。。。。。。。。。。。。。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值