STM32F4 STD标准库串口接收中断+空闲中断例程
- 🔖工程基于
STM32F446
✨用惯了
STM32CubeMX
傻瓜式配置,突然改用标准库写代码,初始化外设内容,总是丢三落四的。
📗串口初始化配置
c
void uart_init(uint32_t bound)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //使能USART1,GPIOA时钟
/* Enable GPIO clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* Connect PXx to USARTx_Tx*/
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
/* Connect PXx to USARTx_Rx*/
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
//USART1_TX GPIOA.9
/* Configure USART Tx as alternate function */
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART Rx as alternate function */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3 ; //抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
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(USART1, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口空闲中断
USART_Cmd(USART1, ENABLE); //使能串口1
}
📘串口中断函数
c
void USART1_IRQHandler(void) //串口1中断服务程序
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
// USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清标志位
// USART_RX_BUF[length] = USART_ReceiveData(USART1);//读取接收到的数据
USART_RX_BUF[length] = USART1->DR & 0x0FF;
length++;
} else if(USART_GetFlagStatus(USART1, USART_FLAG_IDLE) != RESET) { //空闲帧中断
USART1->SR; //先读SR.再读DR
USART1->DR; //清空寄存器
length = 0;
USART_RX_STA = 1; //数据接收 标志位
}
}
📑接收数据所需的变量和宏定义
c
#define USART_REC_LEN 64 //定义最大接收字节数 64
#define EN_USART1_RX 1 //使能(1)/禁止(0)串口1接收
uint8_t USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
uint8_t USART_RX_STA = 0; //接收状态标记
static __IO uint16_t length = 0;//接收数据时的下标
📒处理接收数据和释放空间
c
if(USART_RX_STA) {
USART_RX_STA = 0;//清标志位
printf("Re:%s\n", USART_RX_BUF);
memset(USART_RX_BUF, 0x00, sizeof(USART_RX_BUF));//清空接收数组
}
- 🔬测试效果:
📚测试工程
c
链接:https://pan.baidu.com/s/13UxJawYkAkpIb8SzhSnpqg?pwd=8rc0
提取码:8rc0