本文主要介绍利用stm32CubeMX+Keil,在STM32F103C8T6上,尝试使用寄存器地址方式和HAL库这两种方式,实现及串口通信,还涉及到Keil5编译器V5的安装。由于篇幅太长,本篇文章主要介绍实践操作,理论知识写在我之前的一篇帖子 嵌入式系统开发09——串口通信 里。
目录
一、任务要求
安装 stm32CubeMX,配合Keil,分别尝试使用寄存器地址方式(汇编或C,不限) 和HAL库这两种方式,完成下列任务:
1、完成一个STM32的USART串口通讯程序(查询方式即可,暂不要求采用中断方式),要求:
1)设置波特率为115200,1位停止位,无校验位;
2)STM32系统给上位机(win10)连续发送“hello windows!”。win10采用“串口助手”工具接收。
2、在没有示波器条件下,可以使用Keil的软件 仿真逻辑分析仪 功能观察管脚的时序波形,更方便动态跟踪调试和定位代码故障点。 请用此功能观察第1题中串口输出波形,并分析时序状态正确与否,高低电平转换周期实际为多少。
二、环境搭建
1、硬件环境
-
STM32F103C8T6核心板
-
USB转TTL
-
面包板一块
-
杜邦线(公对公、母对母)若干
-
连接方法:
USB转TTL | STM32F103C8T6 |
---|---|
GND | G |
3V3 | 3V3 |
RXD | PA9 |
TXD | PA10 |
注意将核心板上的BOOT0设置为1,BOOT1设置为0
2、软件环境
-
MDK5、stm32CubeMX、虚拟逻辑分析仪的安装与使用可以参考本人的另外两篇帖子。
1、嵌入式系统开发05——MDK5的安装、汇编语言编程入门实践以及Hex文件的分析
2、嵌入式系统开发08——stm32CubeMX+HAL库实现流水灯以及虚拟逻辑分析仪的使用 -
CH340驱动(USB串口驱动)
安装好之后,将 USB转TTL 和 STM32F103C8T6 连接到电脑上后可以看到端口处连接有一个 USB-SERIAL CH340
-
FlyMcu 烧录助手
-
串口通信助手(SSCOM)
三、寄存器方式实现串口通信
1、创建工程
-
可以按照我之前的帖子来创建工程:
嵌入式系统开发05——MDK5的安装、汇编语言编程入门实践以及Hex文件的分析 -
可以直接利用下面的工程模板来建立(建议使用这种方法)
链接:https://pan.baidu.com/s/1TN_MMYkEdkv1R7TAUwIJEw?pwd=plt3
提取码:plt3 -
建立模板之后点击魔术棒,点击 Device,将芯片选择为 STM32F103C8
-
点击 C/C++,将 Define 里面的 STM32F10X_HD 改为 STM32F10X_MD
2、代码编写
- (1)在 SYSTEM 组下双击 usart.c,其中的 uart_init 函数,代码如下
void uart_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<2; //使能PORTA口时钟
RCC->APB2ENR|=1<<14; //使能串口时钟
GPIOA->CRH&=0XFFFFF00F;//IO状态设置
GPIOA->CRH|=0X000008B0;//IO状态设置
RCC->APB2RSTR|=1<<14; //复位串口1
RCC->APB2RSTR&=~(1<<14);//停止复位
//波特率设置
USART1->BRR=mantissa; // 波特率设置
USART1->CR1|=0X200C; //1位停止,无校验位.
#if EN_USART1_RX //如果使能了接收
//使能接收中断
USART1->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(3,3,USART1_IRQn,2);//组2,最低优先级
#endif
}
先计算得到 USART1->BRR 的内容。然后开始初始化串口引脚,然后设置波特率和奇偶校验等。
这里需要注意一点,因为我们使用到了串口的中断接收,必须在 usart.h 里面设置 EN_USART1_RX 为 1(默认设置就是 1 的)。该函数才会配置中断使能,以及开启串口 1 的 NVIC 中断。这里我们把串口 1 中断放在组 2,优先级设置为组 2 里面的最低。
- (2)在 test.c 中编写如下代码
#include "sys.h"
#include "usart.h"
#include "delay.h"
int main(void)
{
u16 t; u16 len; u16 times=0;
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
uart_init(72,115200); //串口波特率初始化为115200
while(1)
{
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3FFF;//得到此次接收到的数据长度
printf("\r\n hello windows! \r\n\r\n");
for(t=0;t<len;t++)
{
USART1->DR=USART_RX_BUF[t]; //发送一个字节到串口,通过直接操作寄存器来实现的
while((USART1->SR&0X40)==0);//等待发送结束
}
printf("\r\n\r\n");//插入换行
USART_RX_STA=0;
}else
{
times++;
if(times%200==0)printf("hello windows!\r\n");
delay_ms(10);
}
}
}
其中 while((USART1->SR&0X40)==0),表示就是我们在写了一个字节在 USART1->DR 之后,要检测这个数据是否已经被发送完成了,通过检测 USART1->SR 的第 6 位,是否为 1 来决定是否可以开始第二个字节的发送。
3、V5编译器安装
这里点击编译,我最开始编译时,会报很多错
这里是以为编译器选择错误,V6编译器无法兼容部分代码
此时应该选择V5编译器,但是当选择 Missing:Compiler Version 5 进行编译时,提示:
这里是因为 KEIl5 新版本,官方不再默认安装V5编译器,需要自己安装V5编译器。安装方法如下:
(1)下载文件
链接:https://pan.baidu.com/s/1hDvFC3oyAPte5H6A9R5CFg?pwd=2022
提取码:2022
(2)解压到 Keil5 的 ARM 文件夹下(这里需要找到自己的 Keil5 的安装路径,我这里显示的是解压后的文件夹内容)
(3)解压完成后,以管理员身份运行Keil5,点击打开 File Extensions, Books and Environment…
(4)选择 Folders/Extensions,点击 …
(5)选择 Add another ARM Compiler Version to List…
(6)选择 ARMCC 的安装路径,点击确定
(7)如下图,我们可以看到,ARMCC 已经添加成功了,点击 Close ->OK
(8)最后回到 Keil5 主界面,打开 Option for target,到这一步,我们就可以选择使用compiler version 5了
4、编译
点击魔术棒,在 Output 下勾选 Create HEX File
在 Debug 下勾选 Use Simulator,将 Dialog DLL:改为DARMSTM.DLL;Parameter:改为 -pSTM32F103C8
否则调试的时候使用虚拟逻辑分析仪观察输出波形时,会提示错误
在 Target 下,将 ARM Compiler:改为 Use default compiler version 5
点击编译,发现编译成功
5、烧录
按照硬件环境部分将硬件连接到电脑串口上,打开 FlyMcu烧录软件
找到生成的 hex 文件,点击打开
搜索串口
设置波特率为115200bps
点击开始编程,进行烧录
6、实现效果
打开串口调试助手 SSCOM,打开串口设置
配置串口设置
点击打开串口
观察结果
用 Keil5 的虚拟逻辑分析仪观察输出波形
四、HAL库方式实现串口通信
1、创建工程
-
打开STM32CubeMX,点击 ACCESS TO MCU SELECTOR
-
选择 STM32F103C8
-
设置RCC,设置高速外部时钟HSE,选择外部时钟源
-
点击 Connectivity,选择 USART1 ,Mode 设置为 Asynchronous(异步通信)
-
波特率为115200,1位停止位,无校验位(这里不需要改,默认就是这样)
-
NVIC Settings 一栏使能接收中断,勾选Enabled
-
时钟设置,将HCLK设置为 72MHz
-
项目设置,设置项目的名称、位置、环境
-
生成项目
2、代码编写
(1)打开工程,点击 Open Project,找到 main.c
(2)在 main.c 中用一个数组存储 STM32 需要给上位机发送的消息
uint8_t data[]="hello windows!\n";
(3)在while循环中调用查询,并调用延时函数
HAL_UART_Transmit(&huart1, (uint8_t *)data, 15, 0xffff);
HAL_Delay(100); //延时100ms
3、编译
点击魔术棒,在 Output下勾选 Create HEX File
在 Target 下将编译器版本改为 V6.18
在Debug里面选择 Use Simulator,将 Dailog DLL设置为DARMSTM.DLL,Parameter设置为-pSTM32F103C8;
点击OK,点击编译
4、烧录
按照硬件环境部分将硬件连接到电脑串口上,打开 FlyMcu烧录软件
找到生成的 hex 文件,点击打开
搜索串口
设置波特率为115200bps
点击开始编程,进行烧录
5、实现效果
打开串口调试助手 SSCOM,打开串口设置
配置串口设置
点击打开串口
观察结果
五、仿真逻辑分析仪的使用
(1)在KEIL5中打开调试
(2)打开逻辑分析仪
(3)添加需要观察的引脚USART1_SR,调为Bit模式,点击关闭
(4)点击Run ,开始运行
(5)分析波形
发送信息时高电平的持续时间为 0.458us
发送信息时低电平的持续时间为 87us
延时100ms
六、总结
本文主要介绍利用stm32CubeMX+Keil,在STM32F103C8T6上,尝试使用寄存器地址方式和HAL库这两种方式,实现串口通信。通过实验发现,stm32CubeMX的可视化操作可以使得寄存器的初始化配置操作变得非常简单、便捷;HAL库函数则封装了许多stm32的常用函数,相较于寄存器方式,HAL库函数stm32的学习和使用更加容易上手。希望能够给各位读者帮助,同时也希望各位读者能够自己尝试去实验,实践是检验真理的唯一标准,只有通过实验才能够真正熟知和掌握知识。若博客中有不足或者缺漏,望各位指出。
参考列表:
1.搭建STM32开发环境——STM32CubeMX,Keil5
2.STM32实现LED闪烁——基于HAL库
3.基于 MDK 创建 STM32 汇编程序:串口输出 Hello world
4.STM32最小核心板F103串口通信USART