此文档作为对洋桃电子STM32F407单片机视频的整理,B站链接:第20集)USART串口功能_哔哩哔哩_bilibili
????????串口通信对于单片机开发非常重要,在开发过程中,我们需要实时了解单片机运行的状态信息,需要一个信息输入输出功能用于调试,最简单的输入输出功能是LED和按键,但所能表示的信息太少。串口通信成为了最理想的调试工具,在电脑上安装超级终端或串口助手软件将单片机运行参数以中英文显示出来,清晰直观,同时可在电脑上用键盘发送信息给单片机,控制单片机的运行状态。
????????STM32F407系列单片机共有6个独立USART串口功能,表格中列出6个串口的功能差异,从名称上看串口编号1 2 3和6是USART,串口编号4和5是UART,带有S的USART表示具有同步模式,不带S的UART表示没有同步模式,UART不支持调制解调、SPI主机、智能卡应用,而USART支持所有功能,另一个区别是USART1和USART6挂接在APB2总线上,最大速度可达84MHz,其他串口挂接在APB1总线上,最大速度可达42MHz。
????????标准的USART串口共占用6个端,分别是TX、RX、SW_RX、nRTS、nCTS、和SCLK,在不同的功能应用之下这些端口有不同的连接方式,但这些功能应用并不常用,最常用的还是基本通信功能中的异步模式,在异步模式下只需要占用TX (发送) 和RX (接收)端口,其他端口不被占用,可以设置为其他功能。
????????USB转串口电路使用了CH340芯片,该芯片将USB接口转换成USART串口通信,使用时M1需要连接到电脑主机的USB接口上,CH340芯片从USB接口转换成USART串口后连接到单片机的PA9和PA10端口。它们复用为USART1端口的TX (发送)和RX (接收) 端口。
在CubeMX中开启串口功能
????????串口模式下拉列表中的可选择模式项,其中异步和同步是标准通信模式。其他模式都是特殊场合的专用模式,由于后续要与电脑端的串口助手通信,所以需要选择“异步”模式。
????????以USART1为例设置串口参数
????????由于CH340芯片内部带有对TXD和RXD接口的上拉电阻,所以单片机在设置USART1端口时只要按默认的无上下拉模式即可。
????????在电路图中CH340芯片与PA9 PA10连接,导致这两个端口不能再当GPIO端口使用,也不能外接其他串口电路。除非将CH340芯片从开发板上拆下来。如果在项目开发中需要外接USART1串口,可以把USART1重映射到PB6和PB7接口上,然后通过板上的排孔来外接其他电路。
????????重映射之后USART1通信将在PB6 PB7上完成,但是单片机程序下载依然使用的是PA9和PA10。
????????在CubeMX中重新生成代码后,打开main.c文件第99行会自动调用USART1的初始化函数。
????????在main.c文件的第164~190行是USART1初始化函数的内容,其中第174~181行是我们在CubeMX中设置的参数,在这里以代码的形式出现。
? ? ? ? 单片机上电运行时,执行到第99行就对USART1完成了初始化设置。
????????CubeMX生成代码的同时,还会将USART1功能的HAL库文件添加到工程文件树,在CubelDE工程文件树中可以找到stm32f4xx_hal_uart.c文件,此文件是单片机内所有USART串口的驱动程序。USART1/2/3/6和UART4/5功能都使用这一个驱动程序,展开文件中内容构成可以看到其中包含了很多HAL开头的库函数。
????????展开文件中内容构成可以看到其中包含了很多HAL开头的库函数,这些函数都可以在main.C文件中被调用,串口的发送与接收有很多种方案,发送数据可使用发送函数DMA功能、printf函数等,接收数据可使用接收函数、DMA功能、中断处理函数等。这一讲先用最基础的发送函数与接收函数。完成最初级的USART串口通信。
????????第一个参数是USART编号的句柄,用取地址符号&加上串口编号,想用USART1发送就写“&huart1”。
????????第二个参数是要发送内容的数组,我们需要先创建一个数组,将要发送的数据放进去,然后把数组名称写在第二个参数这里。
????????第三个参数是数据数量,想发送几个数据就直接写数字,第四个参数是溢出时间,如果发送过程超出溢出时间就认为发送失败,一般写入0xFFFF。
????????在main.C文件中编写一个串口发送程序,在main.c文件的第72行创建一个数组box,数组中有3个字符,注意用单引号表示1 2 3不是数值而是ASCII码的字符1 2 3。只有以字符方式发送在电脑端才能显示字符。
????????在主循环内部添加第102~103行,其中第102行调用串口发送函数,函数的参数表示向USART1串口发送box数组中的3个字符,溢出时间是0xffff。程序内容是每隔1秒向电脑端发送一次数据。
????????串口查询方接收:????????
????????第一个参数是USART编号的句柄。
????????第二个参数是要接收内容的数组。
????????第三个参数是数据数量。
????????第四个参数是溢出时间 一般写入100。
????????在main.c文件中编写一个串口接收程序。
????????在main.c文件的第72行创建一个变量a,用于存放接收状态。
????????第106行调用串口接收函数,函数的参数表示从USART1串口接收1个数据,数据存放到变量a中,溢出时间是100。变量a为0表示没有接收到数据,不为0表示接收到了数据。所以第107行用if判断是否接收到数据,当接收到数据则执行第108行,将变量a中接收到数据发送出去,第109行将变量a的值清0 为下次接收做准备。
????????实验现象:
????????所谓中断方式是开启NVIC中断控制器中的串口中断允许,当串口收到数据 硬件自动产生中断,单片机中止当前运行的程序进入中断处理程序。读出接收寄存器里收到的数据。
????????CubeMX中开启串口接收中断
????????MAIN函数:
????????首先在main.c文件的第32行创建一个数组box,用于存放串口接收的数据,因为每次只接收一个字节,所以数组数量为1,并使数组的初始值为0。此数组是在main函数之外创建的,是全局变量。可以同时被main函数和串口中断回调函数所使用。
????????HAL库中的stm32f4xx_hal_uart.c文件是USART串口功能库函数文件,第2618行是带有“weak”前缀的串口中断回调函数的弱函数。
????????为了程序简单,把串口中断回调函数卸载main函数里面,在main.c文件里添加的中断回调函数要与弱函数同名,在中断回调函数里写入串口数据接收的处理程序。
????????首先第63行用if语句判断中断产生的来源是不是USART1,因为任何一个串口产生中断都会进入串口中断回调函数,所以要判断只有是USART1中断时才进行处理,第64行当USART1中断时则调用串口发送函数,发送内容是box数组中刚刚接收的数据,第65行再次开始串口接收中断,为下一次接收做好准备。
????????需要注意:由于进入串口中断回调函数后会自动关闭串口中断允许,所以如果想反复接收,就要在中断回调函数的最后重新开启接收中断。
????????因为单片机上电启动时串口接收中断默认为关闭状态,所以在main函数初始化时要开启串口1的接收中断,才能在串口收到数据时产生中断触发。在main.c文件第100行添加开启串口接收中断的函数。
????????此行与第65行的内容一样,此函数的第一个参数是串口号的句柄&huart1,第二个参数是串口接收的数据所存放的位置,我们想把中断接收的数据放入box数组,所以这里写box,box前缀(uint8 t*)是强制将接收的数据转换为8位字节数据,第三个参数是一次接收的数据数量,只有当接收到的数量达到时才会触发中断,这里写入数量为1,因为串口接收都在串口中断回调函数完成,所以在第105~111行的主循环程序中没有添加任何程序。
????????实验现象: