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.

[参考译文] LAUNCHXL-CC2640R2:UART 回调不起作用?

Guru**** 2582405 points
Other Parts Discussed in Thread: CC2640R2F

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/594625/launchxl-cc2640r2-uart-callback-does-not-work

器件型号:LAUNCHXL-CC2640R2
主题中讨论的其他器件:CC2640R2F

您好!

  实现的 UART 回调 UART 回显示例程序、但不起作用。 我使用下面这个帖子中的 svendbt 代码片段。

这是我修改过的 UART 回波示例程序。 它打印"回显字符:"、以便 UART 工作。 我在 uartRxCb()中放置一个断点,但当我按下一个键时,它不会转到 uartRxCb()。 为什么是这样? 您是否有用于 CC2640R2F Launchpad 的演示 UART 回调的 UART 示例程序?

/*
=== uartecho.c ====
*/
#include 
#include 

/*驱动程序头文件*/
#include 
#include 

#include "string.h"

//示例/板头文件*/
#include "Board.h"

#define BUFTYPE char
#define PBUFTYPE char*
#define BUFSIZE 1

UART_Handle UART;

BUFTYPE rxBuf[BUFSIZE]
;


static BUFYPE rxBuf[BUFTXBUFSIZE];static tryf
(txUFb
)、void txBuf (bt)、txBuf (void)、txBuf (txBuf)、txBuf (txBuf);static txf (void (txf)
count);
UART_write (UART、txBuf、sizeof (txBuf)/sizeof (BUFTYPE));
}

/*
==== mainThread ====
//
void * mainThread (void * arg0)
{
const char echoPrompt[]="回显字符:\r\n";
UART_Params uartParams;

/*调用驱动程序初始化函数*/
GPIO_init();
UART_INIT();

/*打开用户 LED */
GPIO_WRITE (Board_GPIO_LED0、1);

/*创建一个数据处理关闭的 UART。 *
UART_PARAMS_INIT (uartParams);

uartParams.readMode = UART_MODE_CALLACK;
uartParams.writeMode = UART_MODE_BLOCKING;
uartParams.readCallback = uartRxCb;
uartParams.readEcho = UART_ECHO_OFF;
uartParams.baudrate = 115200;

UART = UART_OPEN (Board_UART0、uartParams);

if (UART == NULL){
/* UART_open()失败*/
while (1);
}

UART_WRITE (UART、echoPrompt、sizeof (echoPrompt));

/*循环永久回显*/
while (1){
UART_READ (UART、&rxBuf、sizeof (rxBuf)/sizeof (BUFTYPE));

}
}

