Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
串口
串口DMA接收
F030系列芯片UART3~UART6 代码分享 可正常使用
发布于 2023-01-13 23:42:29 浏览:784
订阅该版
看了大家对F030复用串口的疑惑,这里继续给出“当同时使用UART3~UART6中的多个串口时,由于其中断响应函数都是同一个,需要自己在中断函数USART3_6_IRQHandler() 中判断是来自哪个串口的中断。”这个问题的解决办法。这里使用的是串口V2版本。 ```c void USART3_6_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); struct stm32_uart *uart3,*uart4,*uart5; uart5 = rt_container_of(&(uart_obj[UART5_INDEX].serial), struct stm32_uart, serial); uart3 = rt_container_of(&(uart_obj[UART3_INDEX].serial), struct stm32_uart, serial); uart4 = rt_container_of(&(uart_obj[UART4_INDEX].serial), struct stm32_uart, serial); if(__HAL_UART_GET_FLAG(&(uart3->handle), UART_FLAG_RXNE) != RESET) uart_isr(&(uart_obj[UART3_INDEX].serial)); if(__HAL_UART_GET_FLAG(&(uart4->handle), UART_FLAG_RXNE) != RESET) uart_isr(&(uart_obj[UART4_INDEX].serial)); if(__HAL_UART_GET_FLAG(&(uart5->handle), UART_FLAG_RXNE) != RESET) uart_isr(&(uart_obj[UART5_INDEX].serial)); /* leave interrupt */ rt_interrupt_leave(); } ``` 其中就是加入了获取串口的判断,执行不同中断ISR。还有一点需要注意,F030RC的默认DMA通道是Cxs 0级别的中断,如果需要使用串口的DMA中断,需要在DMA初始化的时候添加__HAL_DMA1_REMAP()函数, ![屏幕截图 2023-01-13 234007.png](https://oss-club.rt-thread.org/uploads/20230113/f05dc9edd774fe55c989fc9328eff848.png.webp) 据需要选择不同串口即可,下面是DMA初始化代码。 ```c static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag) { struct rt_serial_rx_fifo *rx_fifo; DMA_HandleTypeDef *DMA_Handle; struct dma_config *dma_config; struct stm32_uart *uart; RT_ASSERT(serial != RT_NULL); RT_ASSERT(flag == RT_DEVICE_FLAG_DMA_TX || flag == RT_DEVICE_FLAG_DMA_RX); uart = rt_container_of(serial, struct stm32_uart, serial); if (RT_DEVICE_FLAG_DMA_RX == flag) { DMA_Handle = &uart->dma_rx.handle; dma_config = uart->config->dma_rx; } else /* RT_DEVICE_FLAG_DMA_TX == flag */ { DMA_Handle = &uart->dma_tx.handle; dma_config = uart->config->dma_tx; } LOG_D("%s dma config start", uart->config->name); { rt_uint32_t tmpreg = 0x00U; #if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) \ || defined(SOC_SERIES_STM32L0) /* enable DMA clock && Delay after an RCC peripheral clock enabling*/ SET_BIT(RCC->AHBENR, dma_config->dma_rcc); tmpreg = READ_BIT(RCC->AHBENR, dma_config->dma_rcc); #elif defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) \ || defined(SOC_SERIES_STM32G4)|| defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32WB) /* enable DMA clock && Delay after an RCC peripheral clock enabling*/ SET_BIT(RCC->AHB1ENR, dma_config->dma_rcc); tmpreg = READ_BIT(RCC->AHB1ENR, dma_config->dma_rcc); #elif defined(SOC_SERIES_STM32MP1) /* enable DMA clock && Delay after an RCC peripheral clock enabling*/ SET_BIT(RCC->MP_AHB2ENSETR, dma_config->dma_rcc); tmpreg = READ_BIT(RCC->MP_AHB2ENSETR, dma_config->dma_rcc); #endif #if defined(DMAMUX1) && (defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)) /* enable DMAMUX clock for L4+ and G4 */ __HAL_RCC_DMAMUX1_CLK_ENABLE(); #elif defined(SOC_SERIES_STM32MP1) __HAL_RCC_DMAMUX_CLK_ENABLE(); #endif UNUSED(tmpreg); /* To avoid compiler warnings */ } if (RT_DEVICE_FLAG_DMA_RX == flag) { __HAL_LINKDMA(&(uart->handle), hdmarx, uart->dma_rx.handle); } else if (RT_DEVICE_FLAG_DMA_TX == flag) { __HAL_LINKDMA(&(uart->handle), hdmatx, uart->dma_tx.handle); } #if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32L0) DMA_Handle->Instance = dma_config->Instance; #elif defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) DMA_Handle->Instance = dma_config->Instance; DMA_Handle->Init.Channel = dma_config->channel; #elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)\ || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1) DMA_Handle->Instance = dma_config->Instance; DMA_Handle->Init.Request = dma_config->request; #endif DMA_Handle->Init.PeriphInc = DMA_PINC_DISABLE; DMA_Handle->Init.MemInc = DMA_MINC_ENABLE; DMA_Handle->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; DMA_Handle->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; if (RT_DEVICE_FLAG_DMA_RX == flag) { DMA_Handle->Init.Direction = DMA_PERIPH_TO_MEMORY; DMA_Handle->Init.Mode = DMA_CIRCULAR; } else if (RT_DEVICE_FLAG_DMA_TX == flag) { DMA_Handle->Init.Direction = DMA_MEMORY_TO_PERIPH; DMA_Handle->Init.Mode = DMA_NORMAL; } DMA_Handle->Init.Priority = DMA_PRIORITY_MEDIUM; #if defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1) DMA_Handle->Init.FIFOMode = DMA_FIFOMODE_DISABLE; #endif if (HAL_DMA_DeInit(DMA_Handle) != HAL_OK) { RT_ASSERT(0); } if (HAL_DMA_Init(DMA_Handle) != HAL_OK) { RT_ASSERT(0); } __HAL_DMA1_REMAP(HAL_DMA1_CH3_USART3_RX); //添加这两个即可 __HAL_DMA1_REMAP(HAL_DMA1_CH1_USART4_RX); /* enable interrupt */ if (flag == RT_DEVICE_FLAG_DMA_RX) { rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; RT_ASSERT(rx_fifo != RT_NULL); /* Start DMA transfer */ if (HAL_UART_Receive_DMA(&(uart->handle), rx_fifo->buffer, serial->config.rx_bufsz) != HAL_OK) { /* Transfer error in reception process */ RT_ASSERT(0); } CLEAR_BIT(uart->handle.Instance->CR3, USART_CR3_EIE); __HAL_UART_ENABLE_IT(&(uart->handle), UART_IT_IDLE); } /* DMA irq should set in DMA TX mode, or HAL_UART_TxCpltCallback function will not be called */ HAL_NVIC_SetPriority(dma_config->dma_irq, 0, 0); HAL_NVIC_EnableIRQ(dma_config->dma_irq); HAL_NVIC_SetPriority(uart->config->irq_type, 1, 0); HAL_NVIC_EnableIRQ(uart->config->irq_type); LOG_D("%s dma %s instance: %x", uart->config->name, flag == RT_DEVICE_FLAG_DMA_RX ? "RX" : "TX", DMA_Handle->Instance); LOG_D("%s dma config done", uart->config->name); } ```
2
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
balabala
这家伙很懒,什么也没写!
文章
1
回答
2
被采纳
0
关注TA
发私信
相关文章
1
串口DMA发送数据时,数据被覆盖
2
关于串口DMA模式下rt_device_close问题
3
利用stm32f427实现usb转串口,电脑端什么也没有识别到
4
finsh 控制台 适配 RS 485请大神指点????
5
uart_sample.c 中,读串口设备时偏移量pos要设置为-1而不是0?
6
【结贴】at_device软件包中对串口接收数据缺少判断导致数据接收异常
7
串口无法接受数据,但可以发送
8
串口如何有效的清除掉接收缓冲,而不必一个一个的去读取
9
串口接收使用方式问题
10
雅特力FINSH问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
freemodbus
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
Debug
中断
编译报错
rt_mq_消息队列_msg_queue
SFUD
keil_MDK
msh
ulog
C++_cpp
MicroPython
本月问答贡献
a1012112796
20
个答案
3
次被采纳
红枫
8
个答案
2
次被采纳
踩姑娘的小蘑菇
7
个答案
2
次被采纳
三世执戟
7
个答案
1
次被采纳
张世争
6
个答案
1
次被采纳
本月文章贡献
YZRD
3
篇文章
6
次点赞
catcatbing
3
篇文章
6
次点赞
lizimu
2
篇文章
12
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部