应用案例:cubeMX hal库 dma串口应用。串口DMA接收消息,利用串口的空闲中断,实现消息的处理
核心代码
stm32f1xx_it.c空闲中断中获取有效消息数量,并置位消息标志
//"stm32f1xx_it.c"
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
#define wifi_uart huart4
uint16_t temp = 0; //dma未使用数据位数
//
if (__HAL_UART_GET_FLAG(&wifi_uart,UART_FLAG_IDLE) != RESET) //如果接受到了一帧数据
{
__HAL_UART_CLEAR_IDLEFLAG(&wifi_uart); //清除标志位
//暂停DMA才能读CNDTR
HAL_UART_DMAStop(&wifi_uart);
//获取未使用数据传输数量
temp = (uint16_t) __HAL_DMA_GET_COUNTER(&hdma_usart4_rx);
//得到 有效数据量
wifi_msg.msg_count = wifi_msg.msg_buff_size - temp;
//接收标志置位,等待处理
wifi_msg.msg_flag = SET;
}
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
usart.c 中开启 空闲中断 只加一行代码__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//空闲中断
#include "usart.h"
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
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();
}
/* USER CODE BEGIN USART1_Init 2 */
//使能IDLE中断
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//空闲中断
/* USER CODE END USART1_Init 2 */
}
main 添加 代码
//串口接收信息
struct UART_DMA_recv
{
FlagStatus msg_flag;
uint16_t msg_count;
uint16_t msg_buff_size;
uint8_t msg_data[512];
};
volatile struct UART_DMA_recv wifi_msg = { .msg_buff_size = sizeof(wifi_msg.msg_data) };
main需添加的代码
int main(void)
{
// �?要主动开启才能接收消�?
HAL_UART_Receive_DMA(&huart1, (uint8_t *)recbuff, RX1_BUFF_SIZE);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_Delay(10);
if( reccount)
{
//发�?�接收到的有效数�?
// HAL_UART_Transmit_DMA(&huart1, (uint8_t *)recbuff, reccount);
HAL_UART_Transmit(&huart1, (uint8_t *)recbuff, reccount, 200);
//等待消息发送完成
while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)==RESET);
memset( (uint8_t *)recbuff,0,reccount);
reccount=0;
recflag = RESET;
//打开dma接收
HAL_UART_Receive_DMA(&huart1, (uint8_t *)recbuff, RX1_BUFF_SIZE);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
注意事项
- 给MCU的数据 不能超过缓存数组 大小。
超过会导致串口一直忙,不能触发空闲中断,也就不能处理数据了。有时间在研究下 超量数据的保证处理。