配置串口的中断接收(标准库)基于STM32F103VET6单片机
注:如有错误欢迎批评改正。
1.串口初始化
我用的是片上外设UART4(因为USART1-3已经有别的用途)
首先定义一个UART(通用异步收发传输器)初始化函数,在函数中定义一个GPIO初始化结构体和一个USART初始化结构体。分别用于定义UART4引脚的输入输出模式和UART4的工作参数。
void UART4_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; // 打开串口GPIO的时钟 DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE); // 打开串口外设的时钟 DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE); // 将USART Tx的GPIO配置为推挽复用模式 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure); // 将USART Rx的GPIO配置为浮空输入模式 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure); // 配置串口的工作参数 // 配置波特率 USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE; // 配置帧数据长度 USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 配置停止位 USART_InitStructure.USART_StopBits = USART_StopBits_1; // 配置校验位 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(DEBUG_USARTx, &USART_InitStructure); // 串口中断优先级配置 NVIC_Configuration(); // 使能串口接收中断 USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE); // USART_ITConfig(UART4,USART_IT_RXNE,ENABLE); // 使能串口 USART_Cmd(DEBUG_USARTx, ENABLE); // 清除发送完成标志 USART_ClearFlag(UART4, USART_FLAG_TC); }
2.中断初始化
然后定义一个NVIC(嵌套向量中断控制器)初始化函数,在函数中定义一个NVIC初始化结构体。用于配置中断源,优先级等参数。这些都可以在misc.h里看到,根据需要选择就好(如果英文不太好可以下载一个有道词典,划词翻译很方便,我就是英文不好)。
void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* 嵌套向量中断控制器组选择 */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 配置USART为中断源 */ NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ; /* 抢断优先级*/ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* 子优先级 */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /* 使能中断 */ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /* 初始化配置NVIC */ NVIC_Init(&NVIC_InitStructure); }
3.注意事项
这里主要就是说几个我遇到的问题,第一个就是要在串口初始化函数中使能串口接收中断,第二个就是程序要有一个死循环(这样程序才能一直运行从而有机会触发中断),还有就是在stm32f10x_it.h中写一个中断服务函数(只要触发中断就会调用这个函数,在选择中断源的时候可以选择中断触发条件,我这里选择的是接收寄存器非空中断,意思就是只要数据寄存器接收到数据就会触发中断)
/*初始化USART 配置模式为 115200 8-N-1,中断接收*/ UART4_Config(); /* 发送一个字符串 */ Usart_SendString( DEBUG_USARTx,"串口发送实验成功\n"); //注释掉的是没使用中断时候的接收函数 // while(1) // { // UART4_DATA=UART4_RECEIVE(); // Usart_SendByte(DEBUG_USARTx,UART4_DATA); // } while(1) {}
// 串口(UART4)中断服务函数 void DEBUG_USART_IRQHandler(void) { uint8_t UART4_Temp; if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET) { UART4_Temp = USART_ReceiveData(DEBUG_USARTx); USART_SendData(DEBUG_USARTx,UART4_Temp); } }
(函数名要在头文件中声明//.h文件)