stm32串口接收数据包hal
时间: 2025-02-13 21:22:16 浏览: 30
STM32 HAL UART 接收数据包示例代码
对于STM32 使用 HAL 库通过串口接收数据包的操作,可以利用 HAL_UART_Receive()
函数完成同步方式下的简单接收任务。然而当涉及到更复杂的应用场景时,如连续的数据流处理或是需要提高效率的情况下,则推荐采用 DMA 方式来进行数据传输。
同步模式下接收固定长度的数据包
下面是一个简单的例子展示如何配置并使用 HAL 库以同步的方式从指定的串口号读取一定数量字节的数据:
#include "stm32f4xx_hal.h"
UART_HandleTypeDef huart1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
int main(void){
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
uint8_t rxData[64]; // 假定最大接收缓冲区大小为64字节
while (true) {
if(HAL_OK == HAL_UART_Receive(&huart1, rxData, sizeof(rxData), HAL_MAX_DELAY)){
// 成功接收到数据后的处理逻辑...
}
}
}
此段程序会在每次调用 HAL_UART_Receive
方法后阻塞直到成功接收到预期数目的字符为止[^1]。
利用DMA异步接收不定长数据包
如果希望实现更加高效灵活的数据包接收机制,可以通过启用 DMA 来执行非阻塞性的数据传输过程。这种方式允许 CPU 在等待 I/O 完成期间继续运行其他任务,从而提高了系统的整体性能。以下是基于 DMA 的 UART 数据包接收实例:
#include "stm32f4xx_hal.h"
#define RX_BUFFER_SIZE 64
UART_HandleTypeDef huart1;
uint8_t aRxBuffer[RX_BUFFER_SIZE];
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
extern void Error_Handler(void);
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&huart1,hdmarx,hdma_usart1_rx);
}
// 初始化DMA通道用于USART1接收
__weak void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/**USART1 GPIO Configuration
PD5 ------> USART1_CK
PD6 ------> USART1_RTS
PD7 ------> USART1_CTS
PD8 ------> USART1_RX
PD9 ------> USART1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
hdma_usart1_rx.Instance = DMA2_Stream2;
hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_NORMAL;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hal_dma_init(&hdma_usart1_rx);
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);
}
}
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);
}
/**
* @brief Callback called when reception is complete with success or error.
*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
// 当DMA完成了整个数据包的接收后会触发该回调函数,
// 此处可加入对接收到的数据进行解析或其他后续操作。
}
int main(void){
...
// 开始DMA接收
HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RX_BUFFER_SIZE);
...
}
上述代码展示了如何设置和初始化带有DMA功能的UART接口,并指定了相应的中断服务例程以及接收完成后要调用的回调函数。一旦DMA控制器完成了全部预定量的数据搬运工作,就会自动触发 HAL_UART_RxCpltCallback
,在此基础上可以根据实际需求进一步扩展业务逻辑[^2].
相关推荐


















