目录
概述
1 硬件介绍
2 软件配置
2.1 RT-Thread Studio配置参数
2.2 FSP配置MCU
3 RT-Thread中UART的接口介绍
3.1 RT-Thread UART简介
3.2 RT-Thread 下的UART接口
4 UART的应用
4.1 应用功能实现
4.2 源代码文件
5 测试
程序下载地址:
RenesaVersionBoard开发RT-Thread之UART驱动应用资源-CSDN文库
概述
本文主要介绍RT-Thread下UART接口的使用方法,笔者使用Renesa Version Board开发板,其开放的UART端口为UART2。文章介绍了使用RT-Studio使能UART,使用FSP配置和使能UART-2,然后编写基于RT-Thread下UART的驱动接口,并测试其功能。
1 硬件介绍
Renesa Version Board开发板扩展接口上提供一个UART接口,其对应Pin引脚为:
Renesa Version Board | 功能定义 |
P802 | RX |
P801 | TX |
2 软件配置
2.1 RT-Thread Studio配置参数
点击RT-thread Settings, 在Hardware中使能UART2,并保存配置信息
2.2 FSP配置MCU
1) 在RT-Thread Studio中点击FSP,打开该软件
2)配置SCI下的UART
3) 创建UART对应的stack
4) 完成以上参数配置后就可以生成项目文件
在hal_data.c文件中,看见和uart相关的代码:
sci_b_uart_instance_ctrl_t g_uart2_ctrl;
sci_b_baud_setting_t g_uart2_baud_setting =
{
/* Baud rate calculated with 0.160% error. */ .baudrate_bits_b.abcse = 0, .baudrate_bits_b.abcs = 0, .baudrate_bits_b.bgdm = 1, .baudrate_bits_b.cks = 0, .baudrate_bits_b.brr = 64, .baudrate_bits_b.mddr = (uint8_t) 256, .baudrate_bits_b.brme = false
};
/** UART extended configuration for UARTonSCI HAL driver */
const sci_b_uart_extended_cfg_t g_uart2_cfg_extend =
{
.clock = SCI_B_UART_CLOCK_INT,
.rx_edge_start = SCI_B_UART_START_BIT_FALLING_EDGE,
.noise_cancel = SCI_B_UART_NOISE_CANCELLATION_DISABLE,
.rx_fifo_trigger = SCI_B_UART_RX_FIFO_TRIGGER_MAX,
.p_baud_setting = &g_uart2_baud_setting,
.flow_control = SCI_B_UART_FLOW_CONTROL_RTS,
#if 0xFF != 0xFF
.flow_control_pin = BSP_IO_PORT_FF_PIN_0xFF,
#else
.flow_control_pin = (bsp_io_port_pin_t) UINT16_MAX,
#endif
.rs485_setting = {
.enable = SCI_B_UART_RS485_DISABLE,
.polarity = SCI_B_UART_RS485_DE_POLARITY_HIGH,
.assertion_time = 1,
.negation_time = 1,
}
};
/** UART interface configuration */
const uart_cfg_t g_uart2_cfg =
{
.channel = 2,
.data_bits = UART_DATA_BITS_8,
.parity = UART_PARITY_OFF,
.stop_bits = UART_STOP_BITS_1,
.p_callback = g_uart2_Callback,
.p_context = NULL,
.p_extend = &g_uart2_cfg_extend,
#define RA_NOT_DEFINED (1)
#if (RA_NOT_DEFINED == RA_NOT_DEFINED)
.p_transfer_tx = NULL,
#else
.p_transfer_tx = &RA_NOT_DEFINED,
#endif
#if (RA_NOT_DEFINED == RA_NOT_DEFINED)
.p_transfer_rx = NULL,
#else
.p_transfer_rx = &RA_NOT_DEFINED,
#endif
#undef RA_NOT_DEFINED
.rxi_ipl = (12),
.txi_ipl = (12),
.tei_ipl = (12),
.eri_ipl = (12),
#if defined(VECTOR_NUMBER_SCI2_RXI)
.rxi_irq = VECTOR_NUMBER_SCI2_RXI,
#else
.rxi_irq = FSP_INVALID_VECTOR,
#endif
#if defined(VECTOR_NUMBER_SCI2_TXI)
.txi_irq = VECTOR_NUMBER_SCI2_TXI,
#else
.txi_irq = FSP_INVALID_VECTOR,
#endif
#if defined(VECTOR_NUMBER_SCI2_TEI)
.tei_irq = VECTOR_NUMBER_SCI2_TEI,
#else
.tei_irq = FSP_INVALID_VECTOR,
#endif
#if defined(VECTOR_NUMBER_SCI2_ERI)
.eri_irq = VECTOR_NUMBER_SCI2_ERI,
#else
.eri_irq = FSP_INVALID_VECTOR,
#endif
};
/* Instance structure to use this module. */
const uart_instance_t g_uart2 =
{
.p_ctrl = &g_uart2_ctrl,
.p_cfg = &g_uart2_cfg,
.p_api = &g_uart_on_sci_b
};
3 RT-Thread中UART的接口介绍
3.1 RT-Thread UART简介
RT-Thread官方网站提供了有关UART使用的详细介绍,其网站地址如下:
https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v1/uart
打开网站后,可以看见如下页面:
3.2 RT-Thread 下的UART接口
应用程序通过 RT-Thread提供的 I/O 设备管理接口来访问串口硬件,相关接口如下所示:
函数 | 描述 |
---|---|
rt_device_find() | 查找设备 |
rt_device_open() | 打开设备 |
rt_device_read() | 读取数据 |
rt_device_write() | 写入数据 |
rt_device_control() | 控制设备 |
rt_device_set_rx_indicate() | 设置接收回调函数 |
rt_device_set_tx_complete() | 设置发送完成回调函数 |
rt_device_close() | 关闭设备 |
一个使用范例:
void test_uart( void )
{
#define SAMPLE_UART_NAME "uart2" /* 串口设备名称 */
static rt_device_t serial; /* 串口设备句柄 */
char str[] = "hello RT-Thread!\r\n";
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* 配置参数 */
/* 查找串口设备 */
serial = rt_device_find(SAMPLE_UART_NAME);
/* 以中断接收及轮询发送模式打开串口设备 */
rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
/* 发送字符串 */
rt_device_write(serial, 0, str, (sizeof(str) - 1));
}
4 UART的应用
4.1 应用功能实现
编写一个函数,实现发送字符串的功能,在PC端口使用调试助手接收数据
代码16行: 定义设备信息
代码29行: 创建接收句柄
代码41行: 查找设备
代码44行: 打开串口,同时使能接收和发送功能
代码46行:发送字符串
发送数据函数接口:
回调函数接口,中断函数会调用该函数,程序员只需调用相关的接口就能进行数据处理。
4.2 源代码文件
创建comm_uart.c文件,编写如下代码:
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-08-25 Administrator the first version
*/
#include "hal_data.h"
#include "comm_uart.h"
#define TRANSFER_LENGTH 128
#define SAMPLE_UART_NAME "uart2" /* 串口设备名称 */
/* 接收模式参数 */
#define RT_DEVICE_FLAG_RX_BLOCKING 0x1000 /* 接收阻塞模式 */
#define RT_DEVICE_FLAG_RX_NON_BLOCKING 0x2000 /* 接收非阻塞模式 */
/* 发送模式参数 */
#define RT_DEVICE_FLAG_TX_BLOCKING 0x4000 /* 发送阻塞模式 */
#define RT_DEVICE_FLAG_TX_NON_BLOCKING 0x8000 /* 发送非阻塞模式 */
#define RT_DEVICE_FLAG_STREAM 0x040 /* 流模式 */
static rt_device_t serial; /* 串口设备句柄 */
uint8_t g_out_of_band_received[TRANSFER_LENGTH];
uint32_t g_transfer_complete = 0;
uint32_t g_receive_complete = 0;
uint32_t g_out_of_band_index = 0;
void comm_uartInit( void )
{
char str[] = "hello RT-Thread, I am uart2!\r\n";
/* 查找串口设备 */
serial = rt_device_find(SAMPLE_UART_NAME);
// 串口设备使用模式为 (发送阻塞 接收非阻塞) 模式
rt_device_open(serial,RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
rt_device_write(serial, 0, str, (sizeof(str) - 1));
}
void com_uartSend( char *buff, int len )
{
rt_device_write(serial, 0, buff, len);
}
void com_uartTest( void )
{
char str[] = "hello RT-Thread, I am uart2!\r\n";
rt_device_write(serial, 0, str, (sizeof(str) - 1));
}
void g_uart2_Callback (uart_callback_args_t * p_args)
{
/* Handle the UART event */
switch (p_args->event)
{
/* Received a character */
case UART_EVENT_RX_CHAR:
{
/* Only put the next character in the receive buffer if there is space for it */
if (sizeof(g_out_of_band_received) > g_out_of_band_index)
{
/* Write either the next one or two bytes depending on the receive data size */
if (UART_DATA_BITS_8 >= g_uart2_cfg.data_bits)
{
g_out_of_band_received[g_out_of_band_index++] = (uint8_t) p_args->data;
}
else
{
uint16_t * p_dest = (uint16_t *) &g_out_of_band_received[g_out_of_band_index];
*p_dest = (uint16_t) p_args->data;
g_out_of_band_index += 2;
}
}
else {
g_out_of_band_index = 0;
}
break;
}
/* Receive complete */
case UART_EVENT_RX_COMPLETE:
{
g_receive_complete = 1;
break;
}
/* Transmit complete */
case UART_EVENT_TX_COMPLETE:
{
g_transfer_complete = 1;
break;
}
default:
{
}
}
}
5 测试
编译代码,下载到板卡中,在终端输入如下命令,查看UART-2是否被使能
list device
编写一个测试函数,在主函数中发送字符串:
void com_uartTest( void )
{
char str[] = "hello RT-Thread, I am uart2!\r\n";
rt_device_write(serial, 0, str, (sizeof(str) - 1));
}
运行代码,在串口终端上可以看见: