嵌入式技术及应用(STM32CubeMX版)课件 任务10 用空闲中断处理串口接收数据_第1页
嵌入式技术及应用(STM32CubeMX版)课件 任务10 用空闲中断处理串口接收数据_第2页
嵌入式技术及应用(STM32CubeMX版)课件 任务10 用空闲中断处理串口接收数据_第3页
嵌入式技术及应用(STM32CubeMX版)课件 任务10 用空闲中断处理串口接收数据_第4页
嵌入式技术及应用(STM32CubeMX版)课件 任务10 用空闲中断处理串口接收数据_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

任务10

用空闲中断处理串口接收数据任务要求STM32的PE0~PE7引脚上接有8只发光二极管控制电路,发光二极管采用低电平有效控制,编号为LED1~LED8。串口1作异步通信口,与计算机进行串行通信,计算机通过串口调试助手向STM32发送控制命令,控制发光二极管的点亮、闪烁和熄灭,STM32接收到控制命令后需用串口向计算机发送反馈信息,以便能在串口调试助手中显示相关信息。串口的波特率BR=115200bps,数据位8位,停止位1位。计算机的串口发送的控制命令以及调试助手中显示的数据如表所示,要求用STM23CubeMX生成初始化程序,然后在Keil中编程实现表的功能。任务要求表中,命令数据为16进制数,55AA为数据头,5A为数据尾,val表示用户输入的某个16进制数,例如,STM32的串口接收到0x55AA04055A,就需要用串口向计算机发送“执行命令4,收到数据05”。命令功能串口调试助手显示的数据55AA015ALED1亮,其他发光二极管熄灭执行命令1,LED1亮55AA025ALED1闪烁,其他发光二极管熄灭执行命令2,LED1闪烁55AA035ALED2亮,其他发光二极管熄灭执行命令3,LED2亮55AA04val5A点亮所有发光二极管执行命令4,收到数据val知识储备

1.串口的空闲中断STM32的串口支持多种中断,与串口接收相关的中断有8种,其中串口接收中断中最常用的是串口接收数据寄存器不为空(RXNE)中断和检测到空闲线路(IDLE)中断。串口接收数据寄存器不为空中断习惯也叫做串口接收中断。它的发生条件是,串口接收到了新的数据。因此,该中断发生后,STM32就可以从串口接收寄存器中读取新接收到的数据。检测到空闲线路中断也叫做空闲中断。它的发生条件是,串口接收完1字节数据后,数据线保持高电平(空闲)的时间超过传输1个字节数据所用的时间。

1.串口的空闲中断【举例】计算机用串口向STM32发送字符串“STM32”时,这5个字符是连续发送的,STM32接收这5个字符数据时也是连续接收的,STM32每接收到一个字符就会产生一次串口接收(RXNE)中断,但不产生IDLE中断,当这5个字符接收完毕后,接收数据线将在一个较长的时间内呈高电平状态,就会产生空闲(IDLE)中断。所以,IDLE中断的发生标志着一批连接数据接收完毕,如果我们把串口接收数据保存到某个缓冲区中,当IDLE中断发生后,我们就可以从缓冲区读取连接接收的一批数据。

2.HAL库中操作空闲中断的宏宏的用法宏__HAL_UART_GET_FLAG(__HANDLE__,__FLAG__)功能检测指定的串口中断标志是否置位。参数1__HANDLE__:串口的句柄,取值为变量huartx的地址,其中x为串口编号,值为1~5。参数2__FLAG__:所要检测的中断标志位,取值如表4-11所示。返回值所检测标志位的状态。值为SET或者RESET。(1)__HAL_UART_GET_FLAG(__HANDLE__,__FLAG__)宏2.HAL库中操作空闲中断的宏中断标志位(1)__HAL_UART_GET_FLAG(__HANDLE__,__FLAG__)宏中断源取值含义UART_FLAG_CTSCTS改变标志UART_FLAG_LBD检测到LIN断路标志UART_FLAG_TXE发送数据寄存器为空标志UART_FLAG_TC发送完成标志UART_FLAG_RXNE接收数据寄存器非空标志UART_FLAG_IDLE空闲线路标志UART_FLAG_ORE溢出错误标志UART_FLAG_NE噪声错误标志UART_FLAG_FE帧错误标志UART_FLAG_PE奇偶校验错误标志

2.HAL库中操作空闲中断的宏宏的用法宏__HAL_UART_CLEAR_IDLEFLAG(__HANDLE__)功能清除指定串口的空闲中断标志位。参数__HANDLE__:串口的句柄,取值为变量huartx的地址,其中x为串口编号,值为1~5。返回值无。(2)__HAL_UART_CLEAR_IDLEFLAG(__HANDLE__)宏【说明】在HAL库中,宏__HAL_UART_CLEAR_FLAG(__HANDLE__,__FLAG__)也是清除串口中断请求标志位,但该宏只能清除CTS、LIN、TC、RXNE等4个串口中断请求标志位,不能清除IDLE、ORE、NE、FE、PE等几个串口中断请求标志位。3.空闲中断的编程方法空闲中断可以采用中断方式编程,也可以采用查询方式编程,但都需要与RXNE中断一起编程,在实际应用中通常采用查询方式编程。采用查询方式的编程方法是,用变量aRxBuf作串口缓冲器,用来存放RXNE中断发生后串口所接收到的数据;用数组UserRxBuf[]作串口接收缓冲区,用来存放串口所接收到的一批数据;用变量UserRxCnt作接收数据计数器,用来记录所接收的数据个数,这个变量也是新接收到的数据在数组UserRxBuf[]中存放的位置。在RXNE中断中只负责接收数据,并将数据存放在数组UserRxBuf[]中,在应用程序中则查阅IDLE中断请求标志位是否置位,若已置位,则表明空闲中断已发生,就进行接收数据处理,数据处结束后再将IDLE中断请求标志位清0,表示本轮数据处理结束,禁止再进行数据处理。3.空闲中断的编程方法步骤(1)在main()函数的初始化部分的最后用HAL_UART_Receive_IT()函数使能串口接收中断,并指定接收缓冲区和接收数据的长度。(2)在串口接收中断回调函数HAL_UART_RxCpltCallback()中读取串口所接收的数据,并保存至用户串口缓冲区UserRxBuf[]中。(3)在main()函数的while(1)死循环中用__HAL_UART_GET_FLAG()宏读取IDLE中断请求标志,并判断其状态。若为复位状态,则结束串口接收数据处理工作;若为置位状态,则根据应用的需要对UserRxBuf[]中的数据进行对应的处理,处理结束后再用__HAL_UART_CLEAR_IDLEFLAG()宏清除IDLE中断请求标志。3.空闲中断的编程方法12345678910111213141516171819202122232425262728293031#defineUSER_RX_BUF_LEN128uint8_tUserRxCnt=0;/*串口接收计数器*/uint8_tUserRxBuf[USER_RX_BUF_LEN];/*串口接收缓冲区,保存所接收的一批数*/uint8_taRxBuf; /*串口接收缓冲器,存放RXNE中断发生后串口所接收到的数据*//*main()函数*/intmain(void){…/*其他软硬件初始化*/ HAL_UART_Receive_IT(&huart1,&aRxBuf,1);/*使能串口1接收中断,并指定接收缓冲区和接收数据长度*/ while(1) { if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)!=RESET)/*判断是否是空闲中断(IDLE)发生*/ {/*此处添加对接收缓冲区的数据(UserRxBuf[]中的数据)进行处理的代码*/memset(UserRxBuf,0,UserRxCnt);UserRxCnt=0;/*串口接收计数值清0*/__HAL_UART_CLEAR_IDLEFLAG(&huart1);/*清除IDLE中断请求标志*/} …/*其他事务处理*/}}/*串口接收中断回调函数*/voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart){ if(huart==&huart1)//判断是否是串口1 { UserRxBuf[UserRxCnt++]=aRxBuf;//持续接收数据 UserRxCnt%=USER_RX_BUF_LEN;//防超界处理 } HAL_UART_Receive_IT(&huart1,&aRxBuf,1);//使能串口1接收中断,并指定接收缓冲区和接收数据长度}程序的框架结构:函数的用法(1)strstr()函数4.常用的串操作函数原型char*strstr(constchar*str1,constchar*str2);原型的位置string.h文件中功能求串str2在串str1中首次出现的地址。参数1被查找的目标串。参数2str2:所要查找的串。返回值若str2是串str1的子串,则返回str2在str1首次出现的地址。若str2不是str1的子串,则返回NULL。4.常用的串操作函数(2)memset()函数原型void*memset(void*buf,intval,intlen);原型的位置string.h文件中功能将存储区的内容设置成指定值。参数1buf:所要设置存储区的首地址。参数2val:所要设置的值。参数3len:所要设置存储区的长度。返回值函数的返回值为所设置存储区的首地址。函数的用法4.常用的串操作函数(3)strlen()函数原型vunsignedintstrlen(constchar*str);原型的位置string.h文件中功能计算串的长度。参数str:串的首地址。返回值串中的字符个数。函数的用法【举例】语句“len=strlen("STM32");”执行后,len的值为5。(4)sprintf()函数4.常用的串操作函数原型intsprintf(char*buf,constchar*format,[argument]);原型的位置string.h文件中功能将格式化数据保存至指定的缓冲区中。参数1buf:指向存放格式化数据的缓冲区的指针,即缓冲区的首地址。参数2format:格式化字符串。格式化字符串可以是需要原样输出的正常字符串,也可以是以%开头的格式规定字符,如%d、%s、%f、%x等。format参数的用法和要求与printf()函数中的format参数的用法和要求完全相同。函数的用法4.常用的串操作函数(4)sprintf()函数原型intsprintf(char*buf,constchar*format,[argument]);参数3argument:所需输出的参数。该参数是一个可选的系列参数,参数的个数、顺序必须与format参数中的格式规定字符的个数、顺序相同,且各参数之间需用“,”符号分开。argument参数的用法和要求与printf()函数中的argument参数的用法和要求完全相同。返回值若写入成功,则返回实际写入缓冲区的字符个数。若写入失败,则返回-1。函数的用法4.常用的串操作函数【说明】(1)sprintf()函数的功能和用法与printf()函数非常相似,两者的差别是,printf()函数是向标准的输出设备(显示器)输出格式化字符串,而sprintf()函数则是向指定的缓冲区(数组)输出格式化字符串。(2)若程序中使用了sprintf()函数,则需在程序文件的开头处包含头文件stdio.h。(4)sprintf()函数实现方法与步骤与任务9相比,任务10的硬件电路增加了8只发光二极管控制电路,任务10的硬件电路:

1.搭建电路

2.生成硬件初始化代码相对于任务9而言,任务10中增加了PE0~PE7,其初始化代码可在任务9的基础上产生,其生成过程如下:步骤(1)在“D:\ex”文件夹中新建Task10子文件夹。(2)将任务9的STM32CubeMX工程文件Task9.ioc(位于“D:\ex\Task9”文件夹中)复制到Task10文件夹中,并将其改名为Task10.ioc。(3)双击Task10.ioc文件图标,打开任务10的STM32CubeMX工程文件。

2.生成硬件初始化代码步骤(4)按照任务2中介绍的方法将PE0~PE7设置为输出口,输出电平为高电平、推挽输出、无上拉电阻也无下拉电阻、高速输出、无用户标签。(5)保存STM32CubeMX工程文件,然后在工程窗口中点击“GENERATECODE”按钮,STM32CubeMX就会生成任务10的初始化代码。

3.编写数据接收程序本任务中,我们将数据接收程序放在自定义文件Serial.c中步骤(1)在“D:\ex\Task10”文件夹中新建User子文件夹,用来保存用户程序文件。(2)打开“D:\ex\Task10\MDK-ARM”文件夹,然后双击文件夹中的Keil工程文件Task10.uvprojx,打开任务10的Keil工程。若任务10的Keil工程已打开,则跳过此步。

3.编写数据接收程序步骤(3)在Keil工程中新建User工程组,其方法如下:第1步:在“Project”窗口中点击“Project:Task10”前面的“+”号,将工程展开。第2步:用鼠标右键点击“Task10”,在弹出的快捷菜单中点击“AddGroup”菜单项。第3步:分2次用鼠标点击“NewGroup”组名(注意:不是双击),将光标移至组名中,再将组名修改为“User”,然后用鼠标点击窗口的任意地方。3.编写数据接收程序步骤(4)在Keil中新建Serial.c文件和Serial.h文件,并保存至D:\ex\Task10\User文件夹中。(5)在Serial.c文件中定义串口接收缓冲区数组UserRxBuf[]、接收数据计数器UserRxCnt、串口接收缓冲器aRxBuf,并重定义fputc()函数和串口接收中断回调函数HAL_UART_RxCpltCallback()。(6)在Serial.h文件中添加3个全局变量UserRxBuf[]、UserRxCnt、aRxBuf的说明。3.编写数据接收程序步骤(7)将Serial.c文件添加至User组中。其方法如下:第1步:在Project窗口中用鼠标右键点击“User”组名,然后在弹出的菜单中点击如图所示的“AddExistingFilestoGroup‘User’”菜单项,打开如图所示的添加文件对话框。3.编写数据接收程序步骤第2步:在添加文件对话框中点击“文件类型(T)”下拉列表框,从中选择“CSourcefile(*.c)”列表项,再在“查找范围(I)”下拉列表框选择Serial.c文件存放的文件夹“D:\ex\Task10\User”,“查找范围(I)”下面的列表框中就会显示Serial.c文件。第3步:在添加文件对话框中点击Serial.c文件(图中的第3处),对话框的“文件名(N)”文本框中就会出现我们所选择的文件,再点击“Add”按钮,将Serial.c文件添加至User组中,此时User组的前面会出现“+”加号。第4步:关闭添加文件对话框。第5步:在Project窗口中点击“User”组名前的“+”号,就可以看到Serial.c文件位于User组中,表明Serial.c文件添加成功,如图所示。3.编写数据接收程序添加文件对话框文件添加的结果

4.编写数据处理程序将上述代码按照程序编写规范的要求添加至main.c文件的对应处,我们要以发现以下现象:(1)在“#include“Serial.h””语句前有一个“X”符号,将鼠标移至该符号出会出现“fatalerror:‘Serial.h’filenotfound”的提示。main.c文件中的用户应用程序

4.在main.c文件中编写应用程序(2)编译程序时输出窗口中会出现如图所示的错误提示。上述提示的含义是,没找到头文件Serial.h。其原因是,Serial.h文件所在的文件夹“D:\ex\Task10\User”并不是工程的头文件所在文件夹,解决问题的方法是,在任务10的Keil工程中增加Serial.h文件所在的文件夹。main.c文件中的用户应用程序5.增加include目录步骤第1步:在Keil窗口中单击图标工具按钮“

”,打开如图所示OptionsforTarget对话框。第2步:在第一步所示对话框中点击“C/C++”标签,再点击includePaths后面的“

”按钮,打开如图所示的FolderSetup对话框。5.增加include目录步骤第3步:在FolderSetup对话框中点击插入图标按钮“

”,在列表框中插入一个空白行,然后点击空白行后面的“

”按钮,打开如图所示的“选择文件夹”对话框。第4步:在选择文件夹对话框中的地址栏中选择文件夹“D:\ex\Task10”(参考右图),对话框的列表框中就会显示“D:\ex\Task10”文件夹中的内容,然后在列表框中点击“User”文件夹名(图中第2处)再点击“选择文件夹”接钮,返回至第二步所示对话框中。5.增加include目录步骤第5步:在第2步所示对话框中点击“OK”按钮,再返回第1步所示的FolderSetup对话框中。第6步:在FolderSetup对话框中点击“OK”按钮,完成头文件位置的设置。

6.调试与下载程序步骤(1)按照前面任务中介绍的方法编译连接程序,并调试程序直至程序正确无误。(2)将程序下载至开发板中,并运行程序。(3)打开串口调试助手,并按图所示设置好串行通信参数,其中数据按Hex发送。6.调试与下载程序步骤

(4)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论