开发者学堂课程【嵌入式之RFID开发与应用2020版:串口接收并处理数据流程】学习笔记与课程紧密联系,让用户快速学习知识
课程地址:https://developer.aliyun.com/learning/course/665/detail/11160
串口接收并处理数据流程
内容介绍:
一、课前讲解
二、串口接收
三、主程序处理数据流程
一、课前讲解
本节课讲解串口的接收部分,前面的内容应用程序只包括fputc并未涉及get,get的部分是很难实现的,在未使用uart之前所采用的dputs循环的去输出。
二、串口接收
(1)代码录入
直接采用代码录入的方式,而不是采用敲代码的方式,因为敲代码的方法低效,浪费时间,所以选择直接带入的方式。
(2)代码功能讲解演示
首先代码使用2个窗口,使用一个进行演示。进入dputs里面。基本上没有太多变化,只是如果这个唯一便支持窗口1的中断,包括优先级也存在设置,如果说在函数不存在对优先级的配置,也没关系
依次往下,中断的使能,中断的初始化,以及中段开启接受的使能。
//Usart1 NIC配置
NVIC_Initstructure. NVIC_IRQChannel = USART1_IRQn;
NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority =1;
NvIC_Initstructure.NvIC_IRQChannelsubpriority =1;
NVIC_Initstructure. NVIC_IRQChannelcmd = ENABLE;
//IRQ通道使能
NWiC-Iit(&lWIC_Initstructure);//根据!y1C_Initstruct中指定的
参数初始化外设NWIC寄存器USAR
#endif//USART初始化设置
USART_Initstructure.USART_BaudRate = bound;
USART_Initstructure.USART_wordLength = USART_WordLength_8b;
USART_Initstructure.USART_stopBits = uSART_StopBits_1;
USART_Initstructure.USART_Parity = USART_Parity_Ho;
USART_Initstructure.uUSART_HardwareFlowControl =uSART_HardwareFlowControl_None;
USART_Initstructure.USART_Hode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1,&USART_Initstructure);
中段开启接受的使能,指开放和接收,指当接收到数据的时候,USART1-IRQHandler(void)就会产生中断,注意此时接受比较麻烦的是,只是收到一个字体便产生中断,通过Receive去读取字体,但是最麻烦的是需要管理收到的字据
比如如下为之前所创建的网观,如连接GPS模块或者是NBLP模块,
作为一个网观,指令为字符串,如/r/n,对接收到的收据进行切割,并且把收到的数据推入到队列当中。队列是自己进行编写的队列。
void USART1_IRQHandler(void)//
串口1中断服务程序
{
if(USART_GetITStatus(USARTI, USARTITRXNE) !=RESET)
//接收中断(接收到的数据必须是0x0d
{
usart_rx_buf[usart_rx_len]=USART_ReceiveData(USART1);//(USART1->DR);//
读取接收到的
usart_rx_len++;
if(usart_rx_len >= QUEUE_RSG_LEN)|usart_rx_len-;//
接收数据错误或超出,重新开始接收
if(usart_rx_len>0)
if((usart_rx_buf[usart_rx_len-1]=='\r')||(usart_rx_buf[usart_rx_len-1]=='\n')usart_rx_len--;//
不保存\r\n
usart_rx_buf[usart_rx_len]=0;//
针对字符串
if((usart_rx_len
>0)&&(usart_rx_len <QUEUE_MSG_LEN)
put_queue(har*)usart_rx_buf);//
遇到\r或\n就保存一次数据到队列中
usart_rx_len=0;//
重新开始接收数据
}
比如接收到一个字符串,应用程序理应处理该字符串,但是由于应用程序是同时进行的或者存在多个字符串,应用程序处理不过来,所以应该将字符串存入队列中,等待应用程序有时间,再进行处理,这是提供一个合理的缓存这是串口1,一般将串口1当作调试串口,将串口2当作网观,串口2使用PA2PA3这两个引脚,配置方式与串口1相同,包括中断也是在网上也存在不少处理的方式,但都存在问题,以上方式是在多次经验积累总结而成。
如中断产生,将接受到usart中,但是不能超过usart的最长长度,规定每一条命令不超过128字节,所以接收的字符串都不超过128个字节,但是可以改的长一些,如果说接受的字符串每一个长度都是正确的,就可以判断收到的是否为命令的结尾,若已经结束,便不保存/r/n,只保存命令的主体部分,比如,ifconfig。并将其存入队列当中,将rx-len清零,并且将接收到的ifconfig指令存放到队列当中,便完成了一次接收。
usart2_rx_buf[usart2_rx_len]=UsART_ReceiveData(USART2);//(USART2->DR);//
读取接收到的,
usart2_rx_len++;
if(usart2_rx_len >= GATEWAY_QUEUE_ MSG LEN)
usart2_rx_len=;//
接收数据错误或超出,重新开始接收
if(usart2_rx_len >0)
if((usart2_rx_buf[usart2_rx_len-1]=='\r')l|(usart2_rx_buf[usart2_rx_len-1]='usart2_rx_len--;//不保存\r\n
usart2_rx_buf[usart2_rx_len]=0;//
针对字符串
if((usart2_rx_len
>0)&&(usart2_rx_len <GATEWAY_QUEUE_MSG_LEN))
gateway_put_queue((char *)usart2_rx_buf);//
遇到\r或\n就保存一次数据到队列
usart2_rx_len=0;//重新开始接收数据
三、主程序处理数据流程
在主程序中,不在进行窗口二,而是进行窗口一中的put-queue,在窗口二中是gateway-put-quece如同如下语句:
If(gatway-get-queue(recv) = = 0)
Debug (“geateway=%s/n ”,recv)
不选择该语句,直接从串口接收数据,便将数据直接打印出来
但是按照之前代码发出并无反应,如输入abcd,添加换行,在自动添加附加位,选择固定值,依然没有反应,所以之前代码并不可行。
观察现在代码,重新编译,进行下载,复位。观察发现较之前多出前缀,因为本次采用bebug打印
接下来采用按键,发现并无问题,再次发送abcd ,或者长指令,发送中文,均无问题。
所以串口的发送可以不加中断,直接完成,但接收是异步事件,发送方时间是未知的,最难点是如何在一堆数据中进行选择识别。