STM32F407 串口配置步骤
2024-08-09 来源:elecfans
介绍STM32F407串口配置步骤,完成串口的数据发送与接收、实现中断接收,支持printf重定向。
STM32F407 串口配置说明
STM32F4 的串口资源相当丰富的,功能也相当强劲,STM32F407ZGT6 最多可提供 6 路串口,有分数波特率发生器、支持同步单线通信和半双工单线通讯、支持 LIN、 支持调制解调器操作、 智能卡协议和 IrDA SIR ENDEC 规范、具有 DMA 等。
【1】串口硬件引脚分析



【2】串口复用引脚介绍
串口寄存器介绍在手册第26章

GPIO口复用功能引脚配置


F407串口对应的引脚

配置复用功能的寄存器

串口时钟频率配置分析

【3】串口1配置示例
Usart.c代码示例:
#include 'usart.h'
/*
函数功能:串口1初始化
函数形参:
u32 clock :时钟频率(默认*1000000HZ) 注意:APB1最大时钟频率为42MHZ APB2最大时钟频率为84MHZ
u32 baud :波特率
硬件连接:
PA9--- >TX
PA10-- >RX
*/
void USART1_Init(u32 clock,u32 baud)
{
/*1. 开时钟*/
RCC- >AHB1ENR|=1< < 0;//使能PORTA时钟
RCC- >APB2ENR|=1< < 4;//使能USART1时钟
/*2. 复位串口时钟*/
RCC- >APB2RSTR|=1< < 4; //使能USART1复位时钟
RCC- >APB2RSTR&=~(1< < 4); //关闭USART1复位时钟
/*3. 配置GPIO口模式*/
GPIOA- >MODER&=~(0x3< < 9*2); //清除模式
GPIOA- >MODER|=0x2< < 9*2; //配置复用功能模式
GPIOA- >MODER&=~(0x3< < 10*2); //清除模式
GPIOA- >MODER|=0x2< < 10*2; //配置复用功能模式
GPIOA- >OTYPER&=~(0x1< < 9); //0表示推挽输出
GPIOA- >OSPEEDR&=~(0x3< < 9*2); //清除之前配置
GPIOA- >OSPEEDR|=0x2< < 9*2; //50MHZ输出速度
GPIOA- >PUPDR&=~(0x3< < 10*2); //清除之前配置
GPIOA- >PUPDR|=0x1< < 10*2; //配置上拉
GPIOA- >AFR[1]&=~(0xF< < 4*1); //清除PA9配置
GPIOA- >AFR[1]|=0x7< < 4*1; //配置PA9复用功能模式为串口1
GPIOA- >AFR[1]&=~(0xF< < 4*2); //清除PA10配置
GPIOA- >AFR[1]|=0x7< < 4*2; //配置PA10复用功能模式为串口1
/*4. 配置USART-CR寄存器*/
USART1- >BRR=(clock*1000000)/baud;//配置波特率
USART1- >CR1|=1< < 3; //使能发送
USART1- >CR1|=1< < 2; //使能接收,并开始搜寻RX引脚上的起始位
USART1- >CR1|=1< < 13; //USART模块使能。
}
/*
函数功能:串口字符串发送
函数形参:
USART_TypeDef *USARTx :串口的类型 (USART1 USART2 USART3)
u8 *str:将要发送的字符串
*/
void USARTxSendString(USART_TypeDef *USARTx,u8 *str)
{
while(*str!='\0')
{
USARTx- >DR=*str;
while(!(USARTx- >SR&1< < 7)){} //等待发送完成
str++;
}
}
Usart.h代码示例
#ifndef USART_H
#define USART_H
#include 'stm32f4xx.h'
void USART1_Init(u32 clock,u32 baud);
void USARTxSendString(USART_TypeDef *USARTx,u8 *str);
#endif
Main.c代码示例
#include 'stm32f4xx.h' // Device header
#include 'led.h'
#include 'delay.h'
#include 'key.h'
#include 'usart.h'
int main(void)
{
u8 key,i,c;
LED_Init();
KEY_Init();
USART1_Init(84,115200);
while(1)
{
key=ScanKeyVal(0);
if(key)
{
i=!i;
LED0(i);
LED1(i);
USARTxSendString(USART1,'万邦易嵌嵌入式开发!\r\n');
}
if(USART1- >SR&1< < 5) //接收到数据
{
c=USART1- >DR;
USART1- >DR=c; //将接收到的数据原路返回
}
}
}
【4】串口标准输入输出重定向
Usart.c文件增加代码:
#include 'usart.h'
/*
函数功能:串口1初始化
函数形参:
u32 clock :时钟频率(默认*1000000HZ) 注意:APB1最大时钟频率为42MHZ APB2最大时钟频率为84MHZ
u32 baud :波特率
硬件连接:
PA9--- >TX
PA10-- >RX
*/
void USART1_Init(u32 clock,u32 baud)
{
/*1. 开时钟*/
RCC- >AHB1ENR|=1< < 0;//使能PORTA时钟
RCC- >APB2ENR|=1< < 4;//使能USART1时钟
/*2. 复位串口时钟*/
RCC- >APB2RSTR|=1< < 4; //使能USART1复位时钟
RCC- >APB2RSTR&=~(1< < 4); //关闭USART1复位时钟
/*3. 配置GPIO口模式*/
GPIOA- >MODER&=~(0x3< < 9*2); //清除模式
GPIOA- >MODER|=0x2< < 9*2; //配置复用功能模式
GPIOA- >MODER&=~(0x3< < 10*2); //清除模式
GPIOA- >MODER|=0x2< < 10*2; //配置复用功能模式
GPIOA- >OTYPER&=~(0x1< < 9); //0表示推挽输出
GPIOA- >OSPEEDR&=~(0x3< < 9*2); //清除之前配置
GPIOA- >OSPEEDR|=0x2< < 9*2; //50MHZ输出速度
GPIOA- >PUPDR&=~(0x3< < 10*2); //清除之前配置
GPIOA- >PUPDR|=0x1< < 10*2; //配置上拉
GPIOA- >AFR[1]&=~(0xF< < 4*1); //清除PA9配置
GPIOA- >AFR[1]|=0x7< < 4*1; //配置PA9复用功能模式为串口1
GPIOA- >AFR[1]&=~(0xF< < 4*2); //清除PA10配置
GPIOA- >AFR[1]|=0x7< < 4*2; //配置PA10复用功能模式为串口1
/*4. 配置USART-CR寄存器*/
USART1- >BRR=(clock*1000000)/baud;//配置波特率
USART1- >CR1|=1< < 3; //使能发送
#ifdef USART1_INTERRUPT
USART1- >CR1|=1< < 5; //开启串口接收中断
SetNVICPriorityGrouping(USART1_IRQn,1,3); //设置中断优先级
#endif
USART1- >CR1|=1< < 2; //使能接收,并开始搜寻RX引脚上的起始位
USART1- >CR1|=1< < 13; //USART模块使能。
}
/*
函数功能:串口字符串发送
函数形参:
USART_TypeDef *USARTx :串口的类型 (USART1 USART2 USART3)
u8 *str:将要发送的字符串
*/
void USARTxSendString(USART_TypeDef *USARTx,u8 *str)
{
while(*str!='\0')
{
USARTx- >DR=*str;
while(!(USARTx- >SR&1< < 7)){} //等待发送完成
str++;
}
}
/*
函数功能:重写printf底层函数接口
*/
int fputc(int c,FILE *stream)
{
USART1- >DR=c; //发送一个字符
while(!(USART1- >SR&1< < 7)){}
return c;
}
/*
函数功能:重新scanf底层函数接口
*/
int fgetc(FILE *stream)
{
while(!(USART1- >SR&1< < 5)){}
return USART1- >DR;
}
/*
函数功能:串口1的中断服务函数
*/
void USART1_IRQHandler(void)
{
u8 data;
if(USART1- >SR&1< < 5)
{
data=USART1- >DR;
USART1- >DR=data;
}
}

