0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

F030系列芯片UART3~UART6代码分享

冬至子 来源:balabala 作者:balabala 2023-10-13 14:14 次阅读

看了大家对F030复用串口的疑惑,这里继续给出“当同时使用UART3~UART6中的多个串口时,由于其中断响应函数都是同一个,需要自己在中断函数USART3_6_IRQHandler() 中判断是来自哪个串口的中断。”这个问题的解决办法。这里使用的是串口V2版本。

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()函数,

1.jpg

据需要选择不同串口即可,下面是DMA初始化代码。

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);
}

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 串口中断
    +关注

    关注

    0

    文章

    63

    浏览量

    13607
  • USART串口
    +关注

    关注

    0

    文章

    31

    浏览量

    6723
  • HAL库
    +关注

    关注

    1

    文章

    112

    浏览量

    5878
收藏 人收藏

    评论

    相关推荐

    请问stm32f0系列芯片12位ADC的实际有效为(ENOB)是多少?

    请问f030系列芯片12位ADC的实际有效为(ENOB)是多少?我知道官方数据手册上没有,而f3系列的官方手册上有具体数值,请问有人知道吗?
    发表于 04-22 07:40

    STM32F030CCT6 UART4接收阻塞模式几分钟后无法收到数据是哪里的问题?

    芯片:STM32F030CCT6 库版本:STM32Cube_FW_F0_V1.11.0 问题:UART4,接收阻塞模式几分钟后无法收到数据。
    发表于 04-17 07:01

    STM32F030CCT6调5个串口,UART2,3,5进不了接收中断怎么解决?

    最近在调试STM32F030CCT6,需要用到5个串口,使用STM32CubeMX创建的工程,使用中断接收和中断发送的处理方式。但是调试发现,UART1和UART6的中断接收和中断发送都正常
    发表于 04-15 06:36

    STM32F030F4 UART1无法进入中断的原因?

    使用STM32F030F4并设定PA2(TX),PA3(RX)为UART 并使用中断接收,却都进不去UART接收中断 但若在主回圈while(1)内加入 printf(“ ”); 却可
    发表于 04-09 07:41

    STM32F302的PB8作为UART3的RXD连接串口模块遇到的问题求解

    STM32F302的PB8作为UART3的RXD连接串口模块。现在问题是: 1、DEBUG模式下,UART3能正常接收。 2、正常运行模式下,UART3无法接收。
    发表于 04-02 07:04

    GD32F103C8T6 Uart3无法发送数据

    GD32F103C8T6是一款由中国的国产芯片厂商GigaDevice生产的单片机芯片,它是一款性价比较高且功能强大的芯片。在GD32F103C8T6中,UART3是其中一个串口通信模
    的头像 发表于 01-09 10:57 493次阅读

    NUC230 TRM手册中定义PA2和PA3可以用UART3,为什么在clk.h中找不到UART3_MODULE定义?

    请问一下各位大大,NUC230 TRM手册中定义PA2和PA3可以用UART3 但我在clk.h中找不到UART3_MODULE定义 请问该如何正常初始化UART3接脚? 谢谢!
    发表于 08-21 06:30

    为什么STM32G030F6P6 UART在勘误手册中未发现说明?

    做了一个STM32G030F6P6实验板,测试UART时发现一个关于接收超时的问题,直接在cubeMX 生成代码中增加receive timeout设置(在STM32G431中就是如此使用,很正常
    发表于 08-07 07:30

    用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?

    想用NUC131单片机UART3作为打印口,但printf没有输出东西,UART10、UART1、UART2作为打印口printf都可以正常输出,请教一下大神们,我的配置是否有问题??
    发表于 06-28 08:41

    NUC230 TRM该如何正常初始化UART3接脚?

    请问一下各位大大,NUC230 TRM手册中定义PA2和PA3可以用UART3 但我在clk.h中找不到UART3_MODULE定义 请问该如何正常初始化UART3接脚?
    发表于 06-28 08:04

    N9H30K的串口修改为UART3后,发现UART3没反应是怎么回事?

    UART3, 添加了两段初程序 outpw(REG_CLK_PCLKEN0, inpw(REG_CLK_PCLKEN0) | (1<<19)); //开打 UART3的时钟
    发表于 06-14 07:06

    NUC230如何使用UART3功能?

    请问一下各位大大,NUC230 TRM手册中定义PA2和PA3可以用UART3 但我在clk.h中找不到UART3_MODULE定义 请问该如何正常初始化UART3接脚?
    发表于 06-13 09:32

    【CW32饭盒派开发板试用体验】2. 使用扩展板串口UART3以及scanf重定向到串口

    【CW32饭盒派开发板试用体验】1. 开箱啦 前言 官方例程提供了对串口的支持,但是默认代码使用的是UART1,扩展板引出来的引脚是UART3,所以修改官方提供的代码
    发表于 05-28 17:09

    imx6ull上的uart3uart6是否支持rs485?

    目前,我正在研究 IMX8dxp 处理器,但我在 fsl-lpuart.c 的 linux 驱动程序中遇到了一些问题。 在我的硬件上,我们想使用硬件 rs485 收发器连接我们的 uart0 端口
    发表于 05-24 07:14

    在V85x上将uart3设置成普通串口收发模式

    由于UART0 被设定为系统dubug 输出(简单来说就是将ttyS0 设定为console),所以使用UART3 作为普通的串口,进行与别的设备通信。
    的头像 发表于 05-17 10:00 636次阅读
    在V85x上将<b class='flag-5'>uart3</b>设置成普通串口收发模式