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.

CC2650 simpleBLEPeripheral工程下添加串口处理(非NPI),写好串口初始化以及接收回调,但无法进入接收回调处理函数。

Other Parts Discussed in Thread: CC2650, CC2640, SYSBIOS

UART_Params_init(&params);
     params.baudRate      = 9600;
     params.writeDataMode = UART_DATA_BINARY;
     params.readMode      = UART_MODE_CALLBACK;     
     params.readDataMode  = UART_DATA_BINARY;
     params.readCallback  = readCallback;
      // Open the UART and initiate the first read
     handle = UART_open(Board_UART, &params);

static void readCallback(UART_Handle handle, void *rxBuf, size_t size)
 {
   UART_write(handle, "Uart is receiving", 20);
     // Copy bytes from RX buffer to TX buffer   
   for(size_t i = 0; i < size; i++)   
       txBuf[i] = ((uint8_t*)rxBuf)[i];
     // Echo the bytes received back to transmitter
     UART_write(handle, txBuf, size);

     // Start another read, with size the same as it was during first call to
     // UART_read()
     UART_read(handle, rxBuf, wantedRxBytes);
  } 

代码如上,请问该如何修改?  请TI的工程师帮忙介绍下串口添加的说明。pdf里面只是简单描述了开启串口的步骤。

  • JinWei,

    不清楚你具体的需求是什么,但是你应该可以参考一下下面的文档,这个对你了解UART的驱动结构会有帮助:

    file:///C:/TI/tirtos_simplelink_2_11_01_09/docs/doxygen/html/_u_a_r_t_8h.html

    这是在你的TIRTOS的安装目录下面,你装过SDK的话应该自动安装好了。

  • Hi Yan,

    我的需求如下:

    1.如我代码中所示,在simpleBLEPeripheral.c中添加完#include <ti/drivers/UART.h> //For UART application之后开启串口,并将串口Read设置为callback的模式。

    在我的帖子中我的串口回调函数也有贴出。  在编译下载完代码之后,调用串口write打印一段字符是没有问题的,而向CC2650发送一串数据时候,串口并没有进入串口回调。所以,我就是想知道串口回调那块配置是否正确。或者使用回调模式是否需要注意其他的事项。

    2.关于你在回复中提到的那个串口使用说明 我已经看过,但是将说明中的回调Read代码移植到协议栈中时我不知道该如何操作,还需要在main.c里面创建任务吗 ?

  • 你好!

    我也在移植UART串口,请看附件,测试结果UART的功能都是可以的,就是不能进入睡眠,

    测试发现是因为在NPI_InitInterface()函数中调用了该NPI_uartRead();函数,屏蔽NPI_uartRead功耗正常但是读功能没有了,请问怎么解决,

    你们有没有功耗正常的UART例程,谢谢!

  • 后续结果怎么样?

  • Hi Habin,

    如果不调用UART_read函数功耗是正常的,因为UART_read会使UART口一直处在读的状态,所以不进入休眠是正常的

    你可以要么在有UART口数据需要读取的时候再打开UART_read,或者使用SCS里面的串口通讯

  • Hi  WBJ

    串口问题算解决了一半,利用2.0的SDK功耗可以下来了,参照HostTest这个工程改的,但是透传速率才1.2KB/S。

    1:我现在想弄ANCS,可是按照2540的配置方法在2640上面是失败的:。

    2:还有就是AD转换有没有例程,可以参考,现在无从下手。

    谢谢!

  • 我的代码的透传速率也是1.2KB 这个已经很快了 等MTU有了之后还可以考虑再往上走走

    另外您说的ANCS和AD我暂时还没有调过,所以请大牛来回答

  • 你们不就是大牛吗,

    听说你们月底会有新版本发布,现在才9号啊,很多东西都无从下手,现在对2640有点迷茫啊。

  • 新版本应该是会更稳定一些然后有些像您这样钻研的比较深的客户会关心的特征

    我现在在看SCS的一些东西 有时间就看看您说的ANCS和AD的问题

    新东西大家都是从头开始看 所以也别迷茫啦

  • 好的,谢谢!

    有问题在继续请教你们。

  • habin,

    你用的是SmartRF06还是SensorTag?

  • sum

    我使用的是SmartRF06,你呢,422943620我QQ,我们可以讨论下,

  • 我也使用回调函数,一开始也不会进回调函数,后来发现是要在初始化函数中,加上以下代码:

    wantedRxBytes = 1;

    int rxBytes = UART_read(handle, rxBuf, wantedRxBytes);

    wantedRxBytes的值可以设置为其他值,当rxBuf收到了wantedRxBytes个字节数据后才会进入回调函数。

    然后数据的读取就可以了,但是我这里出现了数据读取不稳定的问题,我从串口调试助手往CC2640发数据,一次发八九个字节,如果发太快,程序就跑死了,一个字节一个字节会好一点,不会死那么快,如果一次发很多字节,发送频率又比较快那么程序没过多久就跑死了。

    如上图,数据接收了479个字节后就收不到了,程序已经跑死了。请问这是为什么??我尝试过修改波特率,问题依然存在。

  • hai WBJ,

    我用的sdk版本为2.01,开发环境为CCS6.1 ,我想在SimlieBLEPeripheral.c中添加串口透传功能,我该如何操作呢?

    用没有在sdk2.01移植串口透传功能的案例呢?

  • hi,猜猜我是谁

    请问你这个问题问题解决了么?我用了你的程序,的确出现了你说的问题。

  • 解决了,我发的那个程序写法不对,串口收到数据后不能直接在回调里面发数据,因为回调函数是在中断处理函数中被调用的,收数据是在中断中收,发数据又在中断中发会出问题,导致程序蹦了,所以我后来改为收了数据后给任务发一个消息,或者给任务设置一个事件标志,然后在任务中处理数据,我的例子中的处理数据就是将收到的数据再发送出去,所以后来改为在任务中发串口数据后就没出过问题了,实际运行很稳定,速度也很快!

  • 你好,可以把改过的程序发我看看么?(我的邮箱:xiuhaoy007@163.com)

    我刚接触这一块,对任务调度什么的并不熟悉,感谢!

  • 不好意思,因为几个月前写的,然后因为后来一次把协议栈卸载,程序就被删掉了,没有保存下来,但是我只记得实现的方式,已经告诉你了,你可以自己尝试下。

  • hi,yuan yuan2

    你的串口好了吗?

    今天忽然发现之前的代码居然还在。。。贴出来,分别是.h文件和.c文件

    ====================== 优雅的分隔线 =================================

    #ifndef UART_TASK_H
    #define UART_TASK_H

    #ifdef __cplusplus
    extern "C"
    {
    #endif

    /*********************************************************************
     * FUNCTIONS
     */

    /*
     * Task creation function for the UART.
     */
    extern void Uart_createTask(void);
    extern void uart_SendData(uint8_t *txBuf, size_t size);

    /*********************************************************************
    *********************************************************************/

    #ifdef __cplusplus
    }
    #endif

    #endif /* UART_TASK_H */

    ============================== 优雅的分割线 =====================================

    /*******************************************************************************
      Filename:       uart_task.c
      Revised:       
      Revision:      

      Description:   

    *******************************************************************************/

    /*********************************************************************
     * INCLUDES
     */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/knl/Queue.h>

    #include <ICall.h>

    #include <ti/drivers/UART.h>
    #include <ti/drivers/uart/UARTCC26XX.h>

    #include "Board.h"

    #include "util.h"

    #include "uart_task.h"

    /*********************************************************************
     * CONSTANTS
     */
    // Task configuration
    #define UART_TASK_PRIORITY      1

    #ifndef UART_TASK_STACK_SIZE
    #define UART_TASK_STACK_SIZE     644
    #endif

    #define UART_READ_EVT        0x0001

    #define MAX_NUM_RX_BYTES      100   // Maximum RX bytes to receive in one go
    #define MAX_NUM_TX_BYTES      100   // Maximum TX bytes to send in one go

    /*********************************************************************
     * LOCAL VARIABLES
     */

    // Entity ID globally used to check for source and/or destination of messages
    // 线程注册到ICALL时分配的ID
    static ICall_EntityID selfEntity;

    // Semaphore globally used to post events to the application thread
    // 信号量,app线程没有事情处理时是阻塞状态,发信号量给app线程唤醒线程
    static ICall_Semaphore sem;

    // events flag for internal application events.
    // app事件标志变量
    static uint16_t events;

    // Task configuration
    Task_Struct uartTask;
    Char uartTaskStack[UART_TASK_STACK_SIZE];

    static UART_Handle  handle;
    static uint8_t   rxBuf[MAX_NUM_RX_BYTES];  // Receive buffer
    static uint8_t   txBuf[MAX_NUM_TX_BYTES];  // Transmit buffer
    static uint8_t   size_g;

    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static void readCallback(UART_Handle handle, void *rxBuf, size_t size);
    static void Uart_taskFxn(UArg a0, UArg a1);
    static void Uart_init(void);

    /*********************************************************************
     * @fn      SimpleBLEPeripheral_createTask
     *
     * @brief   Task creation function for the Simple BLE Peripheral.
     *
     * @param   None.
     *
     * @return  None.
     */
    void Uart_createTask(void)
    {
      Task_Params taskParams;

      // Configure task
      Task_Params_init(&taskParams);
      taskParams.stack = uartTaskStack;
      taskParams.stackSize = UART_TASK_STACK_SIZE;
      taskParams.priority = UART_TASK_PRIORITY;

      Task_construct(&uartTask, Uart_taskFxn, &taskParams, NULL);
    }

    /*********************************************************************
     * @fn      Uart_init
     *
     * @brief  
     *
     * @param   None.
     *
     * @return  None.
     */
    static void Uart_init(void)
    {
     // ******************************************************************
     // N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp
     // ******************************************************************
     // Register the current thread as an ICall dispatcher application
     // so that the application can send and receive messages.
     // 将线程注册到ICALL,注册了才能收发消息
     ICall_registerApp(&selfEntity, &sem);

     // Hard code the BD Address till CC2650 board gets its own IEEE address
     // uint8 bdAddress[B_ADDR_LEN] = { 0xF0, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA };
     // HCI_EXT_SetBDADDRCmd(bdAddress);

     // Set device's Sleep Clock Accuracy
     //HCI_EXT_SetSCACmd(40);

     // Create an RTOS queue for message from profile to be sent to app.
     // 创建消息队列
    // appMsgQueue = Util_constructQueue(&appMsg);
     
     UART_Params      params;

     // Init UART and specify non-default parameters
     UART_Params_init(&params);
     params.baudRate      = 115200;
     params.writeDataMode = UART_DATA_BINARY;
     params.readMode      = UART_MODE_CALLBACK;
     params.readDataMode  = UART_DATA_BINARY;
     params.readCallback  = readCallback;

     // Open the UART and do the read
     handle = UART_open(Board_UART, &params);
     // Enable RETURN_PARTIAL
     UART_control(handle, UARTCC26XX_RETURN_PARTIAL_ENABLE, NULL);
     // UART_read()
     UART_read(handle, rxBuf, 100);
    }

    /*********************************************************************
     * @fn      Uart_taskFxn
     *
     * @brief  
     *
     * @param   a0, a1 - not used.
     *
     * @return  None.
     */
    static void Uart_taskFxn(UArg a0, UArg a1)
    {
      // Initialize application
      Uart_init();
     
      // Application main loop
      for (;;)
      {
        // Waits for a signal to the semaphore associated with the calling thread.
        // Note that the semaphore associated with a thread is signaled when a
        // message is queued to the message receive queue of the thread or when
        // ICall_signal() function is called onto the semaphore.
        // 等待信号量,若没收到信号量则线程阻塞,不会执行后续的代码
        ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

        if (errno == ICALL_ERRNO_SUCCESS)   // 收到信号量
        {
      
        }
     
     if (events & UART_READ_EVT)
     {
      events &= ~UART_READ_EVT;   //clear event
      
      // Echo the bytes received back to transmitter
      UART_write(handle, txBuf, size_g);
     }
      }
    }

    static void readCallback(UART_Handle handle, void *rxBuf, size_t size)
    {
     // set event
     events |= UART_READ_EVT;
     
     // Copy bytes from RX buffer to TX buffer
     for(size_t i = 0; i < size; i++)
      txBuf[i] = ((uint8_t*)rxBuf)[i];
     
     size_g = size;
     
     // Wake up the application.
     Semaphore_post(sem);
     
     // Start another read, with size the same as it was during first call to
     // UART_read()
     UART_read(handle, rxBuf, 100);
    }

    /*********************************************************************
     * @fn      uart_SendData
     *
     * @brief   串口发数据函数
     *
     * @param   None.
     *
     * @return  None.
     */
    void uart_SendData(uint8_t *txBuf, size_t size)
    {
     UART_write(handle, txBuf, size);
    }

    ================================ 结束 ======================================

     

  • 嗯嗯,非常感谢您的热心回答,我用了官方的 tl.c ,把串口跑起来了,你的代码写得不错!

    我现在想做一个串口透传的功能,就是串口发送数据给模块,然后模块通过无线把数据传到手机APP,不知您之前有没做过这方面的功能呢?

     

  • 我现在做的这是这个,遇到一些问题,求带

  • 你好 ,我现在也在调串口,有几个问题想请教你一下,能加一下qq么?我qq是

  • 你好,能提供一个power_saving使能情况下,使用uart的例子吗?

  • 您好,我使用了您给的程序。我已经成功添加到工程中。

    在main函数中调用Uart_createTask()后,程序就跑步起来;屏蔽Uart_createTask();后,程序才能正常正常工作。

    我也使用SimpleBLEPeripheral例程, 硬件:CC2640_4X4。

    我怀疑会不会是堆栈空间不够了?或者我还缺少一些配置?

  • 你好 ,我想和你做一样的事情 你现在完成了吗?我还不知道怎么开始呢~~求指教

  • 您好,我也在SimpleBLEPeripheral例程中添加Uart_createTask(),同样出现你说的这个问题,你现在解决了吗?

  • 您好,在main函数里调用Uart_createTask,程序就不能够正常运行了

    使用的工程 是SimpleBLEPeripheral,是否需要设置其他参数

  • 你好,可以加个QQ学习下吗?

    494890907

  • 你好!我遇到类似的问题,就是ICall_wait的问题,不太确定是硬件问题还是软件问题,可不可以加QQ细聊。

    QQ、微信:904887853

  • Dendi,

    嗨咯,你的串口透传做好了吗?用ti官方的串口程序,却跑不起来~~用的板子是launchPad,这个程序应该可以直接下载到板子上的吧 ?

    http://dev.ti.com/tirex/#/DevTool/CC2650-LAUNCHXL?link=TI-RTOS%20for%20CC13XX%20and%20CC26XX%2FDevelopment%20Tools%2FCC2650-LAUNCHXL%2FDriver%20Examples%2FUART%20Examples%2FUART%20Echo%2Fuartecho.c

    能帮我看看吗?谢谢了·

  • 你好!

          我写了一个和你的程序差不多的串口输入回调函数,但不知道怎么搞的进去一次后就死了,你能帮我看看吗?



    void simple_uart_init()
    {
    UART_Params_init(&params);

    params.readMode = UART_MODE_CALLBACK;
    params.writeMode = UART_MODE_BLOCKING;
    params.readTimeout = UART_WAIT_FOREVER;
    params.writeTimeout = UART_WAIT_FOREVER;
    params.readCallback = readCallback;
    params.writeCallback = NULL;
    params.readReturnMode = UART_RETURN_NEWLINE;
    params.readDataMode = UART_DATA_TEXT;
    params.writeDataMode = UART_DATA_TEXT;
    params.readEcho = UART_ECHO_ON;
    params.baudRate = 115200;
    params.dataLength=UART_LEN_8;/*!< Data length is 8 bits */
    params.stopBits=UART_STOP_ONE ;/*!< One stop bit */
    params.parityType=UART_PAR_NONE;

    handle = UART_open(Board_UART, &params);
    UART_control(handle, UARTCC26XX_RETURN_PARTIAL_ENABLE, NULL);
    UART_read(handle, rxBuffe, 20);
    if (!handle) {
    System_printf("UART did not open");
    }

    }
    void simple_write(uint16_t hello[],uint16_t u)
    {

    UART_write(handle, hello, u);

    }
    void simple_read()
    {

    UART_read(handle, rxBuffe, length);
    }

    void readCallback(handle,rxBuffe, length)
    {
    //simple_write("\nUART started\n",13);
    //simple_read();
    //simple_write(rxBuffe,length);
    // Enqueue the event.
    SimpleBLECentral_enqueueMsg(SBC_UARTCMD_EVT, 0,0);

    }
    void SimpleBLECentral_processuartcmd()
    {
    Simple_Set_Led(Board_SIMPLE_LED_RED,LED_ON );
    simple_write("\nUART started\n",13);
    simple_read();
    simple_write(rxBuffe,length);
    }

  • 后来有没有改好,我这边也碰到了同样的问题,仅能进去一次,后面就进不去了。

  • 发现问题了,再每次接收完数据后,要重新再读一下,清空一下数据。