Receive Interrupt
该示例演示使用 UART 中断方式与PC终端进行数据通信。
PC终端程序(如PUTTY或UartAssist)发送数据。
SoC接收数据并触发中断。在UART中断处理函数中,在 UART_INT_RD_AVA
中断中将接收到的数据存储到缓冲区中,在 UART_FLAG_RX_IDLE
中断中置位received_flag以表示接收完成。
一旦received_flag被设置,SoC将缓冲区数据发送回PC终端。
环境需求
该示例支持以下开发套件:
Hardware Platforms |
Board Name |
---|---|
RTL87x2G HDK |
RTL87x2G EVB |
更多信息请参考快速入门。
硬件连线
连接P3_0和FT232的RX,P3_1和FT232的TX。
编译和下载
该示例的工程路径如下:
Project file: samples\peripheral\uart\rx_interrupt\proj\rtl87x2g\mdk
Project file: samples\peripheral\uart\rx_interrupt\proj\rtl87x2g\gcc
请按照以下步骤操作构建并运行该示例:
打开工程文件。
按照 快速入门 中 编译APP Image 给出的步骤构建目标文件。
编译成功后,在路径
mdk\bin
或gcc\bin
下会生成 app binapp_MP_xxx.bin
文件。按下复位按键,开始运行。
测试验证
准备阶段
启动 PuTTY 或 UartAssist 等PC终端,连接到使用的COM端口,并进行以下UART设置:
波特率: 115200
8 数据位
1 停止位
无校验
无硬件流控
测试阶段
当EVB启动后,在Debug Analyzer工具内观察如下log。
Start uart rx interrupt test!
该示例开始发送
### Uart interrupt sample ###\r\n
,观察PC终端上出现的字符串。在PC终端上输入字符串,并观察PC终端上是否出现相同的字符串。同时在Debug Analyzer工具上会显示接收到的数据和中断信息。
代码介绍
该章节分为以下几个部分:
源码路径
工程路径:
sdk\samples\peripheral\uart\rx_interrupt\proj
源码路径:
sdk\samples\peripheral\uart\rx_interrupt\src
该工程的工程文件代码结构如下:
└── Project: output_toggle
└── secure_only_app
└── Device includes startup code
├── startup_rtl.c
└── system_rtl.c
├── CMSIS includes CMSIS header files
├── CMSE Library Non-secure callable lib
├── lib includes all binary symbol files that user application is built on
└── rtl87x2g_io.lib
├── peripheral includes all peripheral drivers and module code used by the application
├── rtl_nvic.c
├── rtl_pinmux.c
├── rtl_rcc.c
└── rtl_uart.c
└── APP includes the ble_peripheral user application implementation
├── io_uart.c
└── main_ns.c
初始化
初始化流程包括了 board_uart_init
和 driver_uart_init
。
board_uart_init
中包含了PAD与PINMUX设置:
配置PAD:设置引脚、PINMUX模式、PowerOn、内部上拉。
配置PINMUX:分配引脚分别为UART3_TX、UART3_RX功能。
driver_uart_init
包含了对uart外设的初始化:
使能PCC时钟源。
设置波特率为115200,校验位为无奇偶校验,停止位为1位,数据长度为8bits。
设置接收阈值为14。
使能UART接收中断
UART_INT_RD_AVA
和UART接收空闲中断UART_INT_RX_IDLE
。
RCC_PeriphClockCmd(APBPeriph_UART3, APBPeriph_UART3_CLOCK, ENABLE);
...
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_InitStruct.UART_Parity = UART_PARITY_NO_PARTY;
UART_InitStruct.UART_StopBits = UART_STOP_BITS_1;
UART_InitStruct.UART_WordLen = UART_WORD_LENGTH_8BIT;
UART_InitStruct.UART_RxThdLevel = 14;
UART_InitStruct.UART_IdleTime = UART_RX_IDLE_2BYTE;
...
UART_INTConfig(UART_DEMO, UART_INT_RD_AVA, ENABLE);
UART_INTConfig(UART_DEMO, UART_INT_RX_IDLE, ENABLE);
...
功能实现
执行
uart_senddata_continuous
,发送### Uart interrupt sample ###\r\n
到PC终端。PC终端发送字符串后,检测接收到数据时,
UART_INT_RD_AVA
或UART_INT_RX_IDLE
中断被触发。在UART中断处理函数中,UART正在接收数据会触发
UART_INT_RD_AVA
中断,工作流程如下:关闭
UART_INT_RD_AVA
中断。执行
UART_GetIID()
,获得中断标志类型。当ID为
UART_INT_ID_RX_LEVEL_REACH
(RX FIFO数据长度达到RX FIFO阈值UART_RxThdLevel)时,接收FIFO数据,保存到UART_Recv_Buf中。当ID为
UART_INT_ID_RX_DATA_TIMEOUT
(RX FIFO中至少有一个UART数据,并且不再有数据进来保持4个字节时间)时,接收FIFO数据,保存到UART_Recv_Buf中。
开启
UART_INT_RD_AVA
中断。
在UART中断处理函数中,UART完成接收数据会触发
UART_FLAG_RX_IDLE
中断(读空RX FIFO数据后,在RX空闲超时时间内没有数据进入RX FIFO),工作流程如下:失能
UART_INT_RX_IDLE
中断。清除接收FIFO。
重新使能
UART_INT_RX_IDLE
中断。置位接收标志receive_flag。
uint32_t int_status = UART_GetIID(UART_DEMO);
UART_INTConfig(UART_DEMO, UART_INT_RD_AVA, DISABLE);
if (UART_GetFlagStatus(UART_DEMO, UART_FLAG_RX_IDLE) == SET)
{
UART_INTConfig(UART_DEMO, UART_INT_RX_IDLE, DISABLE);
UART_ClearRxFIFO(UART_DEMO);
UART_INTConfig(UART_DEMO, UART_INT_RX_IDLE, ENABLE);
receive_flag = true;
}
switch (int_status & 0x0E)
{
case UART_INT_ID_RX_DATA_TIMEOUT:
{
lenth = UART_GetRxFIFODataLen(UART_DEMO);
UART_ReceiveData(UART_DEMO, UART_Recv_Buf, lenth);
...
break;
}
...
case UART_INT_ID_RX_LEVEL_REACH:
{
lenth = UART_GetRxFIFODataLen(UART_DEMO);
UART_ReceiveData(UART_DEMO, UART_Recv_Buf, lenth);
...
break;
}
...
}
UART_INTConfig(UART_DEMO, UART_INT_RD_AVA, ENABLE);
一旦置位received_flag,SoC就会将缓冲区数据发回PC终端。
while (1)
{
if (receive_flag == true)
{
receive_flag = false;
uart_senddata_continuous(UART_DEMO, UART_Send_Buf, UART_Recv_Buf_Lenth);
for (uint16_t i = 0; i < UART_Recv_Buf_Lenth; i++)
{
UART_Recv_Buf[i] = 0;
}
UART_Recv_Buf_Lenth = 0;
}
}