STM32F407 串口通信实验 第26节 个人笔记

前言

这篇笔记对应正点原子STM32F407探索者 ,教学视频第26节,网址如下:
https://ke.qq.com/webcourse/index.html#cid=279403&term_id=100330877&taid=1965424279569259&vid=u14245plf1d
这段代码在提供的源码里是没有的,后来有没有在公众号更新我就没注意了。最初版本的源码里确实没有这一篇。

GPIO引脚复用配置

详见 https://www.cnblogs.com/YuQiao0303/p/10011599.html
配置好时钟、gpio的复用映射、gpio

串口配置

常用的usart相关寄存器

USART_SR状态寄存器
USART_DR数据寄存器
USART_BRR波特率寄存器

串口通信编程一般步骤

①串口时钟使能:RCC_APBxPeriphClockCmd();
GPIO时钟使能:RCC_AHB1PeriphClockCmd();
② 引脚复用映射:GPIO_PinAFConfig();
③GPIO端口模式设置:GPIO_Init(); 模式设置为GPIO_Mode_AF
④串口参数初始化:USART_Init();
⑤开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)

NVIC_Init();
USART_ITConfig();

⑥使能串口:USART_Cmd();
⑦编写中断处理函数:USARTx_IRQHandler();
⑧串口数据收发:

void USART_SendData();//发送数据到串口,DR
uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据

⑨串口传输状态获取:

FlagStatus  USART_GetFlagStatus();
void USART_ClearITPendingBit();

完整代码

之前一直没有效果,又回头学习在线调试。
又在中断服务函数中,加了led和蜂鸣器指示,发现是可以进入中断服务函数的,只是发送和接受数据有问题,接受不到数据
最后检查串口初始化的各个参数,才发现把波特率115200写作了11520,缺了一个0
改完后就对了!

#include "stm32f4xx.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "beep.h"

//ALIENTEK 探索者STM32F407开发板 实验0
//STM32F4工程模板-库函数版本
//技术支持:www.openedv.com
//淘宝店铺:http://eboard.taobao.com
//广州市星翼电子科技有限公司  
//作者:正点原子 @ALIENTEK


void My_USART1_Init(void)
{
	//0. 初始化结构体声明
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	//1. 串口和gpio时钟使能
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
	
	//2. gpio复用映射设置
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
	
	//3. GPIO初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;//LED0和LED1对应IO口
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//AF模式
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
	
	//4. USART初始化
	USART_InitStructure.USART_BaudRate=115200;
	USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
	USART_InitStructure.USART_Parity=USART_Parity_No;
	USART_InitStructure.USART_StopBits=USART_StopBits_1;
	USART_InitStructure.USART_WordLength=USART_WordLength_8b;
	USART_Init(USART1,&USART_InitStructure); 
		
	//5.串口使能
	USART_Cmd(USART1,ENABLE);
	
	//如果还要用中断
	//6.串口1的接受非空中断使能
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);    //使能   串口1在接收非空时产生的  中断
	//7.中断初始化
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
}

void USART1_IRQHandler(void)    //中断服务函数的名称在启动文件CORE  setup_stm32f40_41xx.s 中定义
{
	u8 res;
	if(USART_GetITStatus(USART1,USART_IT_RXNE)){    //该项目中我们只使能了一个中断:USART_IT_RXNE
		LED0 = 0;             //红灯亮作为指示
		//BEEP = 1;
		res = USART_ReceiveData(USART1);            //其他项目中我们很可能使能了多个不同的中断
		USART_SendData(USART1,res);                 //所以通常要用 USART_GetITStatus(USART1,USART_IT_RXNE)判断一下到底是哪个中断发生了
	
	}
}
int main(void)
{
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	My_USART1_Init();
	BEEP_Init();
	LED_Init();
	LED1 = 0;     //绿灯是指示灯,常量表示程序正在工作
	LED0 = 1;     //红灯默认是灭的
	BEEP = 0;
	
	while(1);
}



原文地址:https://www.cnblogs.com/YuQiao0303/p/10019362.html