日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

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

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

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

串口DMA其實一點兒都不難

朱老師物聯(lián)網(wǎng)大講堂 ? 2024-04-29 08:10 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

DMA一種在嵌入式實時任務(wù)處理中常用的功能。而UART發(fā)送數(shù)據(jù)包,使用DMA方式能大量減輕CPU處理的時間,使其CPU資源不被大量浪費,尤其在UART收發(fā)大量數(shù)據(jù)包(如高頻率收發(fā)指令)時具有明顯優(yōu)勢。

一、簡述DMA

ecb153ba-05bc-11ef-9118-92fbcf53809c.pngDMA:Direct Memory Access,直接內(nèi)存存取/訪問。簡單來說就是內(nèi)存RAM直接和其他設(shè)備(外設(shè))進行數(shù)據(jù)交互,而不需要CPU參與的一種控制器。DMA它允許不同速度的硬件裝置來溝通,而不需要依賴于 CPU 的大量中斷負(fù)載。否則,CPU 需要從來源把每一片段的數(shù)據(jù)復(fù)制到緩存器,然后把它們再次寫回到新的地方。在這個過程中,CPU不能做其他的工作。

二、DMA的優(yōu)點

ecb153ba-05bc-11ef-9118-92fbcf53809c.pngDMA在系統(tǒng)中的角色好比一個公司的員工,CPU好比是公司的老板?;氐経ART發(fā)送數(shù)據(jù),同樣的道理,CPU只需要簡單的操作(“安排任務(wù)”),就可把一串?dāng)?shù)據(jù)包丟給DMA直接發(fā)送,最后發(fā)送完成,收到一個發(fā)送完成中斷,通知CPU發(fā)送完成即可。說到這里相信大部分人都明白了,老板可以親自開車或者坐飛機送快遞,完成這件事情,但會耽擱老板很多時間。同樣,如果我們使用UART自己發(fā)送,CPU就會不停仲裁發(fā)送結(jié)果,占據(jù)CPU大量資源。在RTOS中,特別是有大量任務(wù)需要處理的時候,UART使用DMA發(fā)送就會帶來很大方便。使用裸機運行的相同,尤為突出。

三、實例代碼:DMA發(fā)送配置

ecb153ba-05bc-11ef-9118-92fbcf53809c.png本文使用STM32F4 MCU、標(biāo)準(zhǔn)外設(shè)庫為例給大家簡單講述一下配置。

01

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 //優(yōu)先級#define COMM_COM_BaudRate 115200 //波特率#define COMM_COM_IRQHandler USART2_IRQHandler //中斷函數(shù)接口(見stm32f4xx_it.c)

USART配置:

/************************************************函數(shù)名稱 :USART_COMM_Configuration功 能 :通信串口配置參 數(shù) :無返 回 值 :無作 者 :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);
/* 復(fù)用配置 */ 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; //復(fù)用模式 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; //傳輸位數(shù) 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; //收發(fā)功能 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}


02

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 //優(yōu)先級#define COMM_TX_DMA_IRQHandler DMA1_Stream6_IRQHandler //中斷函數(shù)接口(見stm32f4xx_it.c)#define COMM_TX_DMA_IT_TCIF DMA_IT_TCIF6

DMA配置:

