女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

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

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

3天內不再提示

UART需要使用DMA發送嗎 ?

黃工的嵌入式技術圈 ? 來源:黃工的嵌入式技術圈 ? 2020-03-07 16:57 ? 次閱讀

DMA一種在嵌入式實時任務處理中常用的功能。

UART發送數據包,使用DMA方式能大量減輕CPU處理的時間,使其CPU資源不被大量浪費,尤其在UART收發大量數據包(如高頻率收發指令)時具有明顯優勢。

Ⅰ簡述DMA

DMA:Direct Memory Access,直接內存存取/訪問。簡單來說就是內存RAM直接和其他設備(外設)進行數據交互,而不需要CPU參與的一種控制器

DMA它允許不同速度的硬件裝置來溝通,而不需要依賴于 CPU 的大量中斷負載。否則,CPU 需要從來源把每一片段的數據復制到暫存器,然后把它們再次寫回到新的地方。在這個時間中,CPU 對于其他的工作來說就無法使用。

ⅡDMA優點

DMA在系統中的角色好比一個公司的員工,CPU好比是公司的老板。

老板想要寄送一個快遞到北京,只需要一個口令安排員工即可,具體填寫快遞單號、物流、派送等一系列工作老板不用關心。最后快遞被對方收到,通知一聲老板即可。

回到UART發送數據,同樣的道理,CPU只需要簡單的操作(類似上面的“安排”),就可把一串數據包丟給DMA直接發送,最后發送完成,收到一個發送完成中斷,通知CPU發送完成即可。

說到這里相信大部分人都明白了,老板可以親自開車或者坐飛機送快遞,完成這件事情,但會耽擱老板很多時間。

同樣,如果我們使用UART自己發送,CPU就會不停仲裁發送結果,占據CPU大量資源。

RTOS中,特別是有大量任務需要處理的時候,UART使用DMA發送就會帶來很大方便。使用裸機運行的相同,尤為突出。

ⅢUART使用DMA發送配置

本文使用STM32F4 MCU、標準外設庫為例給大家簡單講述一下配置。


1.USART配置

USART(COM)宏定義:

/* COMM通信 */ #define COMM_COM USART2 #define COMM_COM_CLK RCC_APB1Periph_USART2 #define COMM_COM_TX_GPIO_CLK RCC_AHB1Periph_GPIOD //UART TX #define COMM_COM_TX_PIN GPIO_Pin_5 #define COMM_COM_TX_GPIO_PORT GPIOD #define COMM_COM_TX_SOURCE GPIO_PinSource5 #define COMM_COM_TX_AF GPIO_AF_USART2 #define COMM_COM_RX_GPIO_CLK RCC_AHB1Periph_GPIOD //UART RX #define COMM_COM_RX_PIN GPIO_Pin_6 #define COMM_COM_RX_GPIO_PORT GPIOD #define COMM_COM_RX_SOURCE GPIO_PinSource6 #define COMM_COM_RX_AF GPIO_AF_USART2 #define COMM_COM_IRQn USART2_IRQn #define COMM_COM_Priority 9 //優先級 #define COMM_COM_BaudRate 115200 //波特率 #define COMM_COM_IRQHandler USART2_IRQHandler //中斷函數接口(見stm32f4xx_it.c)

USART配置:

