4-STM32F1 串口通讯-中断方式

STM32F1 串口通讯-中断方式

本实验是在上个实验《STM32F1 串口通讯-查询方式》的基础上作的,因此这里只总结增长的中断的部分,串口IO和串口初始化和上个实验同样。
增长的步骤
1,在主函数中进行中断分组
2,在使能串口前配置串口中断,
3,使能串口中断后再使能串口
4,编写串口中断函数
5,串口中断函数中查询接收状态以确认是相应中断发生
6,接收数据,发送数据
7,串口中断标志位不须要手动清理,在读取数据后状态标志位会自动清零

注意;若是要使用printf函数的话,须要如下几个步骤
1,在target选项中勾选 use microLIB
2,头文件包含STDIO.H
3,从新定义fputc函数,也就是添加这些代码
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//Ñ­»··¢ËÍ,Ö±µ½·¢ËÍÍê±Ï   
    USART1->DR = (u8) ch;      
	return ch;
}
 4,OK

本实验用的是原子的精英板,代码以下;
#include "sys.h"
#include "delay.h"
#include "stdio.h"
/************************************************************
功能;接收从电脑发送来的信息,并发送回电脑
这里只是测试串口中断,接收的数据长度是有限制的
串口接在PA9,PA10

串口配置步骤
为了更好的说明串口的本质,这里采用查询的方式,并无使用中断
0,在主函数中进行中断分组
1,打开串口IO时钟
2,选择串口接收 引脚
3,选择接收引脚模式,这个模式要看《中文手册》8.1.11章节
4,配置IO翻转速度
5,配置串口发送引脚,方法同串口接收引脚,可是IO模式不同
6,打开uart1时钟
7,选择串口波特率
8,选择是否须要硬件流控制
9,打开接收和发送模式
10,选择是否启用奇偶校验
11,选择中止位个数
12,选择数据长度
13,配置中断初始化
14,使能串口中断
15,配置完成后必定要记得使能串口
16,编写中断函数
17,在中断中确认是否是相应的串口中断
18,接收数据,,该干吗干吗去
19,串口中断不须要手动清理中断标志

****************************************************************/

void init__uart1()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	USART_InitTypeDef USART_InitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;
	
	//	串口IO配置,PA9,PA10
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//IO时钟打开
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//IO方式具体看《中文手册》8.1.11章节
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//IO方式具体看《中文手册》8.1.11章节
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//配置串口1
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//打开串口时钟
	
	USART_InitStruct.USART_BaudRate=115200;	//波特率115200
	USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;	//无硬件流
	USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;	//接收和发送都使能
	USART_InitStruct.USART_Parity=USART_Parity_No;						//无奇偶校验
	USART_InitStruct.USART_StopBits=USART_StopBits_1;					//中止位1位
	USART_InitStruct.USART_WordLength=USART_WordLength_8b;		//数据长度8位
	USART_Init(USART1,&USART_InitStruct);
	
	NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;//虽然知道这个参数的意思,可是还真不知道这个参数放在哪里
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;//使能通道中断
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;//子优先级
	NVIC_Init(&NVIC_InitStruct);//这个函数在misc.c文件里
	
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//打开串口中断,第二个参数是选择中断类型,这里打开的是接收中断
	USART_Cmd(USART1,ENABLE);	//配置完成后必定要记得使能串口
}

 int main(void)
 {	
	char re_data=0;//为了接收字符,仍是定义为字符类型吧
	 
	delay_init();	//延时函数初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	init__uart1();//串口1初始化
	printf("hello word\r\n");//为了测试printf函数是否能用
	 
	while(1)
	{}//等待中断
 }
 
 //串口中断处理函数
 void USART1_IRQHandler(void) 
 {
	 char re_data=0;//为了接收字符,仍是定义为字符类型吧
	 if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==1)//确认下是否是串口1接收中断
	 {
			re_data=USART_ReceiveData(USART1);	//接收数据
			USART_SendData(USART1,re_data);			//发送数据
			while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET); //等待数据发送完 成
	 }	 
	 //这个中断是不须要手动清除标志位的,由于读取数据后接收标志位会自动清零
 }



//重定义fputc函数 ,想要使用printf函数得添加这个函数
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
	return ch;
}