使用中断方式通过UART接收数据
- 实验目的
本节实验目的为实现串口发送和接收。这一节计划采取中断的方式来实现串口接收,K210串口接收到0x00,则熄灭前节提到的红色LED灯,并通过串口打印Red Led Off,否则,则点亮前节提到的红色LED灯,并通过串口打印Red Led On。
- 实验准备
1)、带UART和发光二极管(LED)的K210开发板一块,用于实践并查看实验现象;
2)、官方裸机编程指导手册:kendryte_standalone_programming_guide,用于查阅SDK中接口说明。
- 实验原理
串口通信是指外设和计算机间,通过数据线、地线和控制线等,按位进行数据传输的一种通信方式,传输方式为一个字符一个字符的传输,每个字符一位一位的传输,先传输低位,再传输高位,并且传输每个字符时,总是以起始位开始,以停止位结束,位于位之间可根据自己需求,设置时间间隔,这个时间间隔对应波特率;而对于有些场景,为了保证数据的可靠性,还需加上校验位,称之为奇偶校验位,以此来校验传输数据的正确性。如果两台设备之间需要通过串口进行通信,上面提到的波特率、数据位、停止位和奇偶校验位等这些必要参数,必须设置一致,才能进行串口通信。另外,串口通信支持全双工通信,即:使用一根数据线发送数据的同时,可以用另一个数据线进行数据接收。
- 硬件设计
硬件电路图如下:
- 软件设计
软件流程图如下:
- 软件实现
根据硬件设计和软件设计可知,本节应用实现步骤如下:
1)、设置引脚复用功能:由硬件原理图可知:我们需要将IO12设置为GPIOHS功能,IO4和IO5设置为UART的RX和TX功能,如下图:
2)、LED初始化,如下图:
3)、UART初始化,如下图:
4)、实现uart3接收中断回调函数,在接收中断回调函数中,实现串口接收和记录接收数据长度,如下图:
5)、通过UART发送提示信息,如下图:
6)、判断是否接收到数据,如果接收到数据,判断接收到的控制命令类型,根据接收到的控制命令,进行相应的操作,如下图:
根据上述实现步骤,最终代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116#include <fpioa.h> #include <gpiohs.h> #include <uart.h> #include <plic.h> #include <sysctl.h> #include <stdio.h> #include <sleep.h> #define LED_R_PIN (12) #define LED_R_GPIOHSNUM (0) #define LED_R_FUNC (FUNC_GPIOHS0+LED_R_GPIOHSNUM) #define UART3_RX_PIN (4) #define UART3_TX_PIN (5) #define UART3_NUM (UART_DEVICE_3) #define UART3_RX_FUNC (FUNC_UART1_RX+UART3_NUM*2) #define UART3_TX_FUNC (FUNC_UART1_TX+UART3_NUM*2) /********************************* * 管脚功能初始化 ********************************/ void init_hardware(void) { // 将红色LED管脚设置复用为GPIOHS fpioa_set_function(LED_R_PIN, LED_R_FUNC); // 将UART管脚设置复用为UART fpioa_set_function(UART3_RX_PIN, UART3_RX_FUNC); fpioa_set_function(UART3_TX_PIN, UART3_TX_FUNC); } /********************************* * LED初始化 ********************************/ void init_led(gpio_pin_value_t value) { // 设置输出 gpiohs_set_drive_mode(LED_R_GPIOHSNUM, GPIO_DM_OUTPUT); // 设置初始电平状态 gpiohs_set_pin(LED_R_GPIOHSNUM, value); } /********************************* * 控制LED亮灭 ********************************/ void ctl_led(gpio_pin_value_t value) { gpiohs_set_pin(LED_R_GPIOHSNUM, value); } struct RCVBUF { char buf[128]; unsigned char len; }; /********************************* * UART接收中断回调函数 ********************************/ int irq_uart3_rcv(void *ctx) { struct RCVBUF *rcv_buf = (struct RCVBUF *)ctx; rcv_buf->len = uart_receive_data(UART3_NUM, rcv_buf->buf, 1); return 0; } /********************************* * UART初始化 ********************************/ void init_uart(struct RCVBUF *rcv_buf) { // 初始化 uart uart_init(UART3_NUM); // 设置 uart 工作模式 uart_set_work_mode (UART3_NUM , UART_NORMAL); // 设置 UART 相关参数 uart_config (UART3_NUM , 115200 , UART_BITWIDTH_8BIT , UART_STOP_1 , UART_PARITY_NONE); // 初始化外部中断 plic_init(); // 注册 UART 中断函数 uart_irq_register (UART3_NUM, UART_RECEIVE, irq_uart3_rcv, rcv_buf , 1); // 设置接收中断 触发 FIFO 深度 uart_set_receive_trigger(UART3_NUM, UART_RECEIVE_FIFO_1); // 使能系统中断,如果使用中断,一定要开启系统中断 sysctl_enable_irq(); } int main(int argc, char **argv) { init_hardware(); init_led(GPIO_PV_HIGH); struct RCVBUF rcv_buf = { .len = 0, }; init_uart(&rcv_buf); uart_send_data(UART3_NUM, "CTL LED:[0:OFF/1:ON] rn", sizeof("CTL LED:[0:OFF/1:ON] rn")); while (1) { if(rcv_buf.len != 0) { uart_send_data(UART3_NUM, "rcv_buf.len:", sizeof("rcv_buf.len:")); uart_send_data(UART3_NUM, (char *)&rcv_buf.len, sizeof(rcv_buf.len)); if(rcv_buf.buf[0] == 0) { uart_send_data(UART3_NUM, "LER_R OFF! rn", sizeof("LER_R OFF! rn")); ctl_led(GPIO_PV_HIGH); } else { uart_send_data(UART3_NUM, "LER_R ON! rn", sizeof("LER_R ON! rn")); ctl_led(GPIO_PV_LOW); } uart_send_data(UART3_NUM, "CTL LED:[0:OFF/1:ON] rn", sizeof("CTL LED:[0:OFF/1:ON] rn")); rcv_buf.len = 0; } usleep(20000); } return 0; }
- 编译
1)、同上一节类似,在SDK中创建uart_irq文件夹,在新建的文件夹中创建一个main.c文件,然后将本节代码输入到main.c文件中,如下图:
2)、同上一节的编译方式类似,打开vscode终端,在终端中进入上一节创建的build文件夹,然后输入:cmake ../ -DPROJ=uart_irq -G "MinGW Makefiles" ,生成makefile文件,如下图:
3)、生成makefile文件后,输入:make ,开始编译,如下图:
4)、编译完成后,会在build目录下生成烧录文件:uart_irq.bin,如下图:
- 烧录
同上一节的烧录方式类似,注意:Firmware那一项选择我们刚编译出的uart_irq.bin文件。
- 实验现象
通过串口助手,发送0x00,红色LED灯熄灭,发送其他非零数,红色LED亮起。如下图:
1)、开启LED
2)、关闭LED
- 实验总结
1)、K210串口中断有接收中断和发送中断,用户可根据需求设置想要的中断方式;
2)、K210串口的中断可设置触发FIFO深度,用户可根据需求设置想要的FIFO深度。
最后
以上就是难过皮皮虾最近收集整理的关于K210应用5-使用中断方式通过UART接收数据的全部内容,更多相关K210应用5-使用中断方式通过UART接收数据内容请搜索靠谱客的其他文章。
发表评论 取消回复