第一章 串口硬件引脚分析
STM32F407 的串口资源非常丰富,功能也很强劲。 STM32F407 最多可提供 6 路串口,有分数波特率发生器、支持同步单线通信和半双工单线通讯、支持 LIN、 支持调制解调器操作、 智能卡协议和 IrDA SIR ENDEC 规范、具有 DMA收发功能等,具体详细信息可以查看官方的数据手册。
第二章 串口复用引脚介绍
串口寄存器介绍在手册第26章
GPIO口复用功能引脚配置
F407串口对应的引脚
配置复用功能的寄存器
串口时钟频率配置分析
第三章 串口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!='�')
{
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,"嵌入式开发!rn");
}
if(USART1->SR&1<<5) //接收到数据
{
c=USART1->DR;
USART1->DR=c; //将接收到的数据原路返回
}
}
}
复制代码
第四章 串口标准输入输出重定向
Usart.c文件增加代码:
/*
函数功能:重写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;
}
复制代码
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串口测试!rn");
printf("请输入数据按回车键结束: (串口软件需要勾选发送新行)rn");
scanf("%s",buff);
printf("你输入的数据为:%srnrnrn",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 */
void SetNVICPriorityGrouping(IRQn_Type IRQn,uint32_t PreemptPriority, uint32_t SubPriority);
#endif
复制代码
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!='�')
{
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;
}
}
复制代码
审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
寄存器
+关注
关注
31文章
5308浏览量
119975 -
STM32F407
+关注
关注
15文章
187浏览量
29364 -
串口配置
+关注
关注
0文章
5浏览量
1609
发布评论请先 登录
相关推荐
【STM32F407开发板用户手册】第13章 STM32F407启动过程详解
【STM32F407开发板用户手册】第13章 STM32F407启动过程详解
发表于 11-23 18:06
•73次下载
【STM32F407开发板用户手册】第14章 STM32F407的电源,复位和时钟系统
【STM32F407开发板用户手册】第14章 STM32F407的电源,复位和时钟系统
发表于 12-02 16:21
•42次下载
【STM32F407开发板用户手册】第1章 初学STM32F407的准备工作
【STM32F407开发板用户手册】第1章 初学STM32F407的准备工作
发表于 12-04 13:36
•75次下载
【STM32F407开发板用户手册】第21章 STM32F407的NVIC中断分组和配置(重要)
【STM32F407开发板用户手册】第21章 STM32F407的NVIC中断分组和配置(重要)
发表于 12-04 13:51
•21次下载
【STM32F407开发板用户手册】第8章 STM32F407的终极调试组件Event Recorder
【STM32F407开发板用户手册】第8章 STM32F407的终极调试组件Event Recorder
发表于 12-04 14:21
•19次下载
【STM32F407开发板用户手册】第19章 STM32F407的GPIO应用之按键FIFO
【STM32F407开发板用户手册】第19章 STM32F407的GPIO应用之按键FIFO
发表于 12-05 15:21
•39次下载
STM32F407入门开发: 位带操作
STM32F407的位带操作可以实现类似51单片机中寄存器的操作方法,操作GPIO口代码简洁方便。 关于位段的操作在Cortex-M3M4权威指南里有详细描述:
评论