RM新时代网站-首页

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

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

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

LPC5500_SDK例程:串口DMA發(fā)送+中斷接收

jf_pJlTbmA9 ? 來源:恩智浦MCU加油站 ? 作者:恩智浦MCU加油站 ? 2023-10-30 16:59 ? 次閱讀

LPC5500

串口DMA

LPC5500的SDK中提供了非常豐富的串口例程(如下圖所示):

wKgZomUD4nOAbGGxAAB-3j_-aKk258.png

但是,偏偏沒有串口DMA發(fā)送+中斷接收這種組合。

實話說小編覺得這種組合才是大部分MCU場景中最常用的。尤其是對一些RX數(shù)據(jù)量不大(比如只是解析一些命令)但是TX數(shù)據(jù)量大的應(yīng)用(比如定時,高頻發(fā)送數(shù)據(jù))再合適不過,該架構(gòu)模型簡單,非常容易理解。

本篇文章就手把手教大家分分鐘擼一個DMA發(fā)送+中斷接收的例程:

我們復(fù)制一個dma_transfer例程作為模板,重命名為dma_tx_int_rx(名字無所謂,自己起即可)。打開,編譯下載運行一下,確保原版demo在自己的板子上可以順利的運行,咱們把前期工作都鋪墊好。

下面我們開始改代碼:dma_transfer原版代碼是TX和RX都是dma傳輸,我們只需要將RX改為中斷接收數(shù)據(jù)即可。

首先將USART_TransferCreateHandleDMA函數(shù)修改下,將所有RX DMA有關(guān)的東西去掉,handler填NULL就可以。這樣usart_dma driver就不會處理RX DMA有關(guān)的操作了:

USART_TransferCreateHandleDMA(DEMO_USART,   g_uartDmaHandle, USART_UserCallback, NULL, g_uartTxDmaHandle, NULL);

2. 開啟usart RX中斷,沒啥可說的,常規(guī)操作:

/* Enable RX interrupt. */

USART_EnableInterrupts(DEMO_USART, kUSART_RxLevelInterruptEnable | kUSART_RxErrorInterruptEnable);
EnableIRQ(DEMO_USART_IRQn);

3. 在app層定義(接管)串口硬件中斷,并在中斷中處理串口RX接收到的數(shù)據(jù):

#define DEMO_USART_IRQHandler FLEXCOMM0_IRQHandler
#define DEMO_USART_IRQn     FLEXCOMM0_IRQn



void DEMO_USART_IRQHandler(void)
{
   uint8_t data;
   /* If new data arrived. */
   if ((kUSART_RxFifoNotEmptyFlag | kUSART_RxError | kUSART_RxFifoFullFlag)   USART_GetStatusFlags(DEMO_USART))
   {
       data = USART_ReadByte(DEMO_USART);
       PRINTF("usart rx interrupt:%crn", data);

       if(data == 's')

       {

          /* Send g_tipString out. */

          xfer.data     = g_tipString;

          xfer.dataSize = sizeof(g_tipString) - 1;


          g_uartDmaHandle.txState = kUSART_TxIdle;

          USART_TransferSendDMA(DEMO_USART,  g_uartDmaHandle,  xfer);

      }

   }

   if ((0U != (DEMO_USART->INTENSET    USART_INTENSET_TXIDLEEN_MASK))    (0U != (DEMO_USART->INTSTAT   USART_INTSTAT_TXIDLE_MASK)))

   {

      USART_TransferDMAHandleIRQ(DEMO_USART,  g_uartDmaHandle);

   }

}

注意,這里需要在硬件串口中斷里判斷TXIDLE中斷,并調(diào)用USART_TransferDMAHandleIRQ。這是仿照fsl_usart_dma.c中的寫法(fsl_usart_dma中開啟了TXIDLE中斷,并使用TXIDLE中斷來調(diào)用dma handle用戶回調(diào)函數(shù),現(xiàn)在硬件串口中斷已經(jīng)被app層接管,所以我們同樣要實現(xiàn)這部分功能)。

4. 測試:改好代碼,下載運行:當(dāng)串口敲入任意鍵時候,程序都會回顯接收到數(shù)據(jù),當(dāng)按鍵”s”時,會調(diào)用USART_TransferSendDMA函數(shù)使用DMA發(fā)送一串?dāng)?shù)據(jù),并進(jìn)入DMA發(fā)送完成回調(diào)函數(shù)。

