本帖最后由 Zhao_kar 于 2023-10-4 20:59 编辑
STM32L476RG第二节——USART的基本使用和printf的使用
开头闲聊:上一节做了一个简单的开箱测评+环境搭建+点灯的报告,然后后续稍微鼓捣了一下,现在进度已经到了oled屏幕点亮,以及usart屏幕点亮,还有hc05的使用,mpu6050的基本驱动,然后我这边因为比较懒得写报告,然后就一直拖到了现在,然后国庆稍微有点时间了,就先从usart的基本使用来写一下,然后后续更新的下一篇是usart的串口屏使用,然后是hc05的驱动,再到oled的显示,最后是mpu6050的数据获取和驱动,这里预告一下内容和进度,后续总体再在最终的项目总报告里面详解。
然后不多废话,先来讲讲串口的基本使用。
一、串口基本概念
1、首先讲一些都要知道的东西,串口这个是一个统称,包含了很多东西,严格来讲这一部分的叫做USART串口通信,说白了就是一种通信接口,都是通信了,自然就是用于在STM32单片机和其他外部设备(比如传感器、显示屏、其他微控制器等)之间进行串行通信。像串口屏,HC05都是串口通信的。
2、简单来说,USART串口是一种用于在两个设备之间传输数据的通信协议,其中数据按照一定的时钟和数据位传输,可以是同步传输(有时钟信号)或异步传输(没有时钟信号)。USART串口通常用于调试、数据传输、设备控制等各种应用。
3、USART串口的一些关键特性包括:
全双工通信: USART串口允许同时发送和接收数据,这意味着可以进行双向通信。
多种传输速率: 可以配置不同的波特率,以控制数据传输速率。
数据格式: 可以配置数据位数、停止位数和校验位以满足不同的通信需求。
多种模式: USART支持异步模式和同步模式,可以根据需要选择合适的模式。
中断和DMA: 可以配置USART串口以生成中断或使用DMA(直接存储器访问)来传输数据,以提高通信效率。
4、USART串口通常用于连接STM32单片机与其他外部设备,以便将数据发送到外部设备或从外部设备接收数据。这种通信可以用于调试、传感器数据采集、与其他微控制器通信等各种应用中。
5、在STM32单片机中,USART串口通常包括多个USART通道,可以选择适合你的应用的通道,并配置其参数以满足通信需求。USART通道是STM32的重要外设,可以通过HAL库或底层驱动程序进行配置和使用。
6、这些都是一些简单描述,想深度了解建议自己查查,包括串口的校验位和时序的内容,这里不多说。
二、HAL库里面的串口函数的解析
1、HAL_UART_Transmit(&huart1, (uint8_t *)aRxBuffer, sizeof(aRxBuffer),0xFFFF);
HAL_UART_Transmit(&huart1, (uint8_t *)aRxBuffer, sizeof(aRxBuffer),0xFFFF);
我这里先把后面要用的函数先拿出来,在stm32的hal库里面,串口就是这么用的,分析这个函数,第一个是指向对应的串口,这里配置的串口1,所以是huart1,然后第二个是数据类型+要发送的数据,比如这一个部分是发送数组arxbuffer,然后sizeof里面就是这个数组的数据长度,至于最后一个其实就是发送操作的超时时间,以毫秒为单位。其中0XFFFF
表示无限等待,即发送操作会一直等待直到完成。
2、HAL_UART_Transmit(&huart1, (uint8_t *)&data1,1,0xFFFF);
HAL_UART_Transmit(&huart1, (uint8_t *)&data1,1,0xFFFF);
这个跟上面那个函数一样的,不一样的地方只是数据长度,这里直接是个1,说明1个字节长度,一个道理。
3、这个实验里面用不到的,但是做串口通信的基本用的上:HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
这个是接收的函数,就比如外部设备的数据通过串口发送给单片机接收,比如手机的蓝牙和一个蓝牙模块HC05蓝牙连接,然后把数据发送给HC05,然后hc05把数据发送给单片机,那么就需要接收。然后补个tips:在主函数里,不要放在while(1)里,自己会不断触发的,一般放在中断回调函数里面。
三、实操1——usart基本使用
1、先说明做什么,这一次先使用单片机的usart,像ch340模块发送数据,然后使用电脑的调试助手接收数据。
2、具体操作顺序如下:
- cubemx配置时钟和下载口,配置usart参数
- keil编写代码
- 连接ch340模块
- 打开调试软件并接收数据
操作:
1、cubemx配置
串口配置
时钟树配置
高速时钟
stlink下载
keil
文件配置
PS:我的照片顺序乱了,一般是RCC到SYS到USART到TIMETREE到后面。
2、keil的代码设置
先在开头做变量的赋值和定义
uint8_t data1=0xAB;
uint8_t data2=6;
uint8_t aRxBuffer[]=" hello\r\n";
这里先不管那个中文的,就看三个数据。
/* USER CODE BEGIN 2 */
//函数里面的uart1是把内容发送到外设串口1
//其中data1前面的是指向变量的指针,用于发送data的内容
//第三个1是数据长度,这里是1个字节
//第四个是发送操作时间,等待时间最大值,即不会超时
//发送数组的同理,只不过使用sizeof把数组的数据长度包含进去了
HAL_UART_Transmit(&huart1, (uint8_t *)&data1,1,0xFFFF);
HAL_UART_Transmit(&huart1, (uint8_t *)&data2,1,0xFFFF);
HAL_UART_Transmit(&huart1, (uint8_t *)aRxBuffer, sizeof(aRxBuffer),0xFFFF);
/* USER CODE END 2 */
然后编译烧录代码,打开串口调试助手,这里用的VOFA+。
可以看到如下的内容,首先是data1定义的AB,然后是data2定义的06,最后是数组,但是这里使用16进制,所以没有看到hello。
解释:为什么是20 68 ... 0D 0A 00
- 'h' 的ASCII码是 104,16进制表示为 0x68。
- 'e' 的ASCII码是 101,16进制表示为 0x65。
- 'l' 的ASCII码是 108,16进制表示为 0x6C。
- 'l' 的ASCII码是 108,16进制表示为 0x6C。
- 'o' 的ASCII码是 111,16进制表示为 0x6F。
- 去看我前面的内容,数组前面有个空格,所以有20,后面两个\r\n,然后字符串有个0很正常吧,所以是这样的,只要把串口助手的接收改一下就行了,如下
然后你就可以正常的看到hello了。
基本的USART的发送就成功了,这里没扔进循环,扔进循环的话会有些其他的要考虑的东西,比如发送速率和上下文问题: 如果你将HAL_UART_Transmit放在一个while
循环内,发送数据的速率可能会更快,因为它会在循环中不断发送数据。这可能导致接收端(串口调试助手)在处理来自串口的大量数据时出现问题。所以,大部分情况下都是使用printf+ch340进行调试。
下面为printf的使用。
四、实操2——usart基本使用+printf
1、基本上cubemx和keil都没什么变化,这里直接照着原工程进行编写,我们需要注意的只有一个东西是keil的usb勾选,如图
2、然后就是代码部分了,这里我们需要打开usart.c的文件,在最下面的begin里面添加如下内容:
#include <stdio.h>
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}
然后主函数里面也别忘记了这个
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */
3、接下来就是printf的使用
这里我只是使用了一个中文的
const char *chineseString = "你好,世界!";
然后在while的里面加这个
HAL_Delay(1000);
printf("%s\n", chineseString);
printf("test2");
这样子就可以正常使用printf了
这里解释一下,直接使用printf打印字符是不可以中文的所以换了一个方式去实现
同时备注一下,调试助手需要utf8,不然你可能看到的中文是乱码或者不正常哦。
结果如下图
五、最后补充
最后补充一下,那个前面的串口配置那里,串口调试助手要同步哦,比如波特率,还有校验位这些东西,这些理论我就不解释了,搜一下就知道了,比如我的配置是
vofa里面对应的就是这个
总结一下,本期是usart的基本使用,下一期就是串口屏的测试,下下期就是HC05,下下下期就是oled,下下下下期是mpu6050的简单驱动(前段时间有些事,做了一直没时间写报告)