DMA++空闲中断+串口接收不定长数据
复制3.1方便验证
cubemx添加配置
代码实现
stm32f1xx_it
在stm32f1xx_it.c找到void USART1_IRQHandler(void)替换
添加头文件
#include "usart.h"
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) == SET)//触发串口空闲接收中断
{
uint16_t temp;
__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除串口空闲接收中断标志位
HAL_UART_DMAStop(&huart1);//关闭DAM
//软件清除中断
temp = huart1.Instance->SR;//读SR
temp = huart1.Instance->DR;//读DR
temp = hdma_usart1_rx.Instance->CNDTR;//获取DMA剩余空间长度
Usart1type.DMARecLen = Usart1_DMARecBuffer_Size - temp;//接收数据长度=总长度-剩余长度
HAL_UART_RxCpltCallback(&huart1);//串口接收回调函数
}
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
HAL_UART_Receive_DMA(&huart1,Usart1type.DMARecBuffer,Usart1_DMARecBuffer_Size);//重新使能DMA接收
/* USER CODE END USART1_IRQn 1 */
}
usart.c
声明
teUsart3type Usart3type;
void EnableUsart1_IT(void)
{
__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);//开启串口接收中断
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//开启串口空闲接收中断
__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除串口空闲接收中断标志位
HAL_UART_Receive_DMA(&huart1,Usart1type.DMARecBuffer,Usart1_DMARecBuffer_Size);//使能DMA接收
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
if(Usart1type.RecLen > 0)
{
memcpy(&Usart1type.RecBuffer[Usart1type.RecLen],Usart1type.DMARecBuffer,Usart1type.DMARecLen);
Usart1type.RecLen += Usart1type.DMARecLen;
}
else
{
memcpy(Usart1type.RecBuffer,Usart1type.DMARecBuffer,Usart1type.DMARecLen);
Usart1type.RecLen = Usart1type.DMARecLen;
}
memset(Usart1type.DMARecBuffer,0,Usart1_DMARecBuffer_Size);
Usart1type.DMARecLen = 0;
Usart1type.RecFlag = 1;
}
}
usart.h
#define Usart1_DMARecBuffer_Size 256
#define Usart1_RecBuffer_Size 512
typedef struct
{
uint8_t RecFlag;
uint16_t DMARecLen;
uint16_t RecLen;
uint8_t DMARecBuffer[Usart1_DMARecBuffer_Size];
uint8_t RecBuffer[Usart1_RecBuffer_Size];
}teUsart1type;
extern teUsart1type Usart1type;
声明
void EnableUsart1_IT(void);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
测试
EnableUsart1_IT();
if(Usart1type.RecFlag)
{
Usart1type.RecFlag = 0;
printf("%s and %d\r\n",Usart1type.RecBuffer,Usart1type.RecLen);
memset(Usart1type.RecBuffer,0,Usart1_RecBuffer_Size);
Usart1type.RecLen = 0;
}