串口DMA收不定长数据
主要利用了IDLE空闲中断,然后整体验证采用透传,发送后回传数据。
整体流程
1cubemx配置
2接收发送数组,标志位定义,
3中断使能
4中断函数修改
5回调函数修改
一、cubemx配置
波特率随便设置,我设置的是1M,注意你的上位机和串口助手是否选择一致的参数
DMA USART1 TX RX 设置,mode都是normal模式就可以
二、程序修改
1.初始数组定义
- uint8_t Rx_Flag = 0; //接收标志位
- uint8_t RecCount = 0; //个数
- uint8_t Rx_Buf[256]; //接收缓冲区
- uint8_t Tx_Buf[256];
复制代码
2.中断使能配置
- 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 = 1000000;
- 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;
- huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
- huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
- huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
- if (HAL_RS485Ex_Init(&huart1, UART_DE_POLARITY_HIGH, 0, 0) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN USART1_Init 2 */
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//开启idle中断
- HAL_UART_Receive_DMA(&huart1, Rx_Buf, 256); //开启dma中断
- /* USER CODE END USART1_Init 2 */
- }
复制代码
3.中断函数修改
- */
- void USART1_IRQHandler(void)
- {
- /* USER CODE BEGIN USART1_IRQn 0 */
-
- /* USER CODE END USART1_IRQn 0 */
- HAL_UART_IRQHandler(&huart1);
- /* USER CODE BEGIN USART1_IRQn 1 */
- //添加idle中断处理
- if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)!=RESET) //是否发生idle中断
- {
- __HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除idle中断
- HAL_UART_IdleCpltCallback(&huart1); //用户编写的中断回调函数
- }
- /* USER CODE END USART1_IRQn 1 */
- }
复制代码
4.回调函数修改
- void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart) //空闲中断函数
- {
- Rx_Flag = 1; // 设置接收完成标志
- HAL_UART_DMAStop(huart); // 停止DMA传输
-
- //发生空闲中断时,已接受的数据等于数据总减去dma中待接收的数据
- RecCount= 256 - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
-
- memcpy(Tx_Buf, Rx_Buf, RecCount); //内存复制函数
- memset(Rx_Buf, 0, sizeof(Rx_Buf)); // 清零接收缓存区
- HAL_UART_Receive_DMA(&huart1,Rx_Buf, sizeof(Rx_Buf)); //重新开启DMA传输
-
-
- }
复制代码
————————————————
版权声明:超级馒头神
|