STM32F407 串口配置步骤

发布者:Enchanted2023最新更新时间:2024-08-09 来源: elecfans关键字:STM32F407  串口  配置步骤 手机看文章 扫描二维码
随时随地手机看文章

介绍STM32F407串口配置步骤,完成串口的数据发送与接收、实现中断接收,支持printf重定向。


STM32F407 串口配置说明

STM32F4 的串口资源相当丰富的,功能也相当强劲,STM32F407ZGT6 最多可提供 6 路串口,有分数波特率发生器、支持同步单线通信和半双工单线通讯、支持 LIN、 支持调制解调器操作、 智能卡协议和 IrDA SIR ENDEC 规范、具有 DMA 等。


【1】串口硬件引脚分析

img

img

img

【2】串口复用引脚介绍

串口寄存器介绍在手册第26章

img

GPIO口复用功能引脚配置

img

img

F407串口对应的引脚

img

配置复用功能的寄存器

img

串口时钟频率配置分析

img

【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;

 }

 }

img


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

[1] [2]
关键字:STM32F407  串口  配置步骤 引用地址:STM32F407 串口配置步骤

上一篇:基于STM32的小功率逆变器解决方案
下一篇:STM32速成笔记(13)—低功耗模式

推荐阅读最新更新时间:2026-03-20 11:34

STM32F407 GPIO口输出配置配置步骤
STM32F407ZGT6 是意法半导体(STMicroelectronics)公司推出的一款高性能ARM Cortex-M4核心的32位微控制器(MCU)。它是 STM32F4 系列的一员,具备强大的处理能力和丰富的外设功能,适用于各种应用领域。 【1】F407建工程所需依赖文件 【2】 新建工程 **说明:STM32F4 的主频最高是 168Mhz,所以我们一般设置 PLLCLK 为 168Mhz(M=8,N=336,P=2),通过 SW 选择 SYSCLK=PLLCLK即可得到 168Mhz 的系统运行频率。** 【3】分析LED硬件原理图 【4】编写L
[单片机]
<font color='red'>STM32F407</font> GPIO口输出<font color='red'>配置</font><font color='red'>配置</font><font color='red'>步骤</font>
stm32——串口配置一般步骤
1、串口时钟使能,GPIO时钟使能: RCC_APB2PeriphClockCmd() 2、串口复位 USART_DeInit(); ——非必需 3、GPIO端口模式设置 GPIO_Init(); ——模式设置为GPIO_Mode_AF_PP 4、串口参数初始化 USART_Init(); 5、开启中断并初始化NVIC(当开启中断的时候才需要这个步骤) NVIC_Init(); USART_ITConfig(); 6、使能串口 USART_Cmd(); 7、编写中断处理函数 USARTx_IRQHandler(); 8、串口数据收发 void USART_SendDa
[单片机]
stm32f407串口通信使用流程
初始化 1.定义初始化变量 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; 2.使能时钟 GPIO开启AHB1时钟 USART1开启APB2时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟 3.配置GPIO端口为引脚复用USA
[单片机]
STM32F407——串口显示跑马灯状态
#main.c #include sys.h #include delay.h #include usart.h #include led.h //#include beep.h //#include key.h #include exti.h extern u8 onoff,dir,speed,change,flag; extern u16 time; int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断分组 delay_init(168); //初始化延时函数 LED_In
[单片机]
<font color='red'>STM32F407</font>——<font color='red'>串口</font>显示跑马灯状态
STM32F407 Hal库 串口使用指南
首先,当然是在Cube中进行相应的配置,这个就不多讲了。 之后,在生成的工程中,找到main函数,在/* USER CODE BEGIN 2 */下加入 HAL_UART_Receive_IT(&huart1,Uart1_Data_buffer,n); 这是要给接收到的数据定向,存在Uart_Data_buffer 中。上面函数的第三个参数应该是收到n个字节就触发中断。 然后,在stm32f4xx_it.c的最后面,也就是/* USER CODE BEGIN 1 */下编写 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { 。。。
[单片机]
STM32F407使用USB作虚拟串口出现黄感叹号
最近因为工作需要使用到了STM32F407VET6的USB_OTG_FS作为虚拟串口。 之前用STM32 CubeMX生成过STM32F103C8T6的虚拟串口代码,感觉用起来很方便,于是这次的F407也用MX生产工程,奈何竟然遇到诸多难题,整整困扰了两天。 先说一下我的流程。 MX生成F407 USB虚拟串口工程操作流程 1,选择芯片 先是利用条件筛选选择自己的芯片,如下图: 2,配置管脚 配置RCC输入脚,SYS调试口以及USB_OTG_FS,USB_OTG_FS– Device Only– Comunication Device Class,个人喜欢使用FreeRTOS。配置如下图: 3,配置时钟 用的8M外部晶
[单片机]
STM32F407串口采用DMA收发数据
环境: 主机:WIN8 开发环境:MDK5.13 mcu: stm32f407VGT6 说明: 之前用STM32F103实现DMA收发串口数据,现在项目中采用STM32F407,所以将此机制移植到F4上。 STM32F103上用DMA收发串口数据文章: STM32的串口采用DMA方式发送数据测试 STM32的串口采用DMA方式接收数据测试 源代码: 串口初始化代码: /* * 初始化串口 / static void init_uart(void) { //定义中断结构体 NVIC_InitTypeDef NVIC_InitStructure ; //定义IO初始化结构体 GPIO_Init
[单片机]
stm32f407(cortex-M4)USART串口调试程序
上文通过调试TIM1遇到了一些问题,深入了解了stm32F407的复用功能。网上流传的很多资料都是cortex-M3的,现在都M4了,观念自然得跟上,一味照搬没有自己的思考是不行的。记得我最早的调试的程序就是串口USART,刚入手嘛,就网上找了个例程,例程对IO复用是这么写的: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1, ENABLE); //打开复用时钟 GPIO_StructInit(&GPIO_InitStructure); GPIO_Init
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved