串口接收
串口接收流程
编程USARTx_CR1的M位来定义字长。
编程USARTx_CR2的STOP位来定义停止位位数。
使能USARTx_CR1的UE位使能USARTx。
如果进行多缓冲通信,配置USARTx_CR3的DMA使能(DMAT)。
使能USARTx_CR1的RE位为1使能接收器。
如果要使能接收中断(接收到数据后产生中断),使能USARTx_CR1的RXNEIE位为1。
当串口接收到数据时
USARTx_SR(ISR)的RXNE位置1。表明移位寄存器内容已经传输到RDR(DR)寄存器。已经接收到数据并且等待读取。
如果开启了接收数据中断(USARTx_CR1寄存器的RXNEIE位为1),则会产生中断。(程序上会执行中断服务函数)
如果开启了其他中断(帧错误等),相应标志位会置1。
读取USARTx_RDR(DR)寄存器的值,该操作会自动将RXNE位清零,等待下次接收后置位。
串口接收流程(HAL库)
配置过程:
接收配置步骤①~⑥和发送流程一样,调用HAL_UART_Init函数HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);
步骤⑦开启接收中断:HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef*huart, uint8_t *pData, uint16_t Size);
接收数据过程:
步骤①获取状态标志位通过标识符实现:
__HAL_UART_GET_FLAG //判断状态标志位
__HAL_UART_GET_IT_SOURCE //判断中断标志位
步骤②~③中断服务函数:
void USARTx_IRQHandler(void) ;//(x=1~3,6)
void UARTx_IRQHandler(void) ;//(x=4,5,7,8)
在启动文件startup_stm32fxxx.s中查找。
步骤④读取接收数据:
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
串口接收中断程序配置过程(HAL库)
初始化串口相关参数,使能串口:HAL_UART_Init();
串口相关IO口配置,复用配置:
在HAL_UART_MspInit中调用HAL_GPIO_Init函数。串口接收中断优先级配置和使能:
HAL_NVIC_EnableIRQ();
HAL_NVIC_SetPriority();使能串口接收中断:HAL_UART_Receive_IT();
编写中断服务函数:USARTx_IRQHandler
经过上面步骤,我们就可以写完整的串口接收实验。我们就可以在中断服务函数中编写中断处理过程。
HAL库提供了详细的中断处理函数HAL_UART_IRQHandler,我们在中断服务函数中会调用此函数处理中断。

在void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)函数里可以找到:UART_Receive_IT(huart);然后找到他的定义static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart),里面可以找到HAL_UART_RxCpltCallback(huart);他是一个接收完成处理回调函数,void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart),用户可以自己编写。
在USART_HandleTypeDef中有如下变量:RxXferSize是接收的数量,RxXferCount是剩余的数据个数,pRxBuffPtr指向数据存储位置的地址。比如,一开始要接收10个数据,pRxBuffPtr指向一个起始位置,初始时RxXferSize=10,RxXferCount=10,每接收一次,RxXferCount的值就减去1,而且pRxBuffPtr指针往下移,直到RxXferCount减为0 。
uint8_t *pRxBuffPtr; /*!< Pointer to USART Rx transfer Buffer */
uint16_t RxXferSize; /*!< USART Rx Transfer size */
uint16_t RxXferCount; /*!< USART Rx Transfer Counter */
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
uint16_t* tmp;
uint16_t uhMask = huart->Mask;
/* Check that a Rx process is ongoing */
if(huart->RxState == HAL_UART_STATE_BUSY_RX)
{
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
{
tmp = (uint16_t*) huart->pRxBuffPtr ;
*tmp = (uint16_t)(huart->Instance->RDR & uhMask);
huart->pRxBuffPtr +=2;
}
else
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
}
if(--huart->RxXferCount == 0)
{
/* Disable the UART Parity Error Interrupt and RXNE interrupt*/
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* Rx process is completed, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
HAL_UART_RxCpltCallback(huart);
return HAL_OK;
}
return HAL_OK;
}
else
{
/* Clear RXNE interrupt flag */
__HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
return HAL_BUSY;
}
}
串口接收中断流程