wKgaomUD4nSAYFR0AAB7-_e9_JE059.png

代碼清單

以下是完整代碼清單(可以直接復(fù)制到usart_dma_transfer.c里運行):

/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.

* Copyright 2016-2017 NXP

* All rights reserved.

*

* SPDX-License-Identifier:  BSD-3-Clause

*/

#include "pin_mux.h"

#include "board.h"

#include "fsl_usart.h"

#include "fsl_usart_dma.h"

#include "fsl_dma.h"

#include "fsl_debug_console.h"


#include 

#include "fsl_power.h"


#define DEMO_USART                USART0

#define DEMO_USART_CLK_SRC        kCLOCK_Flexcomm0

#define DEMO_USART_CLK_FREQ       CLOCK_GetFlexCommClkFreq(0U)

#define USART_RX_DMA_CHANNEL      4

#define USART_TX_DMA_CHANNEL      5

#define EXAMPLE_UART_DMA_BASEADDR DMA0

#define DEMO_USART_IRQHandler FLEXCOMM0_IRQHandler

#define DEMO_USART_IRQn       FLEXCOMM0_IRQn

#define ECHO_BUFFER_LENGTH 8


usart_transfer_t xfer;

usart_dma_handle_t g_uartDmaHandle;

dma_handle_t g_uartTxDmaHandle;

uint8_t g_tipString[]                  = "This string is send from UART_DMArn";

#define kUSART_TxIdle 0

void USART_UserCallback(USART_Type *base, usart_dma_handle_t *handle, status_t status, void *userData)

{

   userData = userData;

   if (kStatus_USART_TxIdle == status)

   {

       PRINTF("USART_UserCallback, status:0x%Xrn", status);

   }

}

void DEMO_USART_IRQHandler(void)
{
   uint8_t data;
   /* If new data arrived. */
   if ((kUSART_RxFifoNotEmptyFlag | kUSART_RxError | kUSART_RxFifoFullFlag)   USART_GetStatusFlags(DEMO_USART))
   {
       data = USART_ReadByte(DEMO_USART);
       PRINTF("usart rx interrupt:%crn", data);

       if(data == 's')

       {

          /* Send g_tipString out. */

          xfer.data     = g_tipString;

          xfer.dataSize = sizeof(g_tipString) - 1;


          g_uartDmaHandle.txState = kUSART_TxIdle;

          USART_TransferSendDMA(DEMO_USART,  g_uartDmaHandle,  xfer);

      }

   }

   if ((0U != (DEMO_USART->INTENSET    USART_INTENSET_TXIDLEEN_MASK))    (0U != (DEMO_USART->INTSTAT   USART_INTSTAT_TXIDLE_MASK)))

   {

      USART_TransferDMAHandleIRQ(DEMO_USART,  g_uartDmaHandle);

   }

}

int main(void)

