0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

STM32F407 串口配置步骤

DS小龙哥-嵌入式技术 来源:DS小龙哥-嵌入式技术 作者:DS小龙哥-嵌入式技 2023-07-06 14:29 次阅读

介绍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
   ----------------------------------------------------------------------------------------------------------------------------
    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文件示例
审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 通信
    +关注

    关注

    18

    文章

    6024

    浏览量

    135950
  • 中断
    +关注

    关注

    5

    文章

    898

    浏览量

    41470
  • 串口
    +关注

    关注

    14

    文章

    1551

    浏览量

    76425
  • STM32F407
    +关注

    关注

    15

    文章

    187

    浏览量

    29437
  • Printf
    +关注

    关注

    0

    文章

    83

    浏览量

    13649
收藏 人收藏

    评论

    相关推荐

    STM32F407 GPIO口输入配置配置步骤

    介绍STM32F407新建寄存器工程流程,介绍输入模式的配置方式,以按键为例完成按键输入检测。
    的头像 发表于 07-06 14:28 2256次阅读
    <b class='flag-5'>STM32F407</b> GPIO口输入<b class='flag-5'>配置</b><b class='flag-5'>配置</b><b class='flag-5'>步骤</b>

    STM32F407 位带配置步骤

    介绍STM32F407位带操作方法,设置寄存器的偏移量,实现按GPIO口指定位进行读写操作,方便编程。
    的头像 发表于 07-06 14:30 1217次阅读
    <b class='flag-5'>STM32F407</b> 位带<b class='flag-5'>配置</b><b class='flag-5'>步骤</b>

    STM32F407 外部中断配置步骤

    介绍STM32F407外部中断配置步骤,以按键为例,实现外部中断配置,使用按键触发中断进行LED灯控制。
    的头像 发表于 07-06 14:31 1958次阅读
    <b class='flag-5'>STM32F407</b> 外部中断<b class='flag-5'>配置</b><b class='flag-5'>步骤</b>

    stm32f407串口通信的代码

    stm32f407串口通信的代码 原理图还有封装 很清楚自己画的
    发表于 03-21 17:22 0次下载

    STM32F407串口采用DMA收发数据

    STM32F407串口采用DMA收发数据调试可用!
    发表于 06-17 16:00 60次下载

    STM32F407模板

    STM32F407模板,感兴趣可以看看。
    发表于 07-25 18:52 133次下载

    STM32F407 UCOS III实验

    STM32F407 UCOS III实验,介绍基于STM32F407的UCOSIII实例,参考下
    发表于 09-22 14:08 82次下载

    STM32CubeMX 配置STM32F407 实现HAL库延时微妙方案

    STM32CubeMX 配置STM32F407 实现HAL库延时微妙方案
    发表于 11-24 20:51 20次下载
    <b class='flag-5'>STM32</b>CubeMX <b class='flag-5'>配置</b><b class='flag-5'>STM32F407</b> 实现HAL库延时微妙方案

    STM32F407串口UART 基础配置STM32CubeMX

    STM32F407串口UART 基础配置STM32CubeMX
    发表于 11-29 16:06 55次下载
    <b class='flag-5'>STM32F407</b>的<b class='flag-5'>串口</b>UART 基础<b class='flag-5'>配置</b><b class='flag-5'>STM32</b>CubeMX

    STM32F407STM32F105 CAN通讯失败的定位解决

    STM32F407STM32F105的CAN通讯失败问题,经过一系列的测试分析,发现并解决问题,实现正常的CAN通讯。问题的现象STM32F407 板上安装25MHz晶体,作为HSE时钟,内部
    发表于 12-02 16:51 18次下载
    <b class='flag-5'>STM32F407</b>与<b class='flag-5'>STM32F</b>105 CAN通讯失败的定位解决

    STM32F407开发板用户手册】第21章 STM32F407的NVIC中断分组和配置(重要)

    STM32F407开发板用户手册】第21章 STM32F407的NVIC中断分组和配置(重要)
    发表于 12-04 13:51 21次下载
    【<b class='flag-5'>STM32F407</b>开发板用户手册】第21章 <b class='flag-5'>STM32F407</b>的NVIC中断分组和<b class='flag-5'>配置</b>(重要)

    STM32F407引脚资源总结

    STM32F407引脚资源总结定时器 串口 ADC
    发表于 12-27 18:54 96次下载
    <b class='flag-5'>STM32F407</b>引脚资源总结

    STM32F407原理图下载

    STM32F407原理图下载
    发表于 01-17 13:44 422次下载

    STM32F407入门开发: 串口配置

    STM32F407串口资源非常丰富,功能也很强劲。 STM32F407 最多可提供 6 路串口,有分数波特率发生器、支持同步单线通信和半双工单线通讯、支持 LIN、 支持调制解调器
    的头像 发表于 05-28 13:51 1.1w次阅读
    <b class='flag-5'>STM32F407</b>入门开发: <b class='flag-5'>串口</b><b class='flag-5'>配置</b>

    stm32f407原理图

    stm32f407原理图
    发表于 07-14 16:07 207次下载