串口中断服务函数执行流程
串口中断服务函数中调用HAL库串口中断通用处理函数:HAL_UART_IRQHandler(); 该函数会对中断来源进行分析,调用相应函数。
对于不同的中断类型,我们只需要编写最终的中断处理函数:
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);
串口接收实验
电脑通过串口助手往串口1发送字符,串口1通过中断方式接受字符,每接受一个字符就同时通过串口1返回给电脑。
初始化串口相关参数,使能串口:HAL_UART_Init();
串口相关IO口配置,复用配置:
在HAL_UART_MspInit中调用HAL_GPIO_Init函数。
串口接收中断优先级配置和使能:
HAL_NVIC_EnableIRQ();
HAL_NVIC_SetPriority();
使能串口接收中断:HAL_UART_Receive_IT();
编写中断服务函数:USARTx_IRQHandler
根据如上步骤,其中1、2步骤和串口发送设置差不多,第三步,HAL_NVIC_SetPriority(USART1_IRQn,3,3);抢占和响应优先级均设置为3.这是因为main中的HAL_Init();有一个设置是 HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);
#include 'sys.h'
#include 'delay.h'
#include 'usart.h'
u8 rdata[1];//因为是每接收一个就发出去,所以设置为1
UART_HandleTypeDef usart1_handler;
//初始化串口相关参数,使能串口
void uart1_init(void)
{
usart1_handler.Instance = USART1;
usart1_handler.Init.BaudRate = 115200;
usart1_handler.Init.WordLength = UART_WORDLENGTH_8B;
usart1_handler.Init.StopBits = UART_STOPBITS_1;
usart1_handler.Init.HwFlowCtl = UART_HWCONTROL_NONE;
usart1_handler.Init.Mode = UART_MODE_TX_RX;
usart1_handler.Init.Parity = UART_PARITY_NONE;
HAL_UART_Init(&usart1_handler);
}
//串口相关IO口配置,复用配置
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef GPIO_Initure;
if(huart->Instance==USART1)
{
__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟
__HAL_RCC_USART1_CLK_ENABLE(); //使能USART1时钟
GPIO_Initure.Pin=GPIO_PIN_9; //PA9
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
GPIO_Initure.Alternate=GPIO_AF7_USART1; //复用为USART1
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA9
GPIO_Initure.Pin=GPIO_PIN_10; //PA10
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA10
//串口接收中断优先级配置和使能
HAL_NVIC_SetPriority(USART1_IRQn,3,3);//设置中断优先级
HAL_NVIC_EnableIRQ(USART1_IRQn);//使能中断通道
}
}
//编写中断服务函数
void USART1_IRQHandler()
{
HAL_UART_IRQHandler(&usart1_handler);
//由于调用一次中断,进入中断回调函数后,中断就结束了,所以还要开启中断
HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata));//使能接收中断
}
//编写接收完成中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
u8 rec;
if(huart->Instance==USART1)
{
//rec = *((huart->pRxBuffPtr)-1);
rec = rdata[0];//保存接收到的数据
HAL_UART_Transmit(&usart1_handler,&rec,1,1000);
}
}
int main(void)
{
Cache_Enable(); //打开L1-Cache
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(432,25,2,9); //设置时钟,216Mhz
delay_init(216);
uart1_init();
HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata));//使能接收中断
while(1)
{
}
}
上一篇:STM32-UART-串口通信框图-波特率计算
下一篇:STM32-串口发送数据-过程与配置
推荐阅读最新更新时间:2026-03-25 00:15
- 支持 BLE 连接、由 4mA 至 20mA 电流回路供电的现场发送器参考设计
- AM2DM-0515DH60-NZ ±15 Vout、2W 双路输出 DC-DC 转换器的典型应用
- LTC6261IDC 音频耳机桥式驱动器运算放大器的典型应用
- LTC1775CS 2.5V/5A 可调输出降压稳压器的典型应用电路
- AD8601ARTZ-REEL7 符合 PC100 标准的线路输出放大器的典型应用
- 一种基于分立的 315MHz 振荡器解决方案,用于使用 BFR182 射频双极晶体管的远程无钥匙进入系统
- 使用 ROHM Semiconductor 的 BD49E39G-TR 的参考设计
- AM30EW-2405SZ 5V 三路输出 DC/DC 转换器的典型应用
- LTC3564 的电池在 1.2A 应用中达到 1.2V
- AL1676EV2,基于 AP1676 高亮度降压 LED 驱动控制器的评估板

stm32驱动屏IC rm68042
STM32 PMSM FOC 简介
基于STM32G031的测试测量训练平台完成虚拟仪器实现
非常经典的关于LLC的杨波博士论文
1CIS223-04TG3M






京公网安备 11010802033920号