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.

[参考译文] RTOS/CC2640:UART_Read 问题

Guru**** 2589245 points
Other Parts Discussed in Thread: CC2640

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/600435/rtos-cc2640-uart_read-issue

器件型号:CC2640

工具/软件:TI-RTOS

大家好、

我尝试在 NXP 微控制器和 UART 中基于 CC2640的 Sable-X 之间进行通信。

微控制器向 CC2640发送循环数据、但 Sable-X 似乎无法读取。

我已经使用示波器进行了一些测试、我看到数据很好地到达 Sable-x 的 Rx 引脚、但当我使 UART_Read 时、它返回0作为第一个数据包、然后返回环路-1。

结果是我无法执行 readCallback 函数。

我已经尝试过回波项目等示例项目、它可以正常工作、但当我尝试使 Sable-X 的 UART 与外部微控制器一起工作时、我没有任何东西。  

RX 引脚和 Tx 引脚分别为 IOID 1和 IOID 0、缓冲器的大小和数据匹配的封装、波特率良好。  

我不知道为什么它不起作用,这让我疯了!

下面是我的一些代码:  

void receiveUART(){
int ret;
ret = UART_read (hUart、UART_rxBuf、20);
printf ("UART read %d bytes\n"、ret));
}


UART_Params* UART_Init(){
UART_Params_init (&paramsUart);

paramsUart.writeDataMode = UART_DATA_BINARY;
paramsUart.readMode = UART_MODE_callback;
paramsUart.readCallback = readCallback;
paramsUart.readEcho = UART_ECHO_OFF;
paramsUart.readDataMode = UART_DATA_BINARY;
paramsUart.baudrate = 115200;
paramsUart.readReturnMode = UART_return_full;
hUart = UART_open (Board_UART、&paramsUart);
如果(!hUart){
printf ("UART 未打开");
}
printf ("UART open\n");
返回参数 Uart;
} 