Main.c代码示例
#include 'stm32f4xx.h' // Device header
#include 'led.h'
#include 'delay.h'
#include 'key.h'
#include 'usart.h'
int main(void)
{
u8 i;
u8 buff[100];
LED_Init();
KEY_Init();
USART1_Init(84,115200);
while(1)
{
i=!i;
LED0(i);
LED1(i);
printf('STM32F407串口测试!\r\n');
printf('请输入数据按回车键结束: (串口软件需要勾选发送新行)\r\n');
scanf('%s',buff);
printf('你输入的数据为:%s\r\n\r\n\r\n',buff);
}
}
第一步需要先编写设置中断优先级的函数:
sys.c代码示例
#include 'sys.h'
/*
函数功能:设置NVIC中断控制器优先级
函数形参:
IRQn_Type IRQn:中断线
uint32_t PreemptPriority:抢占优先级
uint32_t SubPriority:次优先级
*/
void SetNVICPriorityGrouping(IRQn_Type IRQn,uint32_t PreemptPriority, uint32_t SubPriority)
{
uint32_t Priority;
NVIC_SetPriorityGrouping(NVIC_PriorityGroup_2); //设置优先级分组,每个工程只能设置一次
Priority=NVIC_EncodePriority(NVIC_PriorityGroup_2,PreemptPriority,SubPriority); //编码优先级
NVIC_SetPriority(IRQn,Priority); //设置优先级
NVIC_EnableIRQ(IRQn);
}
Sys.h文件代码示例:
#ifndef _SYS_H
#define _SYS_H
#include 'stm32f4xx.h'
/*中断控制器分组*/
#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority
4 bits for subpriority */
#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority
3 bits for subpriority */
#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority
2 bits for subpriority */
#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority
1 bits for subpriority */
#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority
0 bits for subpriority */
/**
@code
The table below gives the allowed values of the pre-emption priority and subpriority according
to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function
============================================================================================================================
NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description
============================================================================================================================
NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority
| | | 4 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority
| | | 3 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority
| | | 2 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority
| | | 1 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority
| | | 0 bits for subpriority
============================================================================================================================
@endcode
*/
void SetNVICPriorityGrouping(IRQn_Type IRQn,uint32_t PreemptPriority, uint32_t SubPriority);
#endif
Usart.c文件示例
- [STM32F407系列学习]按键开关控制单个数码管加减计数
- STM32F407 ADC 模式详解:单次转换、连续转换、扫描模式、非扫描模式
- STM32F407 ------ 使用定时器实现精确延时
- stm32f103和stm32f407的GPIO口模式设置以及相互对应的关系
- SPI 串行Flash闪存W25Q128FV 的使用(STM32F407)_硬件篇
- SPI 串行Flash闪存W25Q128FV 的使用(STM32F407)_基础篇
- freeRTOS V10.0.1移植到STM32F407标准库 - 环境Keil5
- 基于STM32F407和OV7670的低端视频监控系统
- STM32F407工程移植--STM32F401,F400
- 在stm32f407上移植openharmony遇到的问题
- 六大全新产品系列推出,MCX A微控制器家族迎来创新
- 意法半导体全新STM32C5系列,重新定义入门级微控制器性能与价值,赋能万千智能设备
- 从控制到系统:TI利用边缘AI重塑嵌入式MCU的边界
- 模组复用与整机重测在SRRC、CCC、CTA/NAL认证中的实践操作指南
- 有源晶振与无源晶振的六大区别详解
- 英飞凌持续巩固全球微控制器市场领导地位
- 使用 Keil Studio for Visual Studio Code开发 STM32 设备
- 蓝牙信道探测技术原理与开发套件实践
- LoRa、LoRaWAN、NB-IoT与4G DTU技术对比及工业无线方案选型分析
- Microchip 推出生产就绪型全栈边缘 AI 解决方案,赋能MCU和MPU实现 智能实时决策
- 【雅特力AT32WB415系列蓝牙BLE 5.0 MCU测评】——by KING_阿飞
- [极海M3内核 APM32E103VET6S MINI开发板]——by xld0932
- 电容这段走线影响这么大?
- Keil MDK中文件的星号代表什么意思?
- 免费申请|MPS 具有内部自动补偿功能的5A、16V、四通道输出【降压电源模块评估板】
- “杨过”3天笔记
- 免费申请|MPS 20V、19A、600kHz、宽输入同步升压变换器评估板
- [ ST NUCLEO-U575ZI-Q 测评] 第N种闪灯-TIM1定时器实现
- 数据统计、回归方程、曲线拟合
- 今日直播:魏德米勒 OMNIMATE® 联接技术的创新发展




