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; }