串口中断(stm32f407)

#include "stm32f4xx.h"  

void LED_Init(void)
{
	GPIO_InitTypeDef   GPIO_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
	
	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_OUT;			//输出模式
	GPIO_InitStructure.GPIO_OType	= GPIO_OType_PP;			//推挽输出
	GPIO_InitStructure.GPIO_Speed	= GPIO_Speed_100MHz;		//输出速率
	GPIO_InitStructure.GPIO_PuPd 	= GPIO_PuPd_NOPULL;			//无上下拉
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_9;				//引脚编号
	GPIO_Init(GPIOF, &GPIO_InitStructure);
	
	GPIO_SetBits(GPIOF,GPIO_Pin_9); //默认不亮
}


void EXTI0_Init(void)
{
	EXTI_InitTypeDef   EXTI_InitStructure;
	GPIO_InitTypeDef   GPIO_InitStructure;
	NVIC_InitTypeDef   NVIC_InitStructure;

	/* Enable GPIOA clock  打开GPIOA外设时钟*/
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	/* Enable SYSCFG clock 打开SYSCFG外设时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

	/* Configure PA0 pin as input floating 配置PA0引脚*/
	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_IN;				//输入模式
	GPIO_InitStructure.GPIO_PuPd 	= GPIO_PuPd_NOPULL;			//无上下拉
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_0;				//引脚编号
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	/* Connect EXTI Line0 to PA0 pin GPIO引脚和外部中断线建立映射关系*/
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

	/* Configure EXTI Line0 配置外部中断线*/
	EXTI_InitStructure.EXTI_Line 	= EXTI_Line0;				//外部中断线0
	EXTI_InitStructure.EXTI_Mode 	= EXTI_Mode_Interrupt;		//中断模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  	//下降沿触发
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;					//使能外部中断线0
	EXTI_Init(&EXTI_InitStructure);

	/* Enable and set EXTI Line0 Interrupt 配置中断优先级*/
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;			//中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;		//响应优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//使能通道
	NVIC_Init(&NVIC_InitStructure);	

}

//串口1的初始化
void USART1_Init(uint16_t  baud)
{
	GPIO_InitTypeDef   GPIO_InitStructure;
	NVIC_InitTypeDef   NVIC_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	
	//1.打开USRAT1外设时钟 + GPIOA外设时钟  PA9-U1_TX  PA10-U1_RX
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	
	//2.配置GPIO引脚 PA9 PA10  引脚模式需要设置为复用模式
	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_AF;				//复用模式
	GPIO_InitStructure.GPIO_PuPd 	= GPIO_PuPd_NOPULL;			//无上下拉
	GPIO_InitStructure.GPIO_OType 	= GPIO_OType_PP;			//推挽输出
	GPIO_InitStructure.GPIO_Speed	= GPIO_Speed_100MHz;		//引脚速率	
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_9|GPIO_Pin_10;	//引脚编号
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//3.把GPIO引脚的功能进行复用  复用为USART1  需要调用两次
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
	
	//4.配置USART1  波特率  停止位  数据位  校验位
	USART_InitStructure.USART_BaudRate = baud;						//波特率  9600bps
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;		//数据位  8bit
	USART_InitStructure.USART_StopBits = USART_StopBits_1;			//停止位  1bit
	USART_InitStructure.USART_Parity = USART_Parity_No;				//校验位  无
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
	USART_Init(USART1,&USART_InitStructure);
	
	//5.指定USART1的中断源  接收到数据就发生中断
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
	//6.配置NVIC 指定中断通道+中断优先级
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;			//中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;		//响应优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//使能通道
	NVIC_Init(&NVIC_InitStructure);	
	
	//7.打开串口
	USART_Cmd(USART1,ENABLE);
}


int main()
{
	//1.硬件初始化
	USART1_Init(9600);
	
	//2.进入死循环
	while(1)
	{
		
		
	}
}

//中断服务函数  不需要手动调用   尽量精简(尽量不要添加很长的延时)
void USART1_IRQHandler(void)
{
	uint16_t recv_data = 0;
	//检测中断是否发生
	if( USART_GetITStatus(USART1,USART_IT_RXNE) != RESET )
	{
		USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中断标志
		
		recv_data = USART_ReceiveData(USART1); //把接收到的数据保存到变量中
		
		USART_SendData(USART1,recv_data); //把收到的数据发送
		while( USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET ); //等待数据发送完成	
	}
}

猜你喜欢

转载自blog.csdn.net/qq_15267341/article/details/132783770