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

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

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

恩智浦MCU加油站 ? 來源:恩智浦MCU加油站 ? 作者:恩智浦MCU加油站 ? 2022-07-21 09:18 ? 次閱讀

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

264e7c58-088d-11ed-ba43-dac502259ad0.png

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

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

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

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

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

首先將USART_TransferCreateHandleDMA函數修改下,將所有RX DMA有關的東西去掉,handler填NULL就可以。這樣usart_dmadriver就不會處理RX DMA有關的操作了:


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接收到的數據:


#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:%c ", 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中斷,并調用USART_TransferDMAHandleIRQ。這是仿照fsl_usart_dma.c中的寫法(fsl_usart_dma中開啟了TXIDLE中斷,并使用TXIDLE中斷來調用dma handle用戶回調函數,現在硬件串口中斷已經被app層接管,所以我們同樣要實現這部分功能)。

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

2664fad2-088d-11ed-ba43-dac502259ad0.png

代碼清單

以下是完整代碼清單(可以直接復制到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_DMA ";

#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%X ", 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:%c ", 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 INTERRUPT ");

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

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

while(1);

}

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

文章出處:【微信公眾號:恩智浦MCU加油站】歡迎添加關注!文章轉載請注明出處。

審核編輯:彭靜
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • 串口
    +關注

    關注

    14

    文章

    1539

    瀏覽量

    75921
  • 函數
    +關注

    關注

    3

    文章

    4263

    瀏覽量

    62244
  • dma
    dma
    +關注

    關注

    3

    文章

    556

    瀏覽量

    100241
  • 接收數據
    +關注

    關注

    0

    文章

    7

    瀏覽量

    6065

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

文章出處:【微信號:NXP_SMART_HARDWARE,微信公眾號:恩智浦MCU加油站】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    如何實現STM32 USART DMA發(fā)送中斷接收?

    如何實現STM32 USART DMA發(fā)送中斷接收?
    發(fā)表于 12-10 07:37

    CH32V307有對應的串口+DMA傳輸中斷接收,主動發(fā)送的例子嗎?

    官方給的例程里 串口+DMA 好像只是一個簡單的演示,請問有對應的 串口+DMA 傳輸 中斷接收,主動發(fā)
    發(fā)表于 06-20 06:01

    請問串口的接收發(fā)送模式如果需要用中斷接收+DMA發(fā)送該如何配置?

    請問串口的接收發(fā)送模式如果需要用中斷接收+DMA發(fā)送該如何配置? RT_DEVICE_OFLAG_RDWR|RT_DEVICE_FLAG_I
    發(fā)表于 02-09 14:04

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

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

    如何使用STM32單片機實現DMA的同時發(fā)送接收

    在SPI通信中,可以同時開啟發(fā)送接收DMA請求,自動數據的發(fā)送接收,完成數據的交換 基本步驟是: 1. 配置好SPI相應引腳
    發(fā)表于 12-07 15:26 ?1w次閱讀

    串口中斷接收發(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中斷+dma的串口不定長數
    的頭像 發(fā)表于 02-16 11:35 ?2686次閱讀
    如何解決PWM使用的<b class='flag-5'>DMA</b>通道與串口<b class='flag-5'>接收</b>的<b class='flag-5'>DMA</b>通道撞車問題

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

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

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

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

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

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

    STM32—無需中斷來實現使用DMA接收串口數據

    本節(jié)目標:通過DMA,無需中斷,接收不定時長的串口數據 描述:當在串口多數據傳輸下,CPU會產生多次中斷接收串口數據,這樣會大大地降低C
    發(fā)表于 12-24 19:01 ?8次下載
    STM32—無需<b class='flag-5'>中斷</b>來實現使用<b class='flag-5'>DMA</b><b class='flag-5'>接收</b>串口數據

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

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

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

    LPC5500_SDK例程:串口DMA發(fā)送+中斷接收
    的頭像 發(fā)表于 10-30 16:59 ?982次閱讀
    LPC5500_SDK<b class='flag-5'>例程</b>:串口<b class='flag-5'>DMA</b><b class='flag-5'>發(fā)送</b>+<b class='flag-5'>中斷</b><b class='flag-5'>接收</b>

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

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