/************************************************函數(shù)名稱 :USART_COMM_DMA_Configuration功 能 :通信串口的DMA配置參 數(shù) :無返 回 值 :無作 者 :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; //外設(shè)地址 DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)0; //內(nèi)存地址(待傳入?yún)?shù)) DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //傳輸方向 DMA_InitStructure.DMA_BufferSize = 0; //傳輸長度(待傳入?yún)?shù)) DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外設(shè)遞增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //內(nèi)存遞增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //數(shù)據(jù)寬度 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //循環(huán)模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //優(yōu)先級 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); //初始化禁止}

03

DMA發(fā)送UART數(shù)據(jù)包

DMA發(fā)送函數(shù):

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

細心的朋友會發(fā)現(xiàn),這個發(fā)送函數(shù)其實很簡單,當(dāng)然,這里是使用STM32F4芯片,其他芯片也差不多,原理類似。HAL庫同樣可以完成。
關(guān)于DMA發(fā)送完成中斷,可根據(jù)實際情況,如果使用RTOS,一般發(fā)送數(shù)據(jù)是一個任務(wù),這個任務(wù)會OS等待(檢測)發(fā)送完成信號(即DMA發(fā)送完成中斷)。

本文轉(zhuǎn)載自公眾號|strongerHuang

如有侵權(quán) |聯(lián)系刪除

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

    關(guān)注

    15

    文章

    1627

    瀏覽量

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

    關(guān)注

    3

    文章

    582

    瀏覽量

    106294
  • 數(shù)據(jù)包
    +關(guān)注

    關(guān)注

    0

    文章

    270

    瀏覽量

    25663
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    三套體重秤聲紋識別語音方案,解決體重相近時人物信息判定異常難題,將原本模糊不清的健康數(shù)據(jù)轉(zhuǎn)化成為

    ,這組組數(shù)據(jù)最終該歸屬于誰?傳統(tǒng)的體重秤需要手動去切換用戶檔案,要是有那么一點兒沒有弄妥當(dāng),健康的數(shù)據(jù)就會出現(xiàn)搞錯的情況,時間長,記錄也就沒有太多實際的用處了
    的頭像 發(fā)表于 04-28 18:04 ?83次閱讀
    三套體重秤聲紋識別語音方案,解決體重相近時人物信息判定異常難題,將原本模糊不清的健康數(shù)據(jù)轉(zhuǎn)化成為

    電流互感器:那個天天幫你“盯著電流”的小玩意

    電流互感器,聽名字挺“正經(jīng)”的,但你知道嗎?它其實是電子工程師的“電流觀察員”、設(shè)備的“安全保鏢”、企業(yè)的“省錢小幫手”。下面用輕松一點的方式,帶你看看它都在哪兒“打工”。
    的頭像 發(fā)表于 12-25 16:46 ?864次閱讀
    電流互感器:那個天天幫你“盯著電流”的小玩意<b class='flag-5'>兒</b>

    深視課堂丨激光位移傳感器SD33系列一點示教操作指南(第三課)

    今天,我們將起學(xué)習(xí)深視智能SD33系列激光位移傳感器的一點示教模式操作方法。一點示教模式是通過設(shè)定個閾值(far),使傳感器在測量值小
    的頭像 發(fā)表于 12-22 08:17 ?611次閱讀
    深視課堂丨<b class='flag-5'>點</b>激光位移傳感器SD33系列<b class='flag-5'>一點</b>示教操作指南(第三課)

    做醫(yī)療嵌入式軟件研發(fā)以后好跳槽嗎?

    做醫(yī)療嵌入式軟件研發(fā),以后想跳槽一點兒不難。別看醫(yī)療行業(yè)門檻高、規(guī)矩多,你手里攢下的那套本事,到哪兒都吃得開。嵌入式這東西,甭管在哪個行當(dāng)里折騰,說到底六個基本部分跑不掉:嵌入式C、ARM架構(gòu)
    的頭像 發(fā)表于 12-03 11:04 ?964次閱讀
    做醫(yī)療嵌入式軟件研發(fā)以后好跳槽嗎?

    串口DMA發(fā)送有緩存嗎?

    串口DMA發(fā)送有緩存嗎, 我是從ringbuffer取出來,放到申請的緩存里,啟動串口DMA發(fā)送,然后就釋放了。暫時沒發(fā)現(xiàn)什么問題。 用的drv_usart.c是這個版本
    發(fā)表于 10-10 06:14

    串口DMA發(fā)送數(shù)據(jù)直發(fā)不出來是怎么回事?

    中斷處理函數(shù),下面的串口DMA發(fā)送和接收中斷進不去,只能進第個中斷。 static rt_size_t stm32_dma_transmit(struct rt_serial_de
    發(fā)表于 10-09 07:01

    請問各位大神,我要用串口控制12臺串聯(lián)的氣體流量計,想要做好一點該怎么修改程序呢

    我剛開始學(xué)串口通信,我想請問下各位大神,我要用串口同時控制12臺串聯(lián)的氣體流量計,每臺流量計的機器號都不一樣,因為要實現(xiàn)在
    發(fā)表于 09-30 11:13

    串口DMA接收方式打開,為什么在開啟IDLE中斷的情況下還需要開啟DMA中斷呢?

    戶接口rx_indicate來讀取數(shù)據(jù),此時,串口收到的數(shù)據(jù)并不定是完整的幀,破壞了使用IDLE中斷的意義。所以,為什么要開啟DMA中斷呢? 此處,可以看到不論是IDLE中斷還是
    發(fā)表于 09-29 08:30

    rtt串口驅(qū)動對低功耗串口lpuart1不兼容怎么解決?

    記錄下開啟低功耗串口lpuart1的問題和臨時解決辦法,希望官方早日修復(fù) 問題現(xiàn)象: 使用rtt studio基于芯片創(chuàng)建了stm32h750的基礎(chǔ)工程,log串口選用的LPU
    發(fā)表于 09-28 08:51

    為什么不同芯片型號的串口開啟DMA編譯結(jié)果不同?

    這是STM32F103打開串口DMA的編譯結(jié)果 這是STM32G431的編譯結(jié)果: G431會有七個報錯,顯示的都是IRQn未聲明
    發(fā)表于 09-23 06:42

    GD32的串口DMA收發(fā)數(shù)據(jù)失敗怎么解決?

    gd32_hw_usart_init()函數(shù)中并未注冊DMA收發(fā)的方式, GD32該函數(shù)如下: 而STM32的該函數(shù)如下: 查找GD32的串口操作庫中相關(guān)的DMA操作也缺失,不
    發(fā)表于 09-17 06:04

    串口DMA發(fā)送失敗的原因?怎么解決?

    我想使用DMA發(fā)送,但是出現(xiàn)了發(fā)送不出去,但是發(fā)送完成回調(diào)函數(shù)它是能進去的,打印出里面的內(nèi)容,接收數(shù)據(jù)是沒問題,這是為什么呢?有大佬指點下嗎 #include #include
    發(fā)表于 08-15 06:21

    STM32407使用串口閑時中斷+DMA方式接收最大接收字節(jié)是多少?

    使用串口閑時中斷+DMA方式接收數(shù)據(jù),波特率為460800,DMA接收長度為1024個字節(jié),并開啟串口閑時中斷,當(dāng)上位機次發(fā)送520個字節(jié)
    發(fā)表于 07-22 08:16

    由反激電源引起的一點兒分析

    由反激電源引起的一點兒分析 開關(guān)電源分為,隔離與非隔離兩種形式,在這里主要談談隔離式開關(guān)電源的拓?fù)湫问剑綦x電源按照結(jié)構(gòu)形式不同,可分 為兩大類:正激式和反激式。反激式指在變壓器原邊導(dǎo)通時副邊截止
    發(fā)表于 05-27 16:52

    請問如何增大usb3.0從設(shè)備fifo接口固件中的寫dma緩存大???

    現(xiàn)有的固件是默認(rèn)的,分別配置了2個1KB的緩存給讀和寫的dma。我想要多分配一點緩存給寫dma,比如分配4kB給寫dma。請教下該如何修改
    發(fā)表于 05-14 08:13
    木里| 林州市| 洛扎县| 青州市| 华宁县| 长治市| 阳泉市| 延川县| 绥阳县| 淅川县| 承德市| 沁阳市| 商洛市| 开原市| 贵州省| 通渭县| 武城县| 平远县| 东丽区| 营口市| 丰城市| 高阳县| 曲靖市| 滕州市| 渝中区| 汉阴县| 廊坊市| 西乌珠穆沁旗| 广德县| 崇义县| 墨脱县| 青河县| 岳西县| 花垣县| 永川市| 阜南县| 竹溪县| 金昌市| 宣武区| 库伦旗| 景德镇市|