完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
简介:
出现空闲标志时,认为一帧报文发送完毕,进行报文分析,比普通的串口中断效率高很多! 用到的工具:CubeMX,Keil5 芯片:STM32F103VET6 步骤: 一、配置串口 二、使能串口NVIC中断 三、配置DMA 四、配置为MDK5,并生成代码工程 五、打开工程,添加部分代码 uint8_t receive_buff[255]; //定义接收数组 int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); HAL_UART_Receive_DMA(&huart1, (uint8_t*)receive_buff, 255); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } 六、添加串口空闲中断处理 /** * @brief This function handles USART1 global interrupt. */ void USART1_IRQHandler(void) { /* USER CODE BEGIN USART1_IRQn 1 */ if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) //判断是否是空闲中断 { __HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除空闲中断标志 HAL_UART_DMAStop(&huart1); //停止本次DMA传输 uint8_t data_length = 255 - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); //计算接收到的数据长度 HAL_UART_Transmit(&huart1,receive_buff,data_length,0x200); //测试函数:将接收到的数据打印出去 memset(receive_buff,0,data_length); data_length = 0; HAL_UART_Receive_DMA(&huart1, (uint8_t*)receive_buff, 255); //重启开始DMA传输 } /* USER CODE END USART1_IRQn 1 */ } 七、连接串口助手测试 收到数据后,会在空闲中断里把收到的数据发送回去。效果如下图所示: 以下为把串口空闲中断抽离出来:以串口2为例: UART_HandleTypeDef huart2; uint8_t receive_buff2[255]; DMA_HandleTypeDef hdma_usart2_rx; void Uart2_Init() { __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_AFIO_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE(); __HAL_RCC_USART2_CLK_ENABLE(); __HAL_RCC_DMA1_CLK_ENABLE(); HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn); GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USART2 DMA Init */ /* USART2_RX Init */ hdma_usart2_rx.Instance = DMA1_Channel6; hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart2_rx.Init.Mode = DMA_NORMAL; hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW; if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(&huart2,hdmarx,hdma_usart2_rx); /* USART2 interrupt Init */ HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); HAL_NVIC_EnableIRQ(USART2_IRQn); huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE); HAL_UART_Receive_DMA(&huart2, (uint8_t*)receive_buff2, 255); } /** * @brief This function handles USART2 global interrupt. */ uint8_t data_length; void USART2_IRQHandler(void) { if(RESET != __HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE)) //判断是否是空闲中断 { __HAL_UART_CLEAR_IDLEFLAG(&huart2); //清除空闲中断标志 HAL_UART_DMAStop(&huart2); //停止本次DMA传输 data_length = 255 - __HAL_DMA_GET_COUNTER(&hdma_usart2_rx); //计算接收到的数据长度 HAL_UART_Transmit(&huart2,receive_buff2,data_length,0x200); //测试函数:将接收到的数据打印出去 // memset(receive_buff2,0,data_length); HAL_UART_Receive_DMA(&huart2, (uint8_t*)receive_buff2, 255); //重启开始DMA传输 } } main里调用初始化即可 int main(void) { int count = 1; Uart2_Init(); while (1) { ... } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1627 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1550 浏览 1 评论
984 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
688 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1601 浏览 2 评论
1867浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
650浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
518浏览 3评论
537浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
506浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 00:19 , Processed in 0.790763 second(s), Total 76, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号