记录一下自己的学习过程,如有错误多多指教。
我使用的时野火的开发板,芯片是F767IGT6。
首先,写一个UART的c文件,配置一下UART。
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-06-11 c the first version
*/
#include <rtthread.h>
#define SAMPLE_UART_NAME "uart1"
//用于接收消息的信号量
static struct rt_semaphore rx_sem;
static rt_device_t serial;
//接受数据回调函数
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
rt_sem_release(&rx_sem);
return RT_EOK;
}
static void serial_thread_entry(void *parameter)
{
char ch;
while(1)
{
//从串口读取一个字节的数据/没有读取到就等待接收信号量
while(rt_device_read(serial, -1, &ch, 1) != 1)
{
//阻塞等待接收信号量/等到信号量 后再次读取数据
rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
}
//读取到的数据通过串口错位输出
ch = ch + 1;
rt_device_write(serial, 0, &ch, 1);
}
}
static int uart_sample (int argc, char *argv[])
{
rt_err_t ret = RT_EOK;
char uart_name[RT_NAME_MAX];
char str[] = "hello RT-Thread!\r\n";
if(argc == 2)
{
rt_strncpy(uart_name, argv[1], RT_NAME_MAX);
}
else {
rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);
}
//查找系统中的串口设备
serial = rt_device_find(uart_name);
if (!serial)
{
rt_kprintf("find %s failed!\n", uart_name);
return RT_ERROR;
}
//初始化信号量
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
//以读写和中断接收方式打开串口设备
rt_device_open(serial, RT_DEVICE_OFLAG_RDWR|RT_DEVICE_FLAG_INT_RX);
//设置接收回调函数
rt_device_set_rx_indicate(serial, uart_input);
//发送字符串
rt_device_write(serial, 0, str, sizeof(str) - 1);
//创建serial线程
rt_thread_t thread = rt_thread_create("serial",serial_thread_entry, RT_NULL, 1024, 25, 10);
//创建成功则启动线程
if( thread != RT_NULL)
{
rt_thread_startup(thread);
}
else {
ret = RT_ERROR;
}
return ret;
}
MSH_CMD_EXPORT(uart_sample, uart device sample);
这里我们的串口是通过MSH_CMD,来调用的所以我们的main函数中是不需要调用函数的,所以main函数不用写任何的东西,然后uart.h文件其实也不用做什么,我这里声明了一个.c文件中的函数。
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-06-11 c the first version
*/
#ifndef APPLICATIONS_UART_H_
#define APPLICATIONS_UART_H_
int uart_sample(int argc, char *argv[]);
#endif /* APPLICATIONS_UART_H_ */
然后编译,下载。也没有报错。
接下来我打开RT终端准备测试一下串口。发现RT的 终端竟然没有反应。首先检查了串口的注册,是uart1没有问题,引脚也没有问题。在KEIL测试串口也是可以使用的。终端就是没有响应。而且
只显示了这些内容,很显然是系统根本没有启动,和硬件是没有关系的。
网上搜索最后发现问题:
刚创建的项目控制台为什么不能用
跟着做之后问题就解决了,真的很感谢这位老哥。
我们的串口也是测试成功,接下来让它控制一下LED:
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-06-11 c the first version
* 2023-11-02 AI Assistant Add LED control via UART commands
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#define SAMPLE_UART_NAME "uart1"
// 三色灯引脚定义 - 使用 GET_PIN 宏定义
#define LED_R_PIN GET_PIN(H, 10) // PH10 (122)
#define LED_G_PIN GET_PIN(H, 11) // PH11 (123)
#define LED_B_PIN GET_PIN(H, 12) // PH12 (124)
// 灯状态变量
static rt_base_t led_r_stat = PIN_HIGH;
static rt_base_t led_g_stat = PIN_HIGH;
static rt_base_t led_b_stat = PIN_HIGH;
// 用于接收消息的信号量
static struct rt_semaphore rx_sem;
static rt_device_t serial;
// 接受数据回调函数
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
rt_sem_release(&rx_sem);
return RT_EOK;
}
// 控制LED显示状态
static void ctrl_led_show(void)
{
rt_pin_write(LED_R_PIN, led_r_stat);
rt_pin_write(LED_G_PIN, led_g_stat);
rt_pin_write(LED_B_PIN, led_b_stat);
// 调试信息 - 输出当前LED状态
rt_kprintf("LED Status: R:%d G:%d B:%d (Pins: %d, %d, %d)\n",
led_r_stat == PIN_LOW,
led_g_stat == PIN_LOW,
led_b_stat == PIN_LOW,
LED_R_PIN, LED_G_PIN, LED_B_PIN);
}
// 串口命令解释执行
static void process_uart_cmd(char cmd)
{
char response[256];
rt_size_t len = 0;
switch (cmd)
{
case 'r': case 'R': // 红灯开关
led_r_stat = (led_r_stat == PIN_LOW) ? PIN_HIGH : PIN_LOW;
len = rt_snprintf(response, sizeof(response), "Red LED: %s\r\n",
led_r_stat == PIN_LOW ? "ON" : "OFF");
break;
case 'g': case 'G': // 绿灯开关
led_g_stat = (led_g_stat == PIN_LOW) ? PIN_HIGH : PIN_LOW;
len = rt_snprintf(response, sizeof(response), "Green LED: %s\r\n",
led_g_stat == PIN_LOW ? "ON" : "OFF");
break;
case 'b': case 'B': // 蓝灯开关
led_b_stat = (led_b_stat == PIN_LOW) ? PIN_HIGH : PIN_LOW;
len = rt_snprintf(response, sizeof(response), "Blue LED: %s\r\n",
led_b_stat == PIN_LOW ? "ON" : "OFF");
break;
case '0': // 所有灯关
led_r_stat = PIN_HIGH;
led_g_stat = PIN_HIGH;
led_b_stat = PIN_HIGH;
len = rt_snprintf(response, sizeof(response), "All LEDs OFF\r\n");
break;
case '1': // 所有灯开(白色)
led_r_stat = PIN_LOW;
led_g_stat = PIN_LOW;
led_b_stat = PIN_LOW;
len = rt_snprintf(response, sizeof(response), "All LEDs ON (White)\r\n");
break;
case 'c': case 'C': // 青色(绿+蓝)
led_r_stat = PIN_HIGH;
led_g_stat = PIN_LOW;
led_b_stat = PIN_LOW;
len = rt_snprintf(response, sizeof(response), "Cyan (Green+Blue)\r\n");
break;
case 'm': case 'M': // 品红色(红+蓝)
led_r_stat = PIN_LOW;
led_g_stat = PIN_HIGH;
led_b_stat = PIN_LOW;
len = rt_snprintf(response, sizeof(response), "Magenta (Red+Blue)\r\n");
break;
case 'y': case 'Y': // 黄色(红+绿)
led_r_stat = PIN_LOW;
led_g_stat = PIN_LOW;
led_b_stat = PIN_HIGH;
len = rt_snprintf(response, sizeof(response), "Yellow (Red+Green)\r\n");
break;
case '?': // 帮助信息
len = rt_snprintf(response, sizeof(response),
"\r\nLED Control Commands:\r\n"
"R - Toggle Red LED\r\n"
"G - Toggle Green LED\r\n"
"B - Toggle Blue LED\r\n"
"0 - All OFF\r\n"
"1 - All ON (White)\r\n"
"C - Cyan (Green+Blue)\r\n"
"M - Magenta (Red+Blue)\r\n"
"Y - Yellow (Red+Green)\r\n"
"Q - Help\r\n"
);
break;
default: // 无效命令
len = rt_snprintf(response, sizeof(response), "Unknown command: %c\r\nUse ? for help\r\n", cmd);
break;
}
// 更新LED状态
ctrl_led_show();
// 发送响应到串口
if (len > 0 && len < sizeof(response)) {
rt_device_write(serial, 0, response, len);
}
}
static void serial_thread_entry(void *parameter)
{
char ch;
while (1)
{
// 从串口读取数据
while (rt_device_read(serial, -1, &ch, 1) != 1)
{
// 等待接收信号量
rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
}
// 处理串口命令
process_uart_cmd(ch);
}
}
static int uart_sample(int argc, char *argv[])
{
rt_err_t ret = RT_EOK;
char uart_name[RT_NAME_MAX];
char str[] = "\r\nUART LED Controller Ready!\r\n"
"Using LEDs on PH10 (R), PH11 (G), PH12 (B)\r\n"
"Enter ? for help\r\n";
// 初始化LED引脚
rt_pin_mode(LED_R_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LED_G_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LED_B_PIN, PIN_MODE_OUTPUT);
// 设置初始状态为关闭
led_r_stat = PIN_HIGH;
led_g_stat = PIN_HIGH;
led_b_stat = PIN_HIGH;
ctrl_led_show();
// 输出调试信息
rt_kprintf("Initialized LEDs:\n");
rt_kprintf(" Red - PH10 (Pin %d)\n", LED_R_PIN);
rt_kprintf(" Green - PH11 (Pin %d)\n", LED_G_PIN);
rt_kprintf(" Blue - PH12 (Pin %d)\n", LED_B_PIN);
// 获取串口设备名称
if (argc == 2) {
rt_strncpy(uart_name, argv[1], RT_NAME_MAX);
} else {
rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);
}
// 查找串口设备
serial = rt_device_find(uart_name);
if (!serial) {
rt_kprintf("find %s failed!\n", uart_name);
return RT_ERROR;
}
// 初始化信号量
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
// 打开串口设备
if (rt_device_open(serial, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX) != RT_EOK) {
rt_kprintf("open %s failed!\n", uart_name);
return RT_ERROR;
}
// 设置串口参数(可选,根据需要设置)
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
config.baud_rate = BAUD_RATE_115200; // 115200bps
config.data_bits = DATA_BITS_8; // 8位数据位
config.stop_bits = STOP_BITS_1; // 1位停止位
config.bufsz = 64; // 接收缓冲区大小
config.parity = PARITY_NONE; // 无校验
rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);
// 设置接收回调函数
rt_device_set_rx_indicate(serial, uart_input);
// 发送欢迎信息
rt_device_write(serial, 0, str, sizeof(str) - 1);
// 创建串口处理线程
rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL,
1024, 25, 10);
// 启动线程
if (thread != RT_NULL) {
rt_thread_startup(thread);
} else {
rt_kprintf("Failed to create serial thread!\n");
ret = RT_ERROR;
}
return ret;
}
MSH_CMD_EXPORT(uart_sample, uart device sample);
只改变uart.c即可。其他文件不变。
测试后一切正常。