Receive Polling

该示例演示使用 UART 轮询方式与 PC 终端进行数据通信。

PC 终端程序(如 PUTTY 或 UartAssist)发送数据,SoC 在主程序内循环检测接收数据,并将相同数据发回给 PC 终端,在 PC 中断程序可看到对应信息。

环境需求

该示例支持以下开发套件:

开发套件

Hardware Platforms

Board Name

RTL8752H HDK

RTL8752H EVB

更多信息请参考 快速入门

硬件连线

连接 P3_0(UART TX)和 FT232 的 RX,P3_1(UART RX)和 FT232 的 TX。

编译和下载

该示例的工程路径如下:

Project file: board\evb\io_sample\UART\Polling\mdk

Project file: board\evb\io_sample\UART\Polling\gcc

请按照以下步骤操作构建并运行该示例:

  1. 打开工程文件。

  2. 按照 快速入门编译 APP Image 给出的步骤构建目标文件。

  3. 编译成功后,在路径 mdk\bingcc\bin 下会生成 app bin app_MP_xxx.bin 文件。

  4. 按照 快速入门MP Tool 给出的步骤将 app bin 烧录至 EVB 内。

  5. 按下 reset 按键,开始运行。

测试验证

准备阶段

启动 PuTTY 或 UartAssist 等 PC 终端,连接到使用的 COM 端口,并进行以下 UART 设置:

  • 波特率: 115200

  • 8 数据位

  • 1 停止位

  • 无校验

  • 无硬件流控

测试阶段

  1. 该示例开始发送 ### Uart demo polling read uart data ####\r\n,观察 PC 终端上出现的字符串。

  2. 在 PC 终端上输入数据,观察 PC 终端上 SoC 是否回复了相同的数据。

代码介绍

该章节分为以下几个部分:

  1. 源码路径

  2. 初始化函数将在 初始化 章节介绍。

  3. 初始化后的功能实现将在 功能实现 章节介绍。

源码路径

  • 工程路径: sdk\board\evb\io_sample\UART\Polling

  • 源码路径: sdk\src\sample\io_sample\UART\Polling

该工程的工程文件代码结构如下:

└── Project: polling
    └── secure_only_app
        └── include
            ├── app_define.h
            └── rom_uuid.h
        ├── cmsis                    includes CMSIS header files and startup files
            ├── overlay_mgr.c
            ├── system_rtl876x.c
            └── startup_rtl876x.s
        ├── lib                      includes all binary symbol files that user application is built on
            ├── rtl8752h_sdk.lib
            ├── gap_utils.lib
            └── ROM.lib
        ├── peripheral               includes all peripheral drivers and module code used by the application
            ├── rtl876x_rcc.c
            ├── rtl876x_pinmux.c
            ├── rtl876x_nvic.c
            └── rtl876x_uart.c
        ├── profile
        └── app                      includes the ble_peripheral user application implementation
            └── main.c

初始化

当 EVB 复位启动时,执行 main 函数,执行以下流程:

int main(void)
{
    extern uint32_t random_seed_value;
    srand(random_seed_value);
    uart_demo();

    while (1)
    {

    }
}

uart_demo 中,包含 PAD/PINMUX 设置,UART 外设的初始化等流程。

void uart_demo(void)
{
    uint16_t demo_str_len = 0;
    uint8_t rx_byte = 0;

    board_uart_init();
    driver_uart_init();

    ...
}

board_uart_init 为 UART 相关的 PAD/PINMUX 设置,包含如下流程:

  1. 配置 PAD:设置引脚,PINMUX 模式,PowerOn,内部上拉,输出失能。

  2. 配置 PINMUX:配置引脚分别为 UART0_TX 和 UART0_RX 功能。

driver_uart_init 为 UART 外设的初始化,包含如下流程:

  1. 使能 RCC 时钟。

  2. 配置 UART 的波特率为 115200。

void driver_uart_init(void)
{
    UART_DeInit(UART0);

    RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);

    /* uart init */
    UART_InitTypeDef UART_InitStruct;
    UART_StructInit(&UART_InitStruct);

    /* Config uart baudrate */
    UART_InitStruct.UART_Div            = BaudRate_Table[BAUD_RATE_115200].div;
    UART_InitStruct.UART_Ovsr           = BaudRate_Table[BAUD_RATE_115200].ovsr;
    UART_InitStruct.UART_OvsrAdj        = BaudRate_Table[BAUD_RATE_115200].ovsr_adj;

    UART_Init(UART0, &UART_InitStruct);
}

功能实现

  1. 定义字符串 ### Uart demo polling read uart data ###\r\n ,执行 uart_senddata_continuous 将字符串内容发送至 PC 端。

    1. uart_senddata_continuous 内,轮询检测标志位 UART_FLAG_TX_FIFO_EMPTY,判断 UART TX FIFO 是否为空。

    2. 当 UART TX FIFO 空时,通过循环将数据塞入 TX FIFO 内,实现数据的多字节连续发送。

    3. 在 PC 端串口助手可以看到 SoC 发送的字符串数据。

    void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount)
    {
        uint8_t count;
    
        while (vCount / UART_TX_FIFO_SIZE > 0)
        {
            while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
            for (count = UART_TX_FIFO_SIZE; count > 0; count--)
            {
                UARTx->RB_THR = *pSend_Buf++;
            }
            vCount -= UART_TX_FIFO_SIZE;
        }
    
        while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0);
        while (vCount--)
        {
            UARTx->RB_THR = *pSend_Buf++;
        }
    }
    
  2. 循环检测 UART 接收数据的状态。当检测到 PC 端有数据发送进来时,接收数据,并将接收的数据发送回 PC 端,在 PC 端串口助手可以观察到收到的数据与刚刚发送的数据相同。

    /* Loop rx and tx */
    while (1)
    {
        if (UART_GetFlagStatus(UART0, UART_FLAG_RX_DATA_AVA) == SET)
        {
            rx_byte = UART_ReceiveByte(UART0);
            UART_SendByte(UART0, rx_byte);
        }
    }