STM32
直播中

杜喜喜

7年用户 1492经验值
私信 关注
[问答]

STM32CubeMX串口+DMA接收不定长数据的函数分享

STM32CubeMX串口+DMA接收不定长数据的函数分享

回帖(1)

杨雨凡

2021-12-7 10:15:50
1.修改CubeMX生成的串口初始化函数
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 19200;
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(FILE, LINE);
}


__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能空闲中断
HAL_UART_Receive_DMA(&huart1, RxDMABuf_1, RXBUF_1_SIZE); //启动DMA接收


}
该函数在usart.c文件下。要更改的就是增加最后两行,其中RxDMABuf_1 是数据接收缓存,RXBUF_1_SIZE 是DMA一帧接收的最大字节数。


2.修改CubeMX生成的串口中断函数
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);


UART_IDLE_Deal(&huart1); //自定义空闲中断处理函数


}
该函数在stm32xxx_it.c文件下。增加UART_IDLE_Callback自定义空闲中断处理函数


3.定义UART_IDLE_Deal空闲中断处理函数
void UART_IDLE_Deal(UART_HandleTypeDef *huart)
{
unsigned int temp;
if( __HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET) //判断是否空闲中断
{
__HAL_UART_CLEAR_IDLEFLAG(huart);
temp = huart->Instance->SR;
temp = huart->Instance->DR;
HAL_UART_DMAStop(huart);


        if(huart->Instance == USART1)
        {
                //计算DMA接收的长度,也就是接收完一帧的长度
                DMA_Usart1_RxSize = RXBUF_1_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
                if(DMA_Usart1_RxSize > 0 )
                {
                        memcpy(RxBuf_1, RxDMABuf_1, DMA_Usart1_RxSize);
                        RxBufSize_1 = DMA_Usart1_RxSize;
                        memset(RxDMABuf_1, 0, sizeof(RxDMABuf_1));
                }
                HAL_UART_Receive_DMA(&huart1, RxDMABuf_1, RXBUF_1_SIZE); //启动下一次接收
        }
}


}
这个函数我定义在了usart.c文件下。功能主要就是接收完一帧数据后将数据拷贝出来,以免下次接收后被覆盖。


4.定义串口接收函数
unsigned char Uart_GetData(UART_HandleTypeDef *huart, unsigned char *buf)
{
unsigned char Size = 0;
if(huart->Instance == USART1)
{
if(RxBufSize_1 > 0)
{
Size = RxBufSize_1;
RxBuf_1[RxBufSize_1] = 0;
memcpy(buf, RxBuf_1, RxBufSize_1);
RxBufSize_1 = 0;
}
}
return Size;
}
该函数供主程序调用。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分