/************************************************函數名稱 : USART_COMM_Configuration功 能 : 通信串口配置參 數 : 無返 回 值 : 無作 者 : strongerHuang*************************************************/ void USART_COMM_Configuration(void){ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* 時鐘配置 */ RCC_AHB1PeriphClockCmd(COMM_COM_TX_GPIO_CLK | COMM_COM_RX_GPIO_CLK, ENABLE); if((USART1 == COMM_COM) || (USART6 == COMM_COM)) RCC_APB2PeriphClockCmd(COMM_COM_CLK, ENABLE); else RCC_APB1PeriphClockCmd(COMM_COM_CLK, ENABLE); /* 復用配置 */ GPIO_PinAFConfig(COMM_COM_TX_GPIO_PORT, COMM_COM_TX_SOURCE, COMM_COM_TX_AF); GPIO_PinAFConfig(COMM_COM_RX_GPIO_PORT, COMM_COM_RX_SOURCE, COMM_COM_RX_AF); /* 引腳配置 */ GPIO_InitStructure.GPIO_Pin = COMM_COM_TX_PIN; //USART Tx GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //復用模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(COMM_COM_TX_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = COMM_COM_RX_PIN; //USART Rx GPIO_Init(COMM_COM_RX_GPIO_PORT, &GPIO_InitStructure); /* NVIC配置 */ NVIC_InitStructure.NVIC_IRQChannel = COMM_COM_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = COMM_COM_Priority; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* USART配置 */ USART_InitStructure.USART_BaudRate = COMM_COM_BaudRate; //波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //傳輸位數 USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位 USART_InitStructure.USART_Parity = USART_Parity_No ; //校驗位 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發功能 USART_Init(COMM_COM, &USART_InitStructure); USART_ClearFlag(COMM_COM, USART_FLAG_RXNE | USART_FLAG_TC); USART_ITConfig(COMM_COM, USART_IT_RXNE, ENABLE); //接收中斷 USART_DMACmd(COMM_COM, USART_DMAReq_Tx, ENABLE); //使能DMA USART_Cmd(COMM_COM, ENABLE); //使能USART }

2.DMA配置

DMA宏定義:

/* COMM_DMA */ #define COMM_DR_ADDRESS ((uint32_t)USART2 + 0x04) #define COMM_DMA DMA1 #define COMM_DMA_CLK RCC_AHB1Periph_DMA1 #define COMM_TX_DMA_CHANNEL DMA_Channel_4 #define COMM_TX_DMA_STREAM DMA1_Stream6 #define COMM_TX_DMA_FLAG_TCIF DMA_FLAG_TCIF6 #define COMM_TX_DMA_IRQn DMA1_Stream6_IRQn #define COMM_TX_DMA_Priority 8 //優先級 #define COMM_TX_DMA_IRQHandler DMA1_Stream6_IRQHandler //中斷函數接口(見stm32f4xx_it.c) #define COMM_TX_DMA_IT_TCIF DMA_IT_TCIF6

DMA配置:

/************************************************函數名稱 : USART_COMM_DMA_Configuration功 能 : 通信串口的DMA配置參 數 : 無返 回 值 : 無作 者 : strongerHuang*************************************************/ void USART_COMM_DMA_Configuration(void){ DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* 使能時鐘 */ RCC_AHB1PeriphClockCmd(COMM_DMA_CLK, ENABLE); /* NVIC配置 */ NVIC_InitStructure.NVIC_IRQChannel = COMM_TX_DMA_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = COMM_TX_DMA_Priority; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* DMA配置 */ DMA_DeInit(COMM_TX_DMA_STREAM); DMA_InitStructure.DMA_Channel = COMM_TX_DMA_CHANNEL; //DMA通道 DMA_InitStructure.DMA_PeripheralBaseAddr = COMM_DR_ADDRESS; //外設地址 DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)0; //內存地址(待傳入參數) DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //傳輸方向 DMA_InitStructure.DMA_BufferSize = 0; //傳輸長度(待傳入參數) DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外設遞增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //內存遞增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //數據寬度 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //循環模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //優先級 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(COMM_TX_DMA_STREAM, &DMA_InitStructure); DMA_ClearFlag(COMM_TX_DMA_STREAM, COMM_TX_DMA_FLAG_TCIF); DMA_ITConfig(COMM_TX_DMA_STREAM, DMA_IT_TC, ENABLE); //使能DMA傳輸完成中斷 DMA_Cmd(COMM_TX_DMA_STREAM, DISABLE); //初始化禁止 } ⅣDMA發送UART數據包

DMA發送函數:

/************************************************函數名稱 : COMM_SendBufByDMA功 能 : 通信串口通過DMA發送數據參 數 : Buf ------ 數據(地址) Length --- 數據長度(字節)返 回 值 : 無作 者 : strongerHuang*************************************************/ void COMM_SendBufByDMA(uint8_t *Buf, uint16_t Length){ DMA_Cmd(COMM_TX_DMA_STREAM, DISABLE); //關閉DMA //內存地址 DMA_MemoryTargetConfig(COMM_TX_DMA_STREAM, (uint32_t)Buf, DMA_Memory_0); DMA_SetCurrDataCounter(COMM_TX_DMA_STREAM, Length); //設置DMA傳輸長度 DMA_Cmd(COMM_TX_DMA_STREAM, ENABLE); //使能DMA }

細心的朋友會發現,這個發送函數其實很簡單,當然,這里是使用STM32F4芯片,其他芯片也差不多,原理類似。 HAL庫同樣可以完成。

關于DMA發送完成中斷,可根據實際情況,如果使用RTOS,一般發送數據是一個任務,這個任務會OS等待(檢測)發送完成信號(即DMA發送完成中斷)。

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

    關注

    68

    文章

    11033

    瀏覽量

    215996
  • uart
    +關注

    關注

    22

    文章

    1268

    瀏覽量

    103253
  • dma
    dma
    +關注

    關注

    3

    文章

    572

    瀏覽量

    102315
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    如何才能拿到UART通過DMA收取回來的數據呢?

    你好,我想詢問一下UART使用DMA時收取數據的代碼。之前我是用的是非DMA模式,使用的函數是CyU3PUartReceiveBytes,但是其處理速度不符合我的要求。因此我使用DMA
    發表于 05-22 08:31

    為什么無法使用Lpuart_Uart_Ip_ 發送任何數據回調中的AsyncSend?

    我已經實現了基于 LPUART 的 DMA ,我可以發送使用 Lpuart_Uart_Ip_ 接收的數據同步發送 in lpuart_6_callback , 但是,我無法
    發表于 04-11 07:51

    stm32 DMA串口接收到數組,數組元素順序錯亂怎么解決?

    配置DMA循環模式,使用HAL_UART_Receive_DMA(&huart1,buffer,4)函數將串口數據循環發送到4個元素的buffer數組內,上位機20ms發送一次
    發表于 03-12 08:02

    DMA發送函數只能被調用一次是怎么回事?

    逐步debug DMA發送函數,HAL_UART Transmit DMA,發現函數會對串口句柄的一個狀態位,gState 進行判斷,只有在 huart->gState==HAL
    發表于 03-12 07:37

    STM32H743 UART DMA接收不到數據,為什么?

    failed!\\n\", \"uart3\"); return RT_ERROR; } /* 以 DMA 接收及輪詢發送方式打開串口設備
    發表于 02-19 06:14

    開源直接用!UDP-UART數據透傳來了

    UDP連接將數據發送到遠程設備,然后將這些數據通過UART接口發送到本地設備。 這種通信方式在需要將遠程設備的數據傳輸到本地設備時非常有用,例如在遠程監控和遠程控制系統中。 ▼ UDP
    的頭像 發表于 02-05 17:14 ?295次閱讀
    開源直接用!UDP-<b class='flag-5'>UART</b>數據透傳來了

    雅特力AT32F402/F405 DMA使用指南

    通道都支持外設的DMA請求映射到任意通道上。圖1.DMA控制器架構DMAMUX簡介對于如何將外設的DMA請求映射到任意的數據流通道上,就需要使用到DMAMUX。DM
    的頭像 發表于 11-20 01:03 ?863次閱讀
    雅特力AT32F402/F405 <b class='flag-5'>DMA</b>使用指南

    DMA是什么?詳細介紹

    系統性能。 DMA(直接內存訪問)概述 1. DMA的定義 直接內存訪問(DMA)是一種硬件特性,允許外圍設備直接讀寫系統內存,而不需要CPU的直接控制。這種技術主要用于高速數據傳輸,
    的頭像 發表于 11-11 10:49 ?1.7w次閱讀

    MSPM0 UART通信中DMA和Ring Buffer環形緩沖的應用

    電子發燒友網站提供《MSPM0 UART通信中DMA和Ring Buffer環形緩沖的應用.pdf》資料免費下載
    發表于 09-05 11:01 ?0次下載
    MSPM0 <b class='flag-5'>UART</b>通信中<b class='flag-5'>DMA</b>和Ring Buffer環形緩沖的應用

    揭秘車載VCU項目之外掛界的“大哥”DMA

    引腳配置此實例選擇CAN0進行配置。三、外設配置對于DMA,其采用的固定映射,對于通道0至通道15,其映射一部分外設,通道16至通道31映射一部分外設,所以對于外設要使DMA,也需要
    的頭像 發表于 07-30 08:11 ?1251次閱讀
    揭秘車載VCU項目之外掛界的“大哥”<b class='flag-5'>DMA</b>

    RL78系列MCU DMAUART中的使用

    對于RL78系列的MCU,為了提高運行效率,減少CPU的占用,建議UART數據收發使用DMA功能。DMA(Direct Memory Access)是RL78 MCU內置的一個控制器,能在支持
    的頭像 發表于 07-17 14:24 ?1105次閱讀
    RL78系列MCU <b class='flag-5'>DMA</b>在<b class='flag-5'>UART</b>中的使用

    ESP8266是否具有與SPI或UART一起使用的DMA功能?

    目前還沒有這方面的文檔,但ESP8266是否具有與 SPI 或 UART 一起使用的 DMA 功能?如果做不到這一點,是否有其他推薦的方法來提高串行吞吐量? 我以 3M 波特率成功運行 UART,但無法向ESPS8266
    發表于 07-12 10:25

    SDK通過UART端口發送消息,有沒有辦法關閉SDK中的消息?

    我正在設計一些需要使UART 端口的應用程序。使用 SDK 1.1.0 時,我發現 SDK 在系統運行時會輸出一些消息。有沒有辦法關閉 SDK 中的消息?謝謝。
    發表于 07-12 10:01

    esp32如何使用DMA來傳輸UART/SPI等外設的數據,編程上應該怎么聲明或者調用?

    esp32如何使用DMA來傳輸UART/SPI等外設的數據,編程上應該怎么聲明或者調用?
    發表于 06-26 07:58

    wifi的發送支持DMA嗎?

    wifi的發送支持DMA嗎? send(),這個函數是阻塞的嗎?怎么發送可以最大化發送頻率?我想在發送完成后處理一些東西,可不可以設置
    發表于 06-24 07:33