{

   usart_config_t    config;

  

   /* set BOD VBAT level to 1.65V */

   POWER_SetBodVbatLevel(kPOWER_BodVbatLevel1650mv, kPOWER_BodHystLevel50mv, false);

   /* attach 12 MHz clock to FLEXCOMM0 (debug console) */

   CLOCK_AttachClk(kFRO12M_to_FLEXCOMM0);

  

   BOARD_InitBootPins();

   BOARD_InitBootClocks();

   BOARD_InitDebugConsole();

  

   PRINTF("USART: TX DMA, RX INTERRUPTrn");

   PRINTF("press 's' for DMA TX tranmsitrn");

  

   USART_GetDefaultConfig( config);

   config.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;

   config.enableTx     = true;

   config.enableRx     = true;

  

   USART_Init(DEMO_USART,  config, DEMO_USART_CLK_FREQ);

  

   /* Configure DMA. */

   DMA_Init(EXAMPLE_UART_DMA_BASEADDR);

   DMA_EnableChannel(EXAMPLE_UART_DMA_BASEADDR, USART_TX_DMA_CHANNEL);

   DMA_EnableChannel(EXAMPLE_UART_DMA_BASEADDR, USART_RX_DMA_CHANNEL);

   DMA_CreateHandle( g_uartTxDmaHandle, EXAMPLE_UART_DMA_BASEADDR, USART_TX_DMA_CHANNEL);

   USART_TransferCreateHandleDMA(DEMO_USART,  g_uartDmaHandle, USART_UserCallback, NULL,  g_uartTxDmaHandle, NULL);

 

   /* Send g_tipString out. */

   xfer.data     = g_tipString;

   xfer.dataSize = sizeof(g_tipString) - 1;

   USART_TransferSendDMA(DEMO_USART,  g_uartDmaHandle,  xfer);

  

   /* Enable RX interrupt. */

   USART_EnableInterrupts(DEMO_USART, kUSART_RxLevelInterruptEnable | kUSART_RxErrorInterruptEnable);

   EnableIRQ(DEMO_USART_IRQn);

來源:恩智浦MCU加油站

審核編輯:湯梓紅

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

    關(guān)注

    5

    文章

    898

    瀏覽量

    41470
  • 串口
    +關(guān)注

    關(guān)注

    14

    文章

    1551

    瀏覽量

    76421
  • dma
    dma
    +關(guān)注

    關(guān)注

    3

    文章

    560

    瀏覽量

    100544
  • SDK
    SDK
    +關(guān)注

    關(guān)注

    3

    文章

    1035

    瀏覽量

    45899
收藏 人收藏

    評論

    相關(guān)推薦

    如何使用DMA的方式進(jìn)行串口發(fā)送接收

    K210_kendryte IDE_UART_DMA本實驗基于kendryte standalone SDK實現(xiàn)K210的C語言裸機開發(fā)。使用DMA的方式進(jìn)行串口
    發(fā)表于 01-20 08:10

    stm32串口dma發(fā)送/接收程序

    串口可以配置成用DMA的方式接收數(shù)據(jù),不過DMA需要定長才能產(chǎn)生接收中斷,如何
    發(fā)表于 11-27 09:41 ?3w次閱讀
    stm32<b class='flag-5'>串口</b><b class='flag-5'>dma</b><b class='flag-5'>發(fā)送</b>/<b class='flag-5'>接收</b>程序

    串口中斷接收發(fā)送的C51程序免費下載

    這是一個單片機C51串口接收中斷)和發(fā)送例程,可以用來測試51單片機的中斷
    發(fā)表于 04-25 18:27 ?4次下載
    <b class='flag-5'>串口中斷</b><b class='flag-5'>接收</b>和<b class='flag-5'>發(fā)送</b>的C51程序免費下載

    STM32串口中斷 DMA接收的幾點注意地方

    STM32串口中斷、DMA接收的幾點注意地方
    的頭像 發(fā)表于 03-04 13:57 ?2.1w次閱讀

    如何解決PWM使用的DMA通道與串口接收DMA通道撞車問題

    項目做到一半,碰到個尷尬問題:PWM使用的DMA通道與串口接收DMA通道撞車了,咋辦?考慮一下,決定放棄idle中斷+
    的頭像 發(fā)表于 02-16 11:35 ?2769次閱讀
    如何解決PWM使用的<b class='flag-5'>DMA</b>通道與<b class='flag-5'>串口</b><b class='flag-5'>接收</b>的<b class='flag-5'>DMA</b>通道撞車問題

    PWM使用的DMA通道與串口接收DMA通道撞車了,咋辦?

    項目做到一半,碰到個尷尬問題:PWM使用的DMA通道與串口接收DMA通道撞車了,咋辦?考慮一下,決定放棄idle中斷+
    發(fā)表于 04-27 06:00 ?12次下載
    PWM使用的<b class='flag-5'>DMA</b>通道與<b class='flag-5'>串口</b><b class='flag-5'>接收</b>的<b class='flag-5'>DMA</b>通道撞車了,咋辦?

    STM32 串口使用IDLE中斷+DMA接收(HAL庫函數(shù))

    STM32 串口使用IDLE中斷+DMA接收(HAL庫函數(shù))一、開發(fā)環(huán)境單片機型號:STM32H743IIT6工程配置環(huán)境:STM32CubeMX 6.3.0固件庫:STM32Cube
    發(fā)表于 12-02 21:06 ?41次下載
    STM32 <b class='flag-5'>串口</b>使用IDLE<b class='flag-5'>中斷</b>+<b class='flag-5'>DMA</b><b class='flag-5'>接收</b>(HAL庫函數(shù))

    STM32 HAL CubeMX 串口IDLE接收空閑中斷+DMA

    關(guān)于DMA原理部分講解,及CubeMx配置部分,請參考該文章【STM32】HAL庫 STM32CubeMX教程十一—DMA (串口DMA發(fā)送
    發(fā)表于 12-20 19:39 ?31次下載
    STM32 HAL CubeMX <b class='flag-5'>串口</b>IDLE<b class='flag-5'>接收</b>空閑<b class='flag-5'>中斷</b>+<b class='flag-5'>DMA</b>

    STM32—無需中斷來實現(xiàn)使用DMA接收串口數(shù)據(jù)

    本節(jié)目標(biāo):通過DMA,無需中斷,接收不定時長的串口數(shù)據(jù) 描述:當(dāng)在串口多數(shù)據(jù)傳輸下,CPU會產(chǎn)生多次
    發(fā)表于 12-24 19:01 ?8次下載
    STM32—無需<b class='flag-5'>中斷</b>來實現(xiàn)使用<b class='flag-5'>DMA</b><b class='flag-5'>接收</b><b class='flag-5'>串口</b>數(shù)據(jù)

    STM32DMA+串口完成中斷 接收發(fā)送

    最近在使用STM32F103單片機進(jìn)行串口接收處理不定長數(shù)據(jù)測試時有兩個需求。1、需要接收不定長的數(shù)據(jù)。2、提高串口響應(yīng)速度。一直看過很多貼子關(guān)于
    發(fā)表于 12-24 19:03 ?5次下載
    STM32<b class='flag-5'>DMA</b>+<b class='flag-5'>串口</b>完成<b class='flag-5'>中斷</b> <b class='flag-5'>接收</b>和<b class='flag-5'>發(fā)送</b>

    stm32 發(fā)送完數(shù)據(jù)后 串口繼續(xù)發(fā)送_STM32之串口DMA接收不定長數(shù)據(jù)

    引言在使用stm32或者其他單片機的時候,會經(jīng)常使用到串口通訊,那么如何有效地接收數(shù)據(jù)呢?假如這段數(shù)據(jù)是不定長的有如何高效接收呢?同學(xué)A:數(shù)據(jù)來了就會進(jìn)入串口中斷,在
    發(fā)表于 12-24 19:17 ?8次下載
    stm32 <b class='flag-5'>發(fā)送</b>完數(shù)據(jù)后 <b class='flag-5'>串口</b>繼續(xù)<b class='flag-5'>發(fā)送</b>_STM32之<b class='flag-5'>串口</b><b class='flag-5'>DMA</b><b class='flag-5'>接收</b>不定長數(shù)據(jù)

    STM32單片機串口空閑中斷+DMA接收不定長數(shù)據(jù)

    在上一篇文章STM32單片機串口空閑中斷接收不定長數(shù)據(jù)中介紹了利用串口空閑中斷接收不定長數(shù)據(jù),這
    發(fā)表于 12-27 19:24 ?18次下載
    STM32單片機<b class='flag-5'>串口</b>空閑<b class='flag-5'>中斷</b>+<b class='flag-5'>DMA</b><b class='flag-5'>接收</b>不定長數(shù)據(jù)

    單片機接收不定長的數(shù)據(jù),最優(yōu)解是DMA+串口空閑中斷

    如果單片機不支持串口空閑中斷DMA,可以參考之前寫的,串口只用接收中斷,完成不定長的分包。這里
    發(fā)表于 12-28 19:26 ?25次下載
    單片機<b class='flag-5'>接收</b>不定長的數(shù)據(jù),最優(yōu)解是<b class='flag-5'>DMA</b>+<b class='flag-5'>串口</b>空閑<b class='flag-5'>中斷</b>

    串口DMA發(fā)送+中斷接收例程

    LPC5500SDK中提供了非常豐富的串口例程(如下圖所示)。
    的頭像 發(fā)表于 07-21 09:14 ?2734次閱讀

    STM32串口中斷DMA接收常見的幾個問題

    STM32串口中斷DMA接收常見的幾個問題
    的頭像 發(fā)表于 10-26 16:41 ?3535次閱讀
    STM32<b class='flag-5'>串口中斷</b>及<b class='flag-5'>DMA</b><b class='flag-5'>接收</b>常見的幾個問題
    RM新时代网站-首页