0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

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

冬至子 ? 來(lái)源:balabala ? 作者:balabala ? 2023-10-13 14:14 ? 次閱讀

看了大家對(duì)F030復(fù)用串口的疑惑,這里繼續(xù)給出“當(dāng)同時(shí)使用UART3~UART6中的多個(gè)串口時(shí),由于其中斷響應(yīng)函數(shù)都是同一個(gè),需要自己在中斷函數(shù)USART3_6_IRQHandler() 中判斷是來(lái)自哪個(gè)串口的中斷。”這個(gè)問(wèn)題的解決辦法。這里使用的是串口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();
}

其中就是加入了獲取串口的判斷,執(zhí)行不同中斷ISR。還有一點(diǎn)需要注意,F(xiàn)030RC的默認(rèn)DMA通道是Cxs 0級(jí)別的中斷,如果需要使用串口的DMA中斷,需要在DMA初始化的時(shí)候添加__HAL_DMA1_REMAP()函數(shù),

1.jpg

據(jù)需要選擇不同串口即可,下面是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); //添加這兩個(gè)即可
__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);
}

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 串口中斷
    +關(guān)注

    關(guān)注

    0

    文章

    64

    瀏覽量

    13824
  • USART串口
    +關(guān)注

    關(guān)注

    0

    文章

    32

    瀏覽量

    6791
  • HAL庫(kù)
    +關(guān)注

    關(guān)注

    1

    文章

    114

    瀏覽量

    6111
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    在NXP源碼基礎(chǔ)上如何適配ELF 1開(kāi)發(fā)板的UART功能

    UART接口供開(kāi)發(fā)者使用,具體包括UART1、UART2、UART3以及UART7。其中UART
    的頭像 發(fā)表于 09-29 11:49 ?208次閱讀
    在NXP源碼基礎(chǔ)上如何適配ELF 1開(kāi)發(fā)板的<b class='flag-5'>UART</b>功能

    ElfBoard技術(shù)貼|如何在NXP源碼基礎(chǔ)上適配ELF 1開(kāi)發(fā)板的UART功能

    了4路UART接口供開(kāi)發(fā)者使用,具體包括UART1、UART2、UART3以及UART7。其中UART
    的頭像 發(fā)表于 09-25 13:56 ?2153次閱讀
    ElfBoard技術(shù)貼|如何在NXP源碼基礎(chǔ)上適配ELF 1開(kāi)發(fā)板的<b class='flag-5'>UART</b>功能

    3章_UART 開(kāi)發(fā)基礎(chǔ)

    3章_UART 開(kāi)發(fā)基礎(chǔ)
    的頭像 發(fā)表于 06-29 14:27 ?528次閱讀
    第<b class='flag-5'>3</b>章_<b class='flag-5'>UART</b> 開(kāi)發(fā)基礎(chǔ)

    使用通用串口模塊下載CW32F030芯片的方法

    芯片數(shù)據(jù)手冊(cè)里4.3節(jié),有表明BOOTLOADER下載時(shí),通過(guò)UART1(也是SWDR接口)PA13PA14下載。 在CW32F030的用戶手冊(cè)里有,2.6節(jié)有講明BOOT引腳在ISP下載時(shí)需要的配置定義。 因此,在啟動(dòng)時(shí),需要
    的頭像 發(fā)表于 05-31 17:30 ?479次閱讀
    使用通用串口模塊下載CW32<b class='flag-5'>F030</b><b class='flag-5'>芯片</b>的方法

    用stm32cubeide生成的STM32G030F6P6代碼只要一開(kāi)中斷,任何中斷程序都會(huì)跑飛怎么解決?

    求助,用stm32cubeide生成的STM32G030F6P6代碼只要一開(kāi)中斷,任何中斷程序都會(huì)跑飛.這個(gè)問(wèn)題是在我升級(jí)stm32cubeide后出現(xiàn)的,以前用的正常,升級(jí)后重新編譯后出現(xiàn)這個(gè)現(xiàn)象,但是現(xiàn)在重新安裝低版本的也不行了。新建工程也不行
    發(fā)表于 05-27 07:45

    STM8S207R8T6測(cè)試程序, UART1,UART3均無(wú)輸出的原因?

    剛買了一個(gè)板子, 測(cè)試程序, UART1,UART3均無(wú)輸出, 量測(cè)PD5,PD6, 高阻態(tài)。 不知道哪位知道什么原因, 剛接觸STM8, 不熟悉, 先謝過(guò)。
    發(fā)表于 05-17 06:33

    stm32f030f4有沒(méi)有uart喚醒功能?

    stm32f030f4 value line 的產(chǎn)品線,在手冊(cè)中對(duì)能否用uart 喚醒講的有點(diǎn)模糊,庫(kù)函數(shù)中對(duì)uart喚醒功能的函數(shù)都做了屏蔽,請(qǐng)問(wèn)用過(guò)的攻城獅,這顆粒到底能否使用uart
    發(fā)表于 05-10 07:56

    請(qǐng)問(wèn)stm32f0系列芯片12位ADC的實(shí)際有效為(ENOB)是多少?

    請(qǐng)問(wèn)f030系列芯片12位ADC的實(shí)際有效為(ENOB)是多少?我知道官方數(shù)據(jù)手冊(cè)上沒(méi)有,而f3系列的官方手冊(cè)上有具體數(shù)值,請(qǐng)問(wèn)有人知道嗎?
    發(fā)表于 04-22 07:40

    STM32F030CCT6 UART4接收阻塞模式幾分鐘后無(wú)法收到數(shù)據(jù)是哪里的問(wèn)題?

    芯片:STM32F030CCT6 庫(kù)版本:STM32Cube_FW_F0_V1.11.0 問(wèn)題:UART4,接收阻塞模式幾分鐘后無(wú)法收到數(shù)據(jù)。
    發(fā)表于 04-17 07:01

    STM32F030CCT6調(diào)5個(gè)串口,UART2,3,5進(jìn)不了接收中斷怎么解決?

    最近在調(diào)試STM32F030CCT6,需要用到5個(gè)串口,使用STM32CubeMX創(chuàng)建的工程,使用中斷接收和中斷發(fā)送的處理方式。但是調(diào)試發(fā)現(xiàn),UART1和UART6的中斷接收和中斷發(fā)送都正常
    發(fā)表于 04-15 06:36

    STM32F030F4 UART1無(wú)法進(jìn)入中斷的原因?

    使用STM32F030F4并設(shè)定PA2(TX),PA3(RX)為UART 并使用中斷接收,卻都進(jìn)不去UART接收中斷 但若在主回圈while(1)內(nèi)加入 printf(“ ”); 卻可
    發(fā)表于 04-09 07:41

    STM32F302的PB8作為UART3的RXD連接串口模塊遇到的問(wèn)題求解

    STM32F302的PB8作為UART3的RXD連接串口模塊?,F(xiàn)在問(wèn)題是: 1、DEBUG模式下,UART3能正常接收。 2、正常運(yùn)行模式下,UART3無(wú)法接收。
    發(fā)表于 04-02 07:04

    使用STM32CubeProgrammer燒寫總是提示失敗的原因?

    想使用STM32F030 串口UART2,作為自舉功能,進(jìn)行燒寫。 現(xiàn)在硬件設(shè)計(jì)的時(shí)候,pin腳連接到了PA2PA3,使用STM32CubeProgrammer燒寫總是提示失敗。 Error
    發(fā)表于 04-01 06:47

    GD32F103C8T6 Uart3無(wú)法發(fā)送數(shù)據(jù)

    GD32F103C8T6是一款由中國(guó)的國(guó)產(chǎn)芯片廠商GigaDevice生產(chǎn)的單片機(jī)芯片,它是一款性價(jià)比較高且功能強(qiáng)大的芯片。在GD32F103C8T
    的頭像 發(fā)表于 01-09 10:57 ?1428次閱讀

    CS32F031芯片UART2無(wú)法使用

    最近在使用CS32F031C8T6芯片做開(kāi)發(fā),在使用UART2去給下位機(jī)通訊時(shí)發(fā)現(xiàn)無(wú)任何數(shù)據(jù)發(fā)送也接收不到任何數(shù)據(jù)。使用的SDK是之前cs32f030的,想請(qǐng)教cs32
    發(fā)表于 11-01 11:54