提前感谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Lucas Poingt、

    使用 UART_Read 的方式不正确。 我会向您发送我的代码以供参考  

    void FIOT_UART_Serial_Rx_CB (UART_Handle iHandle、void * OData、size_t count)
    {
    //!*********
    //!将 UART_Rx_Buf 复制到 UART_Tx_Buf
    //!*********
    
    //!*********
    //!将任务唤醒以处理
    //!*********
    Semaphore_post (UART_hSem);
    }
    /*********
    *职能-任务
    /*
    !
    秘书长的报告
    *@fn void FIOT_UART_CreateTask (void)
    *
    *@协议的简短任务创建函数
    *
    @param None
    *
    @return None
    *
    ******** /
    void FIOT UART_CreateTask (void)
    {
    Task_Params TaskParams;
    //!*********
    //!配置任务
    //!*********
    Task_Params_init (&TaskParams);
    TaskParams.stack = UART_TaskStack;
    TaskParams.STACKSIZE = UART_TASK_STACK_SIZE;
    TaskParams.priority = UART_TASK_PRIORITY;
    
    Task_construction (&UART_TaskStructt、FIOT_UART_TaskFxn、 &TaskParams,NULL);
    }/*
    !
    秘书长的报告
    *@fn void FIOT_UART_InitTask (void)
    *
    *@简要利用 UART 层
    *
    *@param None
    *
    @return None
    *
    ******** /
    void FIOT_UART_InitTask (void)
    {
    //!*********
    //!初始化 UART
    //!*********
    UART_Params uParams;
    
    UART_PARAMS_INIT (uParams);
    
    uParams.writeDataMode = UART_DATA_binary;
    uParams.readDataMode = UART_DATA_binary;
    uParams.readReturnMode = UART_return_full;
    uParams.readMode = UART_MODE_CALLBACK;
    uParams.readCallback = FIOT_UART_Serial_Rx_CB;
    
    UART_uHandle = UART_OPEN (Board_UART、&uParams);
    //!*********
    //!利用信标
    //!*********
    Semaphore_Params sParams;
    Semaphore_Params_init (&sParams);
    sParams.mode = Semaphore_Mode_binary;
    
    Semaphore_construction (&UART_sSem、0、 sParams);
    UART_hSem = Semaphore_handle (&UART_sSem);
    }
    /*!
    秘书长的报告
    *@fn void FIOT_UART_TaskFxn (UARg a0、UARg A1)
    *
    @协议的简短应用任务入口点。
    *
    *@param a0、A1 -未使用。
    *
    *@无返回
    *
    ******** /
    void FIOT UART_TaskFxn (UARg a0、UARg A1)
    {
    //!*********
    //!初始化 UART 层
    //!*********
    FIOT_UART_InitTask ();
    //!*********
    //!UART 层的循环
    //!*********
    对于(;;)
    {
    //!*********
    //!refesh 以读取新数据
    //!*********
    UART_READ (UART_uHandle、&UART_Rx、1);
    
    Semaphore_pend (UART_hSem、BIOS_wait_forever);
    //!*********
    //!处理数据
    //!*********
    
    } 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Luu Vy、您好、 感谢您的回答。

    我不明白为什么我使用 UART_READ 的方式是错误的。

    我看到您使用信标、但我在项目中不需要它、因为函数 receiveUART()(调用了 UART_READ 函数)是由中断触发的(很抱歉、我忘记了这个细节)。 此中断由 NXP 微控制器在发送数据时触发。 这个中断被很好地触发、但我的读取缓冲区中没有任何内容。

    如果我像这样进行读取取消:

    void receiveUART(){
    int ret;
    ret = UART_read (hUart、UART_rxBuf、20);
    printf ("UART read %d bytes\n"、ret);
    UART_readCancel (hUart);
    } 

    然后我进入我的 readCallback 函数、但它不执行任何操作、因为它没有要处理的数据。

    也许您还有其他建议吗?

    此致、

    卢卡斯·普灵特

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Lucas Poingt
    当您调用 UART_READ (hUart、UART_rxBuf、20)时、cc2640将准备一个缓冲区来自动读取 UART 上的20个字节、并且它仅在 cc2640收到20个字节后执行 UART 的回调处理程序。 转至回调处理程序后、接收到的数据存储在 UART_rxBuf 中、您需要再次调用 UART_Read 以接收下一个数据。
    这意味着您必须在读取 UART 上的数据之前调用 UART_READ。
    在我的代码中、我生成一个任务来读取 UART 上的数据。 我调用 UART_READ 来读取一个字节、然后该任务进入睡眠状态。 当调用 UART 回调时、我将唤醒此任务以处理接收到的数据、并再次调用 UART_READ 以读取下一个字节。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Luu Vy、您好、感谢您抽出宝贵的时间、

    好的,所以我做了如下回调函数:

    void readCallback (UART_Handle handle、void *rxBuf、size_t size){
    //*
    处理数据
    */
    int ret;
    ret = UART_read (hUart、UART_rxBuf、20);
    printf ("UART read %d bytes\n"、ret);
    } 

    我得到了该输出:

    [Cortex_M3_0] UART 读取0个字节
    UART 读取0个字节
    UART 读取-1个字节
    UART 读取0个字节
    UART 读取-1个字节
    UART 读取0个字节
    UART 读取-1个字节
    UART 读取0个字节
    UART 读取-1个字节
    UART 读取0个字节
    UART 读取-1个字节
    UART 读取0个字节

    实际上、我进入回调函数、但由于中断、我的 receiveUART 函数被调用。 我不知道为什么我得到 "-1"、我认为这是因为读取错误。

    此致、

    卢卡斯·普灵特

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Lucas Poingt、

    接收到的数据存储在 UART_rxBuf 中。  只需处理红色 UART_rxBuf

    void readCallback (UART_Handle handle、void *rxBuf、size_t size){
    /*
    *处理收到的数据
    *
    printf ("UART 读取%d 字节\n"、大小);
    //读取接收到的数据 UART_rxBuf
    for (uint8_t i = 0;i "the="" rx="" uart[%d]="%d" bytes\n",i,="" uart_rxbuf[i]);="" *="" prepare="" buffer="" to="" read="" the="" next="" 20="" bytes="" uart_read(huart,="" uart_rxbuf,="" 20);="" }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Luu Vy:

    我已经尝试了你给我的内容、但鉴于第一个读取返回0、"size"参数等于0、它不会生成第二个"printf"。

    另一个问题:当您说“准备缓冲区以读取接下来的20个字节”时,这是否意味着我需要将其设为空?

    此致、
    卢卡斯·普灵特
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Lucas Poingt、

    uint8_t UART_Rx[20]={0};
    void FIOT_UART_Serial_Rx_CB (UART_Handle iHandle、void * OData、size_t count)
    {
    //!*********
    //! 处理 RX 数据
    //!*********
    //!接收到的数据长度为20字节,因为调用了回调。
    //!接收到的数据存储在 UART_Rx 中。 只能读取 UART_Rx 缓冲区中的值进行处理
    for (uint8_t i = 0;i<20;i++)
    printf ("Rx UART[%d]=%d 字节\n"、20、UART_Rx[i]);
    //!*********
    //! 准备缓冲器以读取接下来的20个字节
    //! 旧接收到的数据被清除
    //!*********
    UART_READ (UART_uHandle、&UART_Rx、20);
    }
    void FIOT_UART_InitTask (void)
    {
    //!*********
    //!初始化 UART
    //!*********
    UART_Params uParams;
    
    UART_PARAMS_INIT (uParams);
    
    uParams.writeDataMode = UART_DATA_binary;
    uParams.readDataMode = UART_DATA_binary;
    uParams.readReturnMode = UART_return_full;
    uParams.readMode = UART_MODE_CALLBACK;
    uParams.readCallback = FIOT_UART_Serial_Rx_CB;
    
    UART_uHandle = UART_OPEN (Board_UART、&uParams);
    //!准备缓冲器以读取20个字节
    //!FIOT_UART_Serial_CB_Only 在器件接收到20字节
    UART_Read (UART_Rx)时被调用;
    } 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Luu Vy、您好、感谢您的回答。

    我说过、接收数据的长度等于0。 之所以调用我的回调、只是因为我在接收 UART 函数的末尾放置了"UART_readCancel (hUart);"。 我的问题就是 UART_READ 始终返回0 (如果我让 readCancel 返回-1)。

    当您写入"旧接收数据被清除"时、这是否意味着我需要清除它、或者它是自动生成的?

    此致、
    卢卡斯·普灵特
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Lucas Poingt、

    缓冲区中的数据不会清零。 数据保留旧值。 但是、UART 接收到的新数据将存储在 UART 接收到的旧数据中。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Luu Vy:

    好的、因此读取缓冲区中的数据将被覆盖。 但我仍然不知道为什么 UART_Read 始终返回0或-1。 这一问题让我很烦,因为我在这里住了几天...

    此致、
    卢卡斯·普灵特
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Lucas Poingt、
    您使用 UART_Callback。 您不需要返回 UART_READ、因为我们目前没有任何新数据。 返回 UART_ERROR 的原因有很多。 我取决于您的代码。

    "例如、如果一个线程调用 UART_READ (uart0、buffer0...)、则任何其他线程尝试 UART_READ (uart0、buffer1...) 将导致 UART_ERROR 错误,直到第一个 UART_READ()中的所有数据都已传输到 buffer0。 这适用于 UART_MODE_CALLACK 和 UART_MODE_BLOCKING 模式。 因此、应用必须同步使用相同 UART 句柄的 UART_READ()(或 UART_WRITE())调用、或检查 UART_ERROR 返回代码以指示传输仍在进行中。"

    您可以在 UART.h 中查看更多详细信息

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Luu Vy:

    谢谢您、我认为我离问题的根源不远、但它仍然不起作用。

    我尝试了如下操作:

    void receiveUART(){
    int ret;
    UART_read (hUart、UART_rxBuf、20);
    }
    
    void readCallbackTest (UART_Handle handle、void * rxBuf、size_t size){
    printf ("UART read %d bytes\n"、size);
    uint8_t i;
    //读取接收到的数据(UART_rxBuf
    = 0) "the="" rx="" uart[%d]="%d" bytes\n",i,="" uart_rxbuf[i]);="" *="" prepare="" buffer="" to="" read="" the="" next="" 20="" bytes="" uart_read(huart,="" uart_rxbuf,="" 20);="" }
    

    它似乎再也不会进入回调函数、这肯定是因为 UART_READ 函数不会读取任何内容...

    此代码是在 Rx 引脚上从 NXP 微控制器向 Sable-X 模块发送数据的代码:

    while (1){
    unsigned char Data[20];
    Data[0]=ID_serial;// Id_serial 是数据包的 ID,它将在处理数据
    (int i=1;i<20;i++)
    {
    Data[i]='a'时很有用; //只是一个示例
    }
    
    LEDn_PutVal (1);//中断引脚(使 Sable-X 能够知道传入的数据),该引脚触发 Sable-X
    vTaskDelay ((((TickType_t) 1)的接收 UART 功能;//让一些时间到 Sable-X 来查看上升沿
    StringUART (Easy
    )(SendType)(简单);//简单发送数据(20);//简单数据(简单)
    LEDn_PutVal (0);
    vTaskDelay (( TickType_t ) 1000);//在第二次传输(
    int i=1;i<20;i++)
    {
    Data[i]='B';//另一个具有相同 ID_serial 的示例(只是为了在两个示例之间做出不同)
    }
    
    LETaskType (t1
    )
    ;tendt1
    
    
    (t1);tvtaskType (t1
    

    也许这有助于找到问题、但对于我进行的所有测试、我确信发送数据正常。

    此致、

    卢卡斯·普灵特

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Lucas Poingt

    您在哪里调用 receiveUART? 是否确定正确设置 UART 引脚? 我需要您的代码的更多详细信息。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Luu Vy:

    我在 uartRX_Interrupt 中调用 receiveUART 函数。 当 NXP 微控制器在中断引脚(称为 LEDn)上放置"1"时、会触发此中断。 我在 IOID_1上设置 UART_Rx 引脚、在 IOID_0上设置 UART_Tx 引脚(我已从 Sable-X 模块数据表中获取它们)

    以下是 Rx 和 Tx 的引脚配置:

    Board_UART_RX | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_DIS | PIN_IRQ_NEGEDGE | PIN_DRVSTR_MAX、 /* DevPack */
    Board_UART_TX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_NOPULL| PIN_DRVSTR_MAX、 /* DevPack */ 

    此致、

    卢卡斯·普灵特

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Lucas Poingt、

    您是否使用定制 PCB 或 TI 开发套件?
    如果使用 Launchpad、则可以尝试移除 TXD 和 RXD 上的跳线。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Luu Vy:
    我使用定制 PCB、在 NXP 微控制器的 Rx/Tx 和 Tx/Rx 与 Sable-X 模块之间建立直接链接。 我的板上没有任何跳线。

    此致、
    卢卡斯·普灵特
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Lucas Poingt、

    您的项目是基于 simple_peripheral 示例开发的吗?
    您可以尝试执行的操作

    • 1/打开 simple_peripheral 项目
    • 2编辑 RX 和 TX 引脚
    • 3在  SimpleBLEPeripheral_init 中调用 UART_Init()
    • 4/   在 SimpleBLEPeripheral_init 中的 UART_Init()之后调用 receiveUART()
    • 5重建并将堆栈和应用程序下载到器件。 并在 Callback 函数中添加断点。
    • 6使用 NXP 微控制器向设备发送20个字节