This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2540 串口收发乱码

Other Parts Discussed in Thread: CC2540, CC2541

TI 1.3 的实例包,

使用 SimpleBLEPeripheral 增加串口功能!如果不广播,则收发没有错误,

开始广播后,一段时间就有几率出现乱码~!


unsigned char uart_Buf[150];
unsigned char g_getUartLen;
static void RxCB(uint8 port , uint8 event)
{
  g_getUartLen = HalUARTRead(HAL_UART_PORT_0,uart_Buf,100);
  if(g_getUartLen)
  {
    SerialEventStruct *pMsgSerial;
    pMsgSerial = (SerialEventStruct *)osal_msg_allocate( sizeof(SerialEventStruct)) ;
    pMsgSerial->hdr.event = SERIAL_MSG;
    pMsgSerial->msg = (uint8 *)osal_msg_allocate( sizeof(g_getUartLen)) ;
    osal_memcpy(pMsgSerial->msg,uart_Buf,g_getUartLen);
    pMsgSerial->len = g_getUartLen ;
    osal_msg_send( simpleBLEPeripheral_TaskID, (uint8 *)pMsgSerial);
  }
}


void UartInit(void)
{
  halUARTCfg_t uartCfg;
  uartCfg.configured = TRUE;
  uartCfg.baudRate = HAL_UART_BR_115200;
  uartCfg.flowControl = FALSE;
  uartCfg.callBackFunc = RxCB ;
  uartCfg.flowControlThreshold = MT_UART_THRESHOLD;
  uartCfg.rx.maxBufSize = MT_UART_RX_BUFF_MAX;
  uartCfg.tx.maxBufSize = MT_UART_TX_BUFF_MAX;
  uartCfg.idleTimeout = MT_UART_IDLE_TIMEOUT;
  uartCfg.intEnable = TRUE; 
  HalUARTOpen(HAL_UART_PORT_0,&uartCfg);
}

 

static void simpleBLEPeripheral_ProcessOSALMsg( osal_event_hdr_t *pMsg )
{
  switch ( pMsg->event )
  {
  #if defined( CC2540_MINIDK )
    case KEY_CHANGE:
      simpleBLEPeripheral_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys );
      break;
    case SERIAL_MSG:
       HalUARTWrite(0,((SerialEventStruct *)pMsg)->msg,((SerialEventStruct *)pMsg)->len);
       osal_msg_deallocate (((SerialEventStruct *)pMsg)->msg);
      break;
  #endif // #if defined( CC2540_MINIDK )

  default:
    // do nothing
    break;
  }
}

 

  • payen,

    有没有试过在preprocessing 里面把POWER_SAVING关闭?

  • 是的,我在设置里面把

    POWER_SAVING 改成了 xPOWER_SAVING 啦!

  • HCI_EXT_ClkDivOnHaltCmd( HCI_EXT_ENABLE_CLK_DIVIDE_ON_HALT );

    屏蔽, 乱码问题解决,

    但是有一个新问题,

    在 串口的 CALLBACK 函数里面再把接收的数据发送出来,

    结果发现有时候会丢数据,

    115200 波特率 57600  、 9600 波特率都测试了

    都有这个现象~!

  • payen,

    没错,那条HCI命令会在MCU空闲的时候降低主频来降低功耗,但是会影响到DMA控制器搬数据。

    发现你还在用1.3的协议栈,请更新到1.4吧,1.4的UART驱动完全更新过,解决了很多问题。

  • 你好,我现在使用的就是1.4的协议栈,但CC2541在接受串口数据时出现乱码,具体如下:

           1. 非广播/连接情况下,CC2541 uart 接受不会出错。

          2. 在广播或连接模式下,CC2541 uart 数据接受 偶尔出错,在回调函数中调用 NPI_RxBufLen(),得到数据长度为128!!!!

         是不是广播模式下,蓝牙的协议层的数据通信用到了 Uart 使用的DMA? 

  • hi  payen deng:

    我现在遇到和你一样的问题,  2540源码工程用的是simpleBLEPeripheral

    我的POWER_SAVING打开着, HCI_EXT_CLKDivOnHaltCmd也关闭着, 但还是会有数据丢失的问题, UART0配的是DMA模式。

    请问你后来是怎么解决的? 谢谢!

  • 非低功耗下的串口乱码问题,解决方法如下:

    1)在SimpleBLEPeripheral的应用层初始化中注释掉:
    HCI_EXT_ClkDivOnHaltCmd( HCI_EXT_ENABLE_CLK_DIVIDE_ON_HALT );
    PS:这条语句会让空闲的CPU自动进入低频以此降低功耗,注释掉代表不自动切换频率。


    2)在SimpleBLEPeripheral的应用层初始化中添加:
    HCI_EXT_HaltDuringRfCmd(HCI_EXT_HALT_DURING_RF_DISABLE);
    PS:默认是ENABLE的,ENABLE会让RF期间停止MCU。因此需要添加本条语句,关闭它。


    详情见我个性签名档的博客地址,《CC2541之串口收发》

  • 甜甜的大香瓜,

    你的这个信息对我帮助很大。按照这个上面改了一下程序,UART舒畅了很多。

    以前我们的产品(指纹蓝牙锁)在用华为手机运行我们的APP时,指纹录入总是失败,而别的手机(譬如小米,魅族等)操作倒很少出错,奇怪吧?

    最后没办法了只得一步一步跟进蓝牙程序里面去,发现蓝牙连接时华为手机对UART造成了干扰,CC2541与指纹模块间的UART通讯总是掉数据--只针对华为手机哦。郁闷,搞了几天,无果!

    在程序里面添加你上面说的两条指令,UART很舒畅了!!!

    不骄傲,反复再试试。

    感谢先! 好人!

  • 谢谢瓜哥,我解决了SPI通信丢包问题。