完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
stm32f103芯片的串口一直使用DMA+空闲中断,现在使用stm32h7芯片,打算也使用相同的方法
芯片型号:stm32h743 串口:USART2 代码生成:stm32CubeMX 第一步:使用stm32CubeMX生成代码 第二步:添加自己代码 1.发生空闲中断需要reset DMA重新开始接收数据 HAL_StatusTypeDef HAL_UART_DMAStopRx(UART_HandleTypeDef *huart) { /* Stop UART DMA Rx request if ongoing */ if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))) { CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); /* Abort the UART DMA Rx channel */ if(huart->hdmarx != NULL) { HAL_DMA_Abort(huart->hdmarx); } //UART_EndRxTransfer(huart); /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); /* At end of Rx process, restore huart->RxState to Ready */ huart->RxState = HAL_UART_STATE_READY; } return HAL_OK; } 串口空闲中断 /** * @brief This function handles UART4 global interrupt. */ void USART2_IRQHandler(void) { uint32_t _len_dmarev; uint32_t isrflags; uint32_t cr1its; BaseType_t xHigherPriorityTaskWoken; HAL_UART_IRQHandler(&UART2_Handler); isrflags = READ_REG(UART2_Handler.Instance->ISR); cr1its = READ_REG(UART2_Handler.Instance->CR1); if(((isrflags & USART_ISR_IDLE) != RESET) && ((cr1its & USART_CR1_IDLEIE) != RESET)) { __HAL_UART_CLEAR_IDLEFLAG(&UART2_Handler); _len_dmarev = DMA_BUFFER_LENGTH - __HAL_DMA_GET_COUNTER(UART2_Handler.hdmarx); if(_len_dmarev) { //停止DMA HAL_UART_DMAStopRx(&UART2_Handler); //这个地方非常关键,DMA访问的ram,但是CPU访问的是cache,使用下面函数使ram和cache一致 SCB_InvalidateDCache_by_Addr((uint32_t *)dma_rx_buf, DMA_BUFFER_LENGTH); xQueueSendToBackFromISR(Keyboard_Queue,(void*)&uart_to_keyboard_msg,&xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); HAL_UART_Receive_DMA(&UART2_Handler, dma_rx_buf, DMA_BUFFER_LENGTH); __HAL_UART_DISABLE_IT(&UART2_Handler, UART_IT_ERR); __HAL_UART_DISABLE_IT(&UART2_Handler, UART_IT_PE); } else { READ_REG(UART2_Handler.Instance->RDR); __HAL_UART_CLEAR_OREFLAG(&UART2_Handler); } } } unsigned int KeyboardRs485TxFrame(uint8_t * buffer,uint32_t len) { UINT16 i; //拷贝数据到DMA buffer for(i = 0; i < len; i++) { dma_tx_buf = buffer; } //使发送RAM和cache一致 SCB_InvalidateDCache_by_Addr((uint32_t *)dma_tx_buf, DMA_BUFFER_LENGTH); HAL_UART_Transmit_DMA(&UART2_Handler, dma_tx_buf, len); return 0; } 还有一点需要特别注意:DMA访问的是0x24000000以后区域,定义的发送和接收DMA buffer 一定要在这个区域 可使用下面的编译指令: ALIGN_32BYTES(attribute((section (".RAM_D2"))) uint8_t dma_rx_buf[DMA_BUFFER_LENGTH]) ; ALIGN_32BYTES(attribute((section (".RAM_D2"))) uint8_t dma_tx_buf[DMA_BUFFER_LENGTH]); |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1609 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1540 浏览 1 评论
970 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
681 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1587 浏览 2 评论
1861浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
528浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
503浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-21 00:37 , Processed in 0.707899 second(s), Total 76, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号