串口设备使用示例
中断接收及轮询发送
示例代码的主要步骤如下所示:
-
首先查找串口设备获取设备句柄。
-
初始化回调函数发送使用的信号量,然后以读写及中断接收方式打开串口设备。
-
设置串口设备的接收回调函数,之后发送字符串,并创建读取数据线程。
-
读取数据线程会尝试读取一个字符数据,如果没有数据则会挂起并等待信号量,当串口设备接收到一个数据时会触发中断并调用接收回调函数,此函数会发送信号量唤醒线程,此时线程会马上读取接收到的数据。
-
此示例代码不局限于特定的 BSP,根据 BSP 注册的串口设备,修改示例代码宏定义 SAMPLE_UART_NAME 对应的串口设备名称即可运行。
运行序列图如下图所示:
/*
* 程序清单:这是一个 串口 设备使用例程
* 例程导出了 uart_sample 命令到控制终端
* 命令调用格式:uart_sample uart2
* 命令解释:命令第二个参数是要使用的串口设备名称,为空则使用默认的串口设备
* 程序功能:通过串口输出字符串"hello RT-Thread!",然后错位输出输入的字符
*/
1 #include <rtthread.h> 2 3 #define SAMPLE_UART_NAME "uart2" 4 5 /* 用于接收消息的信号量 */ 6 static struct rt_semaphore rx_sem; 7 static rt_device_t serial; 8 9 /* 接收数据回调函数 */ 10 static rt_err_t uart_input(rt_device_t dev, rt_size_t size) 11 { 12 /* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */ 13 rt_sem_release(&rx_sem); 14 15 return RT_EOK; 16 } 17 18 static void serial_thread_entry(void *parameter) 19 { 20 char ch; 21 22 while (1) 23 { 24 /* 从串口读取一个字节的数据,没有读取到则等待接收信号量 */ 25 while (rt_device_read(serial, -1, &ch, 1) != 1) 26 { 27 /* 阻塞等待接收信号量,等到信号量后再次读取数据 */ 28 rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
//接收不到信号量就一直在这里等,等到之后就返回1,然后再进入while判断,判断不通过就进入rt_device_write() 29 } 30 /* 读取到的数据通过串口错位输出 */ 31 ch = ch + 1; 32 rt_device_write(serial, 0, &ch, 1); 33 } 34 } 35 36 static int uart_sample(int argc, char *argv[]) 37 { 38 rt_err_t ret = RT_EOK; 39 char uart_name[RT_NAME_MAX]; 40 char str[] = "hello RT-Thread!\r\n"; 41 42 if (argc == 2) 43 { 44 rt_strncpy(uart_name, argv[1], RT_NAME_MAX); 45 } 46 else 47 { 48 rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX); 49 } 50 51 /* 查找系统中的串口设备 */ 52 serial = rt_device_find(uart_name); 53 if (!serial) 54 { 55 rt_kprintf("find %s failed!\n", uart_name); 56 return RT_ERROR; 57 } 58 59 /* 初始化信号量 */ 60 rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); 61 /* 以中断接收及轮询发送模式打开串口设备 */ 62 rt_device_open(serial, RT_DEVICE_FLAG_INT_RX); 63 /* 设置接收回调函数 */ 64 rt_device_set_rx_indicate(serial, uart_input); 65 /* 发送字符串 */ 66 rt_device_write(serial, 0, str, (sizeof(str) - 1)); 67 68 /* 创建 serial 线程 */ 69 rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10); 70 /* 创建成功则启动线程 */ 71 if (thread != RT_NULL) 72 { 73 rt_thread_startup(thread); 74 } 75 else 76 { 77 ret = RT_ERROR; 78 } 79 80 return ret; 81 } 82 /* 导出到 msh 命令列表中 */ 83 MSH_CMD_EXPORT(uart_sample, uart device sample);
翻译 朗读 复制 正在查询,请稍候…… 重试 朗读 复制 复制 朗读 复制 via 谷歌翻译(国内) 译
翻译 朗读 复制 正在查询,请稍候…… 重试 朗读 复制 复制 朗读 复制 via 谷歌翻译(国内) 译