-克尔

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

    Markel、您好、我不明白为什么要使用您的代码并按键、它应该会转到 uartRxCb。 您能否详细说明按键时代码中会发生什么情况?

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

    下面是我的观察结果。

    1.如果按一次键,然后等待30秒以上,则不会转至 uartRxCb。
    2.如果我反复按键超过10倍,它将进入 uartRxCb。

    为什么需要反复按键才能使程序转至 uartRxCb?

    -克尔
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在您的代码中、我看不到任何与按钮按下相关的代码。 我看不到关于按钮按压和 uartRxCb 的任何关系。 顺便说一下、您在测试时是否启用了节能功能?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Yikai、

    在打开 Tera Term 的情况下,按笔记本电脑键盘上的键。 在 CCS 中没有省电的预定义符号集。 我正在使用 UART_echo 示例程序、然后根据 svendbt 代码对其进行修改。

    -克尔
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Markel Robregado:
    您是否使用密钥来模拟 UART 上的数据?
    BUFSIZE 为1、在 UART 接收到1个字节(= 8时钟)后调用回调。 这意味着您需要在短时间内按8次以模拟1个字节。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Luu Vy:

      您是正确的,在按8次键后,程序将进入 uartRxCb()。 但是、我需要仅在按1次键后将其设置为回调触发器。 建议的初始化是什么? 我正在执行此测试、以便可以在产品开发中应用它。

      我需要解析 BUZZZER、LED0和 LED1等字符串。

    这是用于产品开发的 UART 回调。

    void UartApp__UartRxCB (UART_Handle handle、void * buf、size_t count)
    {
    
    字 I;
    
    对于(i = 0;i < count;i++)
    {
    TestApp_DecodeData (*(((((字节*) buf)+I)));
    }
    
    返回;
    } 
    void TestApp_DecodeData (字节 Rx_data)
    {
    /*从缓冲区读取字节*/
    开关(Rx_DATA)
    {
    /*检查终止字符*/
    案例'\r':/*'\r' 0x0D */
    {
    /*命令完成并处理测试命令*/
    TestApp_UartMsgHandler (&TestCmd[0]);
    
    /*处理 test 命令后,将 test 命令缓冲区重置为 null 终止*/
    MEMSET (&TestCmd[0]、'\0'、MAX_TEST_CMD_LEN);
    
    /*重置测试命令索引*/
    TestCmdIndex = 0;
    中断;
    }
    
    /*删除缓冲区左侧的字符*/
    案例'\b'://*'\b' 0x08 */
    {
    if (TestCmdIndex = 0)
    {
    /*没有要删除的字符*/
    }
    其他
    {
    if (TestCmdIndex >0)
    {
    TestCmdIndex--;
    }
    其他
    {
    /*不执行任何操作*/
    }
    
    /*删除缓冲区左侧的字符*/
    TestCmd[TestCmdIndex]='\0';
    }
    中断;
    }
    
    默认值:
    {
    if (((rx_data >='0')&&(rx_data <='9'))||
    ((RX_DATA >='A')&&(RX_DATA <='Z'))||
    (((rx_data >='a')&&(rx_data <='z'))||
    ((RX_DATA ='))
    {
    TestCmd[TestCmdIndex]= Rx_DATA;
    TestCmdIndex++;
    }
    其他
    {
    /*忽略其余不支持的键*/
    }
    中断;
    }
    }
    
    返回;
    } 

    -克尔

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

    我已经将 UART 初始化更改为下面的内容。 但是、我仍然需要按键8x、程序才能转到 UART 回调。

    UART_PARAMS_INIT (uartParams);
    
    uartParams.readMode = UART_MODE_CALLACK;
    //uartParams.writeMode = UART_MODE_BLOCKING;
    uartParams.readCallback = uartRxCb;
    //uartParams.readEcho = UART_ECHO_OFF;
    uartParams.baudrate = 115200;
    
    uartParams.readDataMode = UART_DATA_Binary;//UART_DATA_TEXT;
    uartParams.writeDataMode = UART_DATA_binary;//UART_DATA_text;
    uartParams.dataLength = UART_LEN_8;
    //uartParams.stopbits = UART_STOP_ONE;
    uartParams.readReturnMode = UART_return_full;//UART_return_NEWLINE;
    
    
    UART = UART_OPEN (Board_UART0、uartParams);
    
    if (UART == NULL){
    /* UART_open()失败*/
    while (1);
    }
    
    UART_WRITE (UART、echoPrompt、sizeof (echoPrompt));
    
    /*循环永久回显*/
    while (1){
    UART_READ (UART、rxBuf、sizeof (rxBuf)/sizeof (BUFTYPE));
    } 

    -克尔

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

    问题已解决。 我将 UART 读取移到了 while 环路之外。 按1次键后、它将转至 UART 回叫。

    const char echoPrompt[]="回显字符:\r\n";
    UART_Params uartParams;
    
    /*调用驱动程序初始化函数*/
    GPIO_init();
    UART_INIT();
    
    /*打开用户 LED */
    GPIO_WRITE (Board_GPIO_LED0、1);
    
    /*创建一个数据处理关闭的 UART。 *
    UART_PARAMS_INIT (uartParams);
    
    uartParams.readMode = UART_MODE_CALLACK;
    uartParams.writeMode = UART_MODE_BLOCKING;
    uartParams.readCallback = uartRxCb;
    uartParams.baudrate = 115200;
    
    uartParams.readDataMode = UART_DATA_Binary;//UART_DATA_TEXT;
    uartParams.writeDataMode = UART_DATA_binary;//UART_DATA_text;
    uartParams.dataLength = UART_LEN_8;
    //uartParams.stopbits = UART_STOP_ONE;
    uartParams.readReturnMode = UART_return_full;//UART_return_NEWLINE;
    
    
    UART = UART_OPEN (Board_UART0、uartParams);
    
    if (UART == NULL){
    /* UART_open()失败*/
    while (1);
    }
    
    UART_WRITE (UART、echoPrompt、sizeof (echoPrompt));
    UART_READ (UART、rxBuf、sizeof (rxBuf)/sizeof (BUFTYPE));
    
    /*循环永久回显*/
    while (1){
    //uart_read (UART、rxBuf、sizeof (rxBuf)/sizeof (BUFTYPE));
    } 

    -克尔

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

    但它仅回调一次。 您需要重新调用 UART_Read 进行下一次回调。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    奇怪的是、它需要重新调用 UART_READ 进行下一次回调。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Luu Vy:

      是的、它只进行一次回调。 可能是因为"uartParams.writeMode = UART_MODE_BLOCK"。 也许我需要使用来自 svendbt 代码的信标。 我注意到、当缓冲区已满时、会进行回调。

      我需要按键8x 来触发 UART 读回调真的很奇怪。

      我一直在实验什么可能导致 UART 读回调、我注意到如果我在下面设置、如果我按下"Enter Key"、则不会发生 UART 读回调。

    uartParams.readDataMode = UART_DATA_TEXT;
    uartParams.writeDataMode = UART_DATA_TEXT;
    uartParams.readReturnMode = UART_return_NEWLINE;

      此外、如果我在下面设置、字符不会回显。

    uartParams.readEcho = UART_ECHO_ON;

      TI 的某个人能否就不支持上述这2项的原因发表评论?

    -克尔

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

    尊敬的 Luu Vy:

      如果我在 UART 发送回调时调用 UART_READ()、我能够持续执行 UART 回显。 某种程度上似乎不是正确的方法、但它起作用。

    /*
    === uartecho.c ====
    */
    #include 
    #include 
    
    /*驱动程序头文件*/
    #include 
    #include 
    
    /*示例/板头文件*/
    #include "Board.h"
    #include "string.h"
    
    //由 Markel 添加
    #define BUFTYPE char
    #define PBUFTYPE char*
    #define BUFSIZE 1
    UART_Handle UART;
    
    BUFTYPE rxBuf[BUFTXBUF[BUFSIZ];
    
    
    
    * BUFET_USTUFF_UCTL (USTUFF_UARTh
    
    )、nZE (nitude_bt)、nitzFF_eUARTxBuf (nit_bt)、nitude_rx (nate[BUT)、nitude_bt)、nitude_bu (nit_bt
    
    
    
    //由 Markel
    静态空 uartRxCb (UART_Handle handle、void *buf、size_t count)添加{
    //将 rxBuf 复制到 txBuf
    memset (txBuf、0、BUFSIZE);
    memcpy (txBuf、rxBuf、 计数);
    UART_WRITE (UART、txBuf、count);
    
    }
    
    /*
    ===== mainThread ====
    //
    void * mainThread (void * arg0)
    {
    const char echoPrompt[]="回显字符:\r\n";
    UART_Params uartParams;
    
    /*调用驱动程序初始化函数*/
    GPIO_init();
    UART_INIT();
    
    /*打开用户 LED */
    GPIO_WRITE (Board_GPIO_LED0、1);
    
    /*创建一个数据处理关闭的 UART。 *
    UART_PARAMS_INIT (uartParams);
    
    uartParams.readMode = UART_MODE_CALLACK;
    uartParams.writeMode = UART_MODE_CALLBACK;
    uartParams.readCallback = uartRxCb;
    uartParams.writeCallback = uartTxCb;
    uartParams.baudrate = 115200;
    
    uartParams.readDataMode = UART_DATA_TEXT;//UART_DATA_BINARY;
    uartParams.writeDataMode = UART_DATA_TEXT;//UART_DATA_BINARY;
    uartParams.dataLength = UART_LEN_8;
    uartParams.stopbits = UART_STOP_ONE;
    uartParams.readReturnMode = UART_return_NEWLINE;//UART_return_full;
    
    
    UART = UART_OPEN (Board_UART0、uartParams);
    
    if (UART == NULL){
    /* UART_open()失败*/
    while (1);
    }
    
    UART_WRITE (UART、echoPrompt、sizeof (echoPrompt));
    
    UART_READ (UART、rxBuf、sizeof (rxBuf)/sizeof (BUFTYPE));
    
    /*循环永久回显*/
    while (1){
    
    }
    } 

    我在论坛上看到、处理 UART 的最佳方法是创建另一个任务。 下面是示例程序的链接。

    -克尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    奇怪的是、我们必须在 UART 传输回调时调用 UART_read()来使 RX 回调工作。 希望 TI 的人能对此进行解释。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Markel Robregado:

    您的代码将正常工作、因为其逻辑正确。  
    接收 Rx 回调时。 您调用 UART_WRITE。 TX 写入完成后。 TX 回调被调用。 在 TX 调用函数中、您再次调用 UART_READ。 因此您可以再次接收 RX 回调。
    我们可以按如下方式修改代码。

    /*
    === uartecho.c ====
    */
    #include 
    #include 
    
    /*驱动程序头文件*/
    #include 
    #include 
    
    /*示例/板头文件*/
    #include "Board.h"
    #include "string.h"
    
    //由 Markel 添加
    #define BUFTYPE char
    #define PBUFTYPE char*
    #define BUFSIZE 1
    UART_Handle UART;
    
    BUFTYPE rxBuf[BUFTXYPE
    TXBuf[BUFUST_BUFUST_8
    
    
    = UTTON0;* BUTTON0 = TOOTH 0 = 0 UTTL 0 = 0 UTTLE_TOPL 0;* BUTTL 0 = 0 = UTTON0 = 0 = TOOTH 0 = 0;* UTTON0 = UTTL 0 = 0 = 0 = 0 = 0 = 0 = 0 =
    
    //UART_READ (UART、rxBuf、sizeof (rxBuf)/sizeof (BUFTYPE));
    }
    
    
    //由 Markel
    添加静态空 uartRxCb (UART_Handle handle、void * buf、size_t count){
    //将 rxBuf 复制到 Btxf
    memset (UFtxBuf、0、rxBuf
    、rxBuf); 计数);
    rxFlag = 0;
    txFlag = 1;
    UART_WRITE (UART、txBuf、 计数);
    
    }
    
    /*
    ==== mainThread ====
    //
    void * mainThread (void * arg0)
    {
    const char echoPrompt[]="回显字符:\r\n";
    UART_Params uartParams;
    
    /*调用驱动程序初始化函数*/
    GPIO_init();
    UART_INIT();
    
    /*打开用户 LED */
    GPIO_WRITE (Board_GPIO_LED0、1);
    
    /*创建一个数据处理关闭的 UART。 *
    UART_PARAMS_INIT (uartParams);
    
    uartParams.readMode = UART_MODE_CALLACK;
    uartParams.writeMode = UART_MODE_CALLBACK;
    uartParams.readCallback = uartRxCb;
    uartParams.writeCallback = uartTxCb;
    uartParams.baudrate = 115200;
    
    uartParams.readDataMode = UART_DATA_TEXT;//UART_DATA_BINARY;
    uartParams.writeDataMode = UART_DATA_TEXT;//UART_DATA_BINARY;
    uartParams.dataLength = UART_LEN_8;
    uartParams.stopbits = UART_STOP_ONE;
    uartParams.readReturnMode = UART_return_NEWLINE;//UART_return_full;
    
    
    UART = UART_OPEN (Board_UART0、uartParams);
    
    if (UART == NULL){
    /* UART_open()失败*/
    while (1);
    }
    
    UART_WRITE (UART、echoPrompt、sizeof (echoPrompt));
    
    rxFlag = 1;
    UART_READ (UART、rxBuf、sizeof (rxBuf)/sizeof (BUFTYPE));
    
    /*循环永久回显*/
    while (1){
    if (rxFlag=0 && txFlag=0)
    {
    UART_READ (UART、rxBuf、sizeof (rxBuf)/sizeof (BUFTYPE));
    }
    }
    




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

    尊敬的 Luu Vy:

      我尝试了您的代码修改、UART 回波工作正常、但效果不好。 它将回显第一个字符、然后您需要多次按某个键才能回显另一个字符。 之后它可以正常工作。  

      无论如何、我修改了 simple_peripheral 并实现了 UART Echo。 这是基于 svendbt 代码的。 我将信标更改为"Event"。 simple_peripheral UART Echo 工作正常。 以下是我的修改。 我不确定在任务的 for 循环中调用 UART_read()是否是最佳方法。

    文件名:simple_peripheral.c

    #include 
    #include "simple_peripheral.h"
    
    UART_Handle hart;
    
    BUFTYPE rxBuf[BUFSIZE];
    BUFTYPE txBuf[BUFSIZ];
    
    const char echoPrompt[]="recho:\r\n";
    
    static void uartRxCb (mem_handle、void *buf、size
    
    
    、rxBuf)、set to rxBuf (rxxBuf); 计数);
    //回显
    Event_POST 的唤醒任务(synctic 事件、SBP_UART_EVT);
    }
    
    静态空 SimpleBLEPeripheral_init (void)
    {
    。 。 。
    UART_INIT();
    
    //UART Init
    UART_Params uartParams;
    //创建一个数据处理关闭的 UART。 */
    uartParams_init (&uartParams);
    
    uartParams.readMode = UART_MODE_CALLBACK;
    uartParams.writeMode = UART_MODE_Blocking;
    uartParams.readCallback = uartRxCb;
    //uartParams.writeCallback = uartTxCb;
    uartParams.budrate = 115200;
    
    uartParams.readDataMode = UART_DATA_BINART;
    uartParams.writeDataMode = UART_DATA_BIN;
    uartParams.dataLength = UART_LEN_8;
    uartParams.stopbits = UART_STOP_1;
    uartParams.readReturnMode = UART_return_full;
    
    huart = UART_open (Board_UART0、&uartParams);
    
    if (huart = NULL){
    /* UART_open()失败*/
    while (1);
    }
    
    uart_write (huart、echoPrompt、sizeof (echoPrompt));
    }
    
    static void SimpleBLEPeripheral_taskFxn (UArg a0、UArg A1)
    {
    //初始化应用
    SimpleBLEPeripheral_init ();
    
    //应用程序主循环
    用于(;;)
    {
    uint32_t 事件;
    
    //等待与调用线程关联的事件被发布。
    //请注意,与线程关联的事件在时发布
    //消息在线程的消息接收队列中排队
    事件= Event_pend (syncEvent、Event_ID_none、SBP_All_Events、
    iCall_TIMEOUT_FOREVER);
    
    UART_READ (huart、&rxBuf、sizeof (rxBuf)/sizeof (BUFTYPE));
    
    IF (事件)
    {
    。 。 。 。
    IF (事件和 SBP_UART_EVT)
    {
    UART_WRITE (huart、txBuf、sizeof (txBuf)/sizeof (BUFTYPE));
    }
    }
    
    } 

    文件名:simple_peripheral.h

    // RTOS 应用
    程序的内部事件#define SBP_ICALL_EVT iCall_MSG_EVENT_ID // Event_ID_31
    #define SBP_queue_EVT Util_queue_event_ID // Event_ID_30
    #define SBP_State_change_EVT EVENT_ID_00
    #define SBP_CHAR_CHANGE_EVT EVENT_ID_01
    #define SK_KEY_CHANGE_EVT EVENT_ID_02
    #define SBP_UART_EVT EVENT_ID_03
    #define SBP_Period_EVT EVENT_ID_04
    
    #ifdef FEATE_OAD
    #define SBP_queue_ping_EVT EVENT_ID_01
    
    #define SBP_All_Events (SBP_ICALL_EVT |\
    SBP_queue_EVT |\
    SBP_Period_EVT |\
    SBP_queue_ping_EVT)
    #else
    #define SBP_All_Events (SBP_ICALL_EVT |\
    SBP_queue_EVT |\
    SBP_State_change_EVT |\
    SBP_CHAR_CHANGE_EVT |\
    SK_KEY_CHANGE_EVT |\
    SBP_UART_EVT |\
    SBP_Period_EVT)
    #endif /* Feature_OAD */ 

    -克尔