国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

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

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

3天內不再提示

LPC800前生今世-第九章 直接存儲器訪問 (DMA)

恩智浦MCU加油站 ? 來源:未知 ? 2023-12-21 08:55 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

DMA是直接存儲器訪問(DirectMemory Access)的縮寫。在MCU芯片中,DMA是除CPU之外,最常見的總線主設備。作為總線主設備,DMA控制器可以輸出地址和控制信號到總線上,主動地發起和控制數據傳輸過程,它能夠按照程序的配置,在兩個從設備之間傳輸數據。例如在存儲器和I2C模塊之間傳輸數據,實現I2C數據的發送或接收,或從ADC讀出數據再傳送到USART進行發送。

下圖是LPC82x的部分框圖,圖中醒目標出了總線主設備,和DMA控制器。wKgZomWDjhOAIhgaAAF_2DFruUQ412.png? ? ? ? ? ? ? ? ? ?? ??圖1.LPC82x結構框圖(部分)LPC82x的所有片內外設中,只有DMA控制器是總線主設備,其它都是總線從設備,只有主設備才能主動發起數據的傳輸操作。

DMA的優勢是,可以在CPU最少的干預下,高效地執行數據塊的傳輸,節省CPU的時間,同時可以在CPU執行內部操作而不訪問總線時,更高效地利用總線的時間。

1.1DMA控制器的一些基本操作在介紹LPC800DMA控制器之前,先通過這個傳輸示意圖,回顧一下通用DMA控制器必須具備的基本操作。wKgZomWDjhSAfUdoAAEaJ-B3HnA548.png

圖2.DMA傳輸示意圖

產生數據傳輸的源地址和目標地址:DMA控制器在接到傳輸請求后,在內部總線上產生源數據地址SA,讀出要傳輸的數據,然后再產生存放數據的目標地址DA,將數據寫入指定的地方。

控制每次傳輸后地址的變化:可以控制每次DMA傳輸是涉及到一個連續的地址區域還是單個獨立的地址。每次讀寫的源地址和目標地址分別改變或不改變,也可以同步地改變。

控制傳輸的數據長度:軟件需要指定每次DMA傳輸的數據數量n

指定傳輸的數據寬度:軟件需要指定每次DMA讀寫的數據寬度,一般是以內部數據總線的寬度為限。對于32MCU,可以是1個字節、2個字節(半字)4個字節()

控制傳輸數據的節奏,即傳輸數據的時機:每次DMA讀寫都需要在有傳輸請求時才會執行。傳輸請求可以來自于數據源設備,例如ADC轉換結束;傳輸請求也可以來自于數據目標設備,例如SPI的發送就緒。因此每兩次傳輸請求的間隔可以不一致。DMA的傳輸請求也可以由DMA控制器內部產生,用于內存中數據塊的傳送。

狀態查詢和中斷控制:DMA控制器的狀態和中斷可以是多種多樣,通常有傳輸開始、傳輸結束、傳輸錯誤等。

LPC800DMA控制器實現了上述所有的基本控制功能,而且還有不少自己的特色,下面一一介紹。

1.2DMA傳輸與CPU指令的執行不管是CPU還是DMA控制器,都要通過同一條總線訪問存儲器和各種片內外設,進行數據傳輸。CPU的基本操作就是取指、譯碼、運算、執行的過程,取指操作需要占用總線,執行階段的讀數據或寫數據操作也需要占用總線。DMA控制器可以充分地利用CPU不占用總線的時間,在總線上傳輸數據。

如果在同一個時間,CPUDMA控制器都需要占用總線,這種情況下需要有仲裁機制,協調兩個總線主設備的動作。

如果在總線已經被某個主設備(例如CPU)占用的時候,另一個主設備(例如DMA控制器)就會稍作等待,待總線空閑時,再開始數據傳輸。

從以上描述可以看出,DMA可以在不需CPU干預的情況下,利用CPU不占用總線的空閑時間進行數據傳輸。這樣不但提高了總線的利用率,還減輕了CPU搬運數據的負擔,提高了系統的并行性,能夠實現更復雜的控制要求,或降低整體的功耗。

1.3LPC800DMA控制器LPC800DMA控制器具有如下特性:多個通道,每個通道唯一地連接到一個片內外設的輸入或輸出請求,例如USARTSPII2C通信外設。▲DMA傳輸可以由片內或片外事件觸發,每個DMA通道都可以有多個觸發輸入源,每次傳輸只能選擇一個觸發源。可以指定每個DMA通道的優先級,當通道之間的傳輸需求發生沖突時,高優先級通道先進行傳輸。傳輸描述符機制,通過多個傳輸描述符互聯,可以實現鏈式的DMA傳輸控制。每次(每個傳輸描述符)最多可以傳輸1024個字(1024x4=4096字節)地址增量的多種選項,允許靈活的數據包處理。LPC800各系列的DMA配置如下:

系列

通道數目

觸發輸入源數目

LPC80xLPC81x

0

0

LPC82x

18

9

LPC83x

18

8

LPC84x

25

13

1.3.1DMA寄存器一覽

DMA控制器有15個寄存器,涉及到所有通道,可以分為四組。

寄存器組

寄存器名稱

功能

說明

通用寄存器組

CTL

DMA控制器寄存器

只有一個控制位,使能DMA控制器

INTSTAT

中斷狀態寄存器

標志是否有掛起的中斷

SRAMBASE

傳輸描述符地址寄存器

所有通道第一個傳輸描述符的存放地址(必須512字節對齊)

通道控制寄存器組

ENABLESET0

通道使能寄存器

每個通道占用一位。表示是否使能對應通道

ENABLECLR0

通道失能寄存器

每個通道占用一位。表示是否失能對應通道

ACTIVE0

通道激活狀態寄存器

每個通道占用一位。表示對應通道是否加載了傳輸描述符

BUSY0

通道忙狀態寄存器

每個通道占用一位。表示對應通道是否正在搬運數據

通道中斷寄存器組

ERRINT0

錯誤中斷狀態寄存器

每個通道占用一位。表示是否有錯誤中斷

INTENSET0

中斷使能寄存器

每個通道占用一位。表示是否使能對應通道的中斷

INTENCLR0

中斷失能寄存器

每個通道占用一位。表示是否失能對應通道的中斷

INTA0

中斷A狀態寄存器

每個通道占用一位。表示是否有中斷A

INTB0

中斷B狀態寄存器

每個通道占用一位。表示是否有中斷B

傳輸控制寄存器

SETVALID0

設置“有效”控制位寄存器

每個通道占用一位。用于設置描述符的“有效”控制位

SETTRIG0

設置“觸發”控制位寄存器

每個通道占用一位。用于觸發對應的通道傳輸

ABORT0

通道中止傳輸寄存器

每個通道占用一位。用于中止對應的通道傳輸

每個DMA通道還分別有下表中的三個寄存器,用于配置各個通道的參數,將在1.4節詳細介紹。

寄存器名稱

功能

說明

CFG

通道配置寄存器

用于配置通道的使能、觸發、成組傳輸(Burst)和優先級的選項

CTLSTAT

通道控制狀態寄存器

用于標示通道的有效和觸發狀態

XFERCFG

通道傳輸配置寄存器

用于配置通道的各個配置選項

1.3.2 DMA傳輸描述符

除了上述寄存器外,LPC800DMA控制器通過位于內存中的傳輸描述符,控制每次的DMA傳輸。每個傳輸描述符有4個字(32/),內容如下:wKgZomWDjhSAcHgNAAAfGz12R-s782.png多個傳輸描述符可以構成一個連續的鏈條或循環鏈,鏈條中的每一個描述符對應一次DMA傳輸。傳輸的數據數量、數據寬度以及地址變化的方式等,由XFERCFG寄存器的內容指定。

每次DMA傳輸開始前,DMA控制器都要把一個完整的描述符讀入,傳輸描述符中偏移地址為0x0的字會被傳送到XFERCFG寄存器中,用于控制各項傳輸參數。一個鏈條的第一次傳輸參數,需要由軟件直接寫入到XFERCFG寄存器,因此鏈條中的第一個描述符的第一個字為保留位。在傳輸開始時,DMA控制器會把傳輸區的地址讀入內部寄存器中。

使用描述符的鏈接特性,可以方便地實現多種數據傳輸控制。

例如需要使用SPI驅動一個LCD屏幕產生動畫效果時,可以配置為下圖所示的乒乓結構的DMA描述符鏈條,CPU只需要不斷地生成顯示圖片,由DMA控制器平行地進行圖片數據至LCD屏幕的傳送。

wKgZomWDjhSAQY9AAAFL7cj531c211.png? ? ? ? ? ? ? ? ? ??圖3.乒乓結構的DMA描述符鏈

這里使用了三個傳輸描述符。第一個描述符(鏈頭)指示將緩沖區A的數據傳輸到SPI的發送寄存器,后面兩個描述符分別指示緩沖區B和緩沖區A的數據,輪流傳輸到SPI的發送寄存器。CPU只需要在對應的緩沖區準備好數據,再設置對應的描述符為“有效”,接下來DMA控制器就會直接把數據傳送到SPI模塊進行發送。

1.3.3 DMA傳輸通道每個通信外設的發送傳輸可以產生DMA請求,接收傳輸也可以產生DMA請求。

LPC800DMA控制器非常簡單,每個片內外設產生的DMA傳輸請求信號,唯一地連接到一個固定的DMA通道。即如果把片內外設作為DMA傳輸的源或目標,并且希望由該外設來控制傳輸的節奏(通過DMA傳輸請求信號),則必須使用對應的通道。如果能夠使用其它的方法(例如時鐘觸發等),保證外設不會發生數據溢出的情況,則可以使用任意通道,但這種用法不能最優地利用帶寬時間,除非需要特殊的時序控制,一般不建議使用。

每個通道對應的DMA請求源如下表所示:

wKgZomWDjhSAXLVrAACL8bMrNOk751.pngwKgZomWDjhSAd-bfAABMlOrT-KY420.png

表1.DMA通道與DMA請求源的對應表

1.3.4 DMA觸發源的選擇

DMA控制器之外,有一個DMA觸發輸入 (DMA TRIGMUX)模塊,每個DMA通道都在這個模塊中有一個對應的多選一選擇器,由DMA_ITRIG_INMUXn寄存器控制(n對應表1的通道號),用戶可以在多種信號中選擇一個作為DMA的觸發信號。下表列出了所有可能的選項:wKgZomWDjhSAL5FoAACCKcBc_X4128.png表2.DMA觸發選項(1):在LPC82x/83x中,n取值0~17;在LPC84x中,n取值0~24

*:每一個DMA通道都輸出一個觸發信號,所有通道輸出的觸發信號都連接到兩個多選一的選擇器:DMA_INMUX_INMUX0DMA_INMUX_INMUX1,這兩個多選一選擇器的輸出可以作為另一個DMA通道的觸發源選項之一。這個配置允許多個DMA通道的協同操作。

wKgZomWDjhSAFyZlAAFhs4hBuhg801.png? ? ? ? ? ? ? ? ? ? ? ?圖4.DMA觸發輸入框圖

上圖為某個DMA通道的觸發輸入模塊框圖,每個通道都有一個這樣相同的電路用于選擇它的觸發輸入。 1.4 DMA傳輸的請求、觸發與生成傳輸概念每個通道的DMA觸發信號相當于這個通道的總開關,只有打開這個總開關,才能夠進行隨后的DMA傳輸操作。

每次DMA傳輸(即圖2示意中的每一次讀寫)的時機,則由DMA請求信號決定。

成組傳輸(Burst)是指在一次觸發之后,按照指定的次數進行一組數據的傳輸,這組數據傳輸完成后,需要另一次的觸發條件才能進行下一組的數據傳輸。

成組傳輸控制和DMA傳輸請求控制組合為四種操作模式,他們與觸發信號的關系如下表所示。

表中的DMA傳輸請求信號以USARTTXRDY為例:

組合模式

使能成組傳輸(TRIGBURST,見1.5.1)

使能外設請求(PERIPHREQEN,見1.5.1)

操作模式說

0

0

0

觸發信號用于啟動完整的DMA傳輸過程,只需一個觸發信號即可完成所有數據傳輸。

DMA將以最快的速度,連續不斷地傳送數據,直到完成所有數據。

1

0

1

每個DMA傳輸請求(TXRDY),只能傳輸一個數據。

2

1

0

每個觸發信號啟動一組DMA傳輸,每組傳送BURSTPOWER(1.5.1)個數據。因此總共需要(XFERCOUNT/BURSTPOWER)組的傳輸(即需要相同數目的觸發信號),才能完成所有數據。

XFERCOUNT位于XFERCFG寄存器(1.5.2)

DMA將以最快的速度,連續不斷地傳送數據,直到完成所有數據。

3

1

1

每個DMA傳輸請求(TXRDY),只能傳輸一個數據。

表3.成組傳輸和外設請求與觸發信號的關系表

表中的組合模式0適合于從存儲器至存儲器的數據塊拷貝;組合模式1適合于常用的通信模塊的數據發送和接收。

組合模式23則視具體的應用情況,由用戶自由發揮。例如,要在USART上發送若干個固定長度的數據包,而發送每個數據包的時間需要由定時器來決定,則可以使用上述的組合模式3,設置BURSTPOWER為數據包的長度,設置SCT定時器產生觸發信號(見表2SCT_DMA0/1)

拿自動步槍做一個形象的比喻,成組的概念相當于子彈夾,外設請求相當于扳機,觸發相當于擊發保險,一次DMA傳輸中需要打出一箱子彈。那么每種組合模式有如下對應:組合模式0:打開擊發保險后,不需其它動作,整箱子彈即全部射出。組合模式1:打開擊發保險后,每扣動一次扳機,射出一發子彈,直到打完整箱子彈。組合模式2:打開擊發保險后,不需其它動作,一個彈夾中的子彈即全部射出。然后再次打開擊發保險,即射出另一個彈夾中的全部子彈。重復上述操作直到整箱子彈打光。組合模式3:打開擊發保險后,每扣動一次扳機,射出一個彈夾中的一顆子彈,重復直到這個彈夾中的子彈打光,擊發保險自動關閉。然后須再次打開擊發保險,再一次次地扣動扳機,逐個射出另一個彈夾中的所有子彈,擊發保險再次自動關閉。重復上述過程直到打完整箱子彈。

這里有一個要求,即XFERCOUNT必須能被BURSTPOWER整除,即一箱子彈的數目,必須是一個彈夾能容納子彈個數的倍數。

1.5 DMA通道參數寄存器

1.3.1節中列出的寄存器,用于控制整個DMA控制器,以及控制每個通道的使能、中斷和觸發等狀態。每個通道的具體工作模式,由下述三個寄存器來描述。

1.5.1DMA通道配置寄存器(CFG)

wKgZomWDjhWAZvIUAAHyUtsnSG0901.png

各個控制域的說明如下:▲PERIPHREQEN:使能外設請求。0 – 使能外設請求;1 – 不使能外設請求。

每個通道的外設請求來源是固定的,見表1。例如對應SPI0的發送就緒信號(TXRDY)DMA通道,在LPC82x/83x中是通道7,在LPC84x中是通道11HWTRIGEN:使能硬件觸發。硬件觸發信號源由DMA_ITRIG_INMUXn寄存器選擇,1.3.4節。0 – 使能硬件觸發;1 – 不使能硬件觸發。TRIGPOL:觸發極性。TRIGTYPE:觸發類型。TRIGPOLTRIGTYPE共同決定如何使用觸發信號,組合關系如下表。

TRIGTYPE

TRIGPOL

說明

0

0

下降沿觸發

0

1

上升沿觸發

1

0

低電平觸發

1

1

高電平觸發

TRIGBURST:觸發成組傳輸。

0 – 觸發之后不按組傳輸(或可理解為所有數據為一組)1 - 觸發之后執行成組傳輸。BURSTPOWER:成組傳輸中每組的長度。這個域的內容為2的冪次數值,取值為0~10,表示每組長度為1(20)2(21)4(22) 8(23)……1024(210)不支持0~10之外的數值。

注意:XFERCOUNT必須是BURSTPOWER的倍數。

SRCBURSTWRAP:成組傳輸中每組傳輸結束后,是否需要恢復傳輸的源地址。0 – 不恢復源地址;1 – 恢復源地址。

這個控制項適合于重復地讀出相同的數據塊,或相同的一組寄存器。DSTBURSTWRAP:成組傳輸中每組傳輸結束后,是否需要恢復傳輸的目標地址。0 – 不恢復目標地址;1 – 恢復目標地址。

這個控制項適合于重復地寫入相同的存儲區,例如重復地讀出一組傳感器的數值,軟件只關心即時的數值,而不關心數值變化的過程。CHPRIORITY:設置本通道的優先級。在多個通道同時請求獲得總線進行傳輸時,優先級高的通道先得到總線的使用權限。

0 – 最高優先級;7 – 最低優先級。

1.5.2 DMA通道傳輸配置寄存器(XFERCFG)

wKgZomWDjhWAX_oHAAIeMtFOje4522.png

該寄存器的內容給出了當前DMA傳輸的各項參數。一個傳輸描述符指定的一次傳輸結束后,DMA控制器會自動地讀入鏈條中的下一個描述符,描述符的第一個字的內容會加載到XFERCFG寄存器,見1.3.2節的說明。

XFERCFG各個控制域的說明如下:CFGVALID:表示所對應的描述符是否有效。0 – 描述符無效;1 – 描述符有效。RELOAD:當前描述符所指定的傳輸完成后,是否需要讀入下一個描述符。0 – 不讀入下一個描述符;1 – 讀入下一個描述符,允許描述符的鏈接操作。SWTRIG:軟件觸發。0 – 需要由HWTRIGENTRIGPOLTRIGTYPE指定通道的觸發條件。

1 – 設置此位表示該通道的觸發條件立即滿足。

注意:使用軟件觸發時,在TRIGBURST=0時,不得使用電平觸發。CLRTRIG:當前描述符的傳輸結束后,是否清除觸發條件。0 – 不清除。如果RELOAD=1,則下一個描述符的觸發條件滿足。

1 – 清除。當前描述符指示的傳輸結束后,清除觸發條件。

注意:只有軟件觸發條件和邊沿觸發條件可以被清除,而電平觸發條件不能被清除。SETINTA:當前描述符的傳輸結束后,是否產生中斷標志INTA0 – 不產生中斷標志;1 – 產生中斷標志。▲SETINTB:當前描述符的傳輸結束后,是否產生中斷標志INTB0 – 不產生中斷標志;1 – 產生中斷標志。

INTAINTB在硬件上沒有差別,用戶可以用這兩個中斷(標志)區別是哪個描述符的傳輸完成了,尤其是在乒乓結構的傳輸中。WIDTH:表示每次DMA傳輸的數據寬度。源地址的讀和目標地址的寫,使用相同的數據寬度。0 – 8位數據傳輸;1 – 16位數據傳輸;2 – 32位數據傳輸;3 – 保留組合,不得使用。

注意:如果要求的數據寬度是16位或32位,則傳輸的地址也必須分別是2字節或4字節對齊的。SRCINC:表示每次傳輸一個數據后,源地址的增量變化。0 – 地址無變化。

1 – 地址按數據寬度+1,指向數據區中的下一個數據。

2 – 地址按數據寬度+2

3 – 地址按數據寬度+4DSTINC:表示每次傳輸一個數據后,目標地址的增量變化。該域的取值含義與SRCINC一樣。

SRCINCDSTINC取值為0,最常見的應用場景是面對外設寄存器的讀寫,例如傳送一個數據塊至SPI0TXDAT,或從USARTRXDAT讀出一組數據至存儲區。

SRCINCDSTINC取值為1,最常見的應用場景對一個連續的存儲區的讀寫。

SRCINCDSTINC取值為23時,一個應用案例是,當WIDTH=0(8位數據)時,希望傳輸一組數據字或半字中的某個字節,而不管其它字節。▲XFERCOUNT:傳輸的數據總數,寄存器中填入(總數-1)該域有10位,即最大傳輸數據數目為1024

傳輸的字節總數為:(XFERCOUNT + 1) *WIDTH

注意1:在DMA傳輸過程中,DMA控制器會遞減該數值,因此不能在傳輸過程中或傳輸結束后,讀出該域而得知預設的傳輸數目。

注意2:如果設置了TRIGBURST =1,則XFERCOUNT必須是BURSTPOWER的倍數。

1.5.3DMA通道控制和狀態寄存器(CTLSTAT)wKgZomWDjhWAHK8VAABpkAN0DLo503.png這個寄存器只有兩個標志位,用戶可以檢查這些標志位,獲知當前DMA控制器的部分運行狀態。▲VALIDPENDING:延遲的有效位。見0的說明。▲TRIG:觸發標志。該位表示是否有觸發條件。設置觸發條件有多種途徑:通道傳輸配置寄存器(XFERCFG)SWTRIG控制位。設置觸發控制寄存器(SETTRIG0) ,該寄存器可以同時設置一個或多個通道的觸發條件。■DMA觸發輸入模塊選定的硬件觸發信號,滿足TRIGPOLTRIGTYPE時。清除觸發條件也有多種途徑:CLRTRIG=1時,描述符指定的傳輸結束時,清除觸發條件。

當失能DMA控制器時,見CTRL寄存器。

1.6描述符有效位的延遲設置機制通道傳輸配置寄存器(XFERCFG)CFGVALID位,指定該描述符是否有效。當一個有效的描述符被讀入DMA控制器后,當CTLSTAT寄存器的TRIG標志被設置后,DMA傳輸就會立即開始,這是最理想的情況。

通常的情況是,當準備好一個描述符A,尤其是使用描述符鏈時,描述符A所對應的存儲區的數據可能還沒有準備好,循環的乒乓結構就是一個很好的例子。這種情況下,就需要先設置描述符ACFGVALID=0,待數據區準備好后再設置它為有效。這樣延遲設置描述符有效,是通過SETVALID0寄存器來完成。

SETVALID0寄存器的每一位對應一個DMA通道,第n位寫’1’表示延遲設置通道n的描述符有效。

使用SETVALID0寄存器實現延遲設置描述符有效,是為了避免設置錯誤。設想一下,當DMA控制器已經在運行鏈上的某個描述符B時,軟件無法知道另一個描述符A是否已經被讀入DMA控制器。如果它還未被讀入DMA控制器,則可以直接操作描述符A所在的存儲區;如果它已經被讀入DMA控制器,則應該操作XFERCFG寄存器。

SETVALID0寄存器就是為了正確地設置描述符的有效位。

經過以上介紹可以看到,如果當前加載到DMA控制器的描述符是有效的,設置SETVALID0寄存器表示延遲設置鏈中下一個描述符為有效,此時CTLSTAT寄存器的VALIDPENDING為‘1’,標示這種狀態;當下一個描述符被讀入DMA控制器時,經延遲的設置描述符有效的操作才最終完成,此時VALIDPENDING位被清除。如果當前加載到DMA控制器的描述符是無效的,設置SETVALID0寄存器表示改變當前這個描述符為有效,不需經過延遲,操作立即生效。

使用這種延遲機制,軟件可以從容地先準備好描述符鏈,然后再按部就班地準備好數據區,逐步推進數據傳輸進程,而不必費周折查詢等待DMA控制器的狀態。

1.7若干DMA傳輸例程

本節的幾個例程,分別展示幾種DMA的常見用法。所有例程都會用到這樣幾個結構體。

結構體DMA_CHDESC_T是所有通道的描述符鏈中的第一個描述符。

typedef struct {

uint32_t notused; // 第一個描述符的這個位置是保留位

uint32_t source; // DMA傳輸源數據區的末地址

uint32_t dest; // DMA傳輸目標數據區的末地址

uint32_t next; // 鏈接到下一個描述符

} DMA_CHDESC_T;

所有通道的第一個描述符,需要按順序放在一個DMA_CHDESC_T數組中,而且這個數組的開始地址必須是512字節對齊的內存地址:

ALIGN(512) DMA_CHDESC_T Chan_Desc_Table[];

每個通道的第一個描述符,必須放在這個數組中與通道編號對應的單元中。例如USART1_RX_DMA通道的第一個描述符需要放在數組的第2個單元中(見表1)

結構體DMA_RELOADDESC_T適用于其它描述符。所有描述符必須位于16字節對齊的內存地址。

typedef struct {

uint32_t xfercfg; // 描述符的傳輸配置寄存器

uint32_t source; // DMA傳輸源數據區的末地址

uint32_t dest; // DMA傳輸目標數據區的末地址

uint32_t next; // 鏈接到下一個描述符

} DMA_RELOADDESC_T;

1.7.1DMA執行內存中的數據塊拷貝

使用DMA的最簡單應用就是在內存中拷貝一個數據塊,這是一個非常有效率的搬移數據塊的方法,尤其是數據量比較大時,CPU可以同時執行更多的操作。DMA拷貝數據塊不涉及到任何外設請求,使用軟件觸發,所以也不涉及到任何硬件的觸發。

本例程先用隨機數初始化數組Buffer1[ ],然后用DMABuffer1[ ]傳送數據至Buffer2[ ]。數組定義如下:

wKgZomWDjhWAQg70AAAtAqdSbxI093.png下面是初始化DMA控制器,并啟動DMA的函數。代碼片段1.使用DMA在內存中拷貝一個數據塊

01  void DMA_M2M_Init(uint32_t *buf1, uint32_t *buf2, uint32_t length)
02  {   uint32_t ch_cfg_val, xfercount, xfercfg; 
03  
04      LPC_SYSCON->SYSAHBCLKCTRL |= DMA;
05      LPC_DMA->CTRL = 0;
06  
07      LPC_DMA->SRAMBASE = (uint32_t)(&Chan_Desc_Table); 
08  
09      xfercount = length - 1; 
10  ch_cfg_val = 0; 
11      xfercfg = 0 << DMA_XFERCFG_CFGVALID | // 暫時設置為無效
12                0 << DMA_XFERCFG_RELOAD   | // 沒有下一個描述符
13                1 << DMA_XFERCFG_SWTRIG   | // 軟件觸發
14                1 << DMA_XFERCFG_CLRTRIG  | // 傳輸結束時清除觸發標志
15                1 << DMA_XFERCFG_SETINTA  | // 傳輸結束時設置INTA中斷
16                0 << DMA_XFERCFG_SETINTB  |
17                2 << DMA_XFERCFG_WIDTH    | // 數據寬度為32位
18                1 << DMA_XFERCFG_SRCINC   | // 每次傳輸后源地址遞增
19                1 << DMA_XFERCFG_DSTINC   | // 每次傳輸后目標地址遞增
20                xfercount << DMA_XFERCFG_XFERCOUNT; // 傳輸長度
21      LPC_DMA->CHANNEL[CH_USART0_RX].CFG = ch_cfg_val; 
22      LPC_DMA->CHANNEL[CH_USART0_RX].XFERCFG = xfercfg; 
23  
24      Chan_Desc_Table[CH_USART0_RX].source = (uint32_t)(&buf1[xfercount]);
25      Chan_Desc_Table[CH_USART0_RX].dest   = (uint32_t)(&buf2[xfercount]);
26      Chan_Desc_Table[CH_USART0_RX].next   = (uint32_t)0L; 
27  
28      LPC_DMA->INTENSET0 =  1 << CH_USART0_RX; 
29      LPC_DMA->ENABLESET0 = 1 << CH_USART0_RX; 
30  
31      LPC_DMA->CTRL = 1; 
32  
33      LPC_DMA->SETVALID0 = 1 << CH_USART0_RX; 
34  //  LPC_DMA->SETTRIG0  = 1 << CH_USART0_RX;
35  }

在這個例程中,用到了宏定義CH_USART0_RX,這是對應USART0接收方向的DMA通道號(見表1),在頭文件中定義了所有的通道號:

#define CH_USART0_RX 0 // USART0接收就緒

#define CH_USART0_TX 1 // USART0發送就緒

#define CH_USART1_RX 2 // USART1接收就緒

#define CH_USART1_TX 3 // USART1發送就緒

......

......

Chan_Desc_Table所有通道的描述符鏈頭構成的數組,這個數組的起始地址必須是512字節對齊的。

ALIGN(512) DMA_CHDESC_T Chan_Desc_Table[1];

在本例程中,由于使用的是通道0,而沒有使用其它通道,所以在數組中只配置了一個單元。

原則上,這個數組中對應不使用的通道的描述符單元,可以挪做其它用途。

在這個例程里,配置好所有的寄存器和描述符,并且使能了整個DMA控制器后,在第33行配置了對應的傳輸符為有效,該語句執行后DMA傳輸立即開始了。

如果第13行沒有配置XFERCFG的“軟件觸發”位,執行第33行后DMA通道還需要等待觸發信號才能開始傳輸,第34行就是由軟件發出DMA觸發信號的另一種途徑。

由上面的介紹可以看出,可以有多種方式,靈活地安排啟動DMA傳輸的時機和方法,讓用戶可以更加有效地安排自己的應用流程。

下面是這個例程的主函數和中斷處理程序。

代碼片段2.使用DMA拷貝一個數據塊的中斷函數和主函數

01  uint8_t DMA_IntA_Flag;
02  void DMA_IRQHandler(void) // DMA中斷處理程序
03  {
04      if (LPC_DMA->INTA0 & (1 << CH_USART0_RX)) {
05          LPC_DMA->INTA0 = 1 << CH_USART0_RX;
06          DMA_IntA_Flag = 1;
07      }
08      if (LPC_DMA->ERRINT0 & (1 << CH_USART0_RX)) 
09          LPC_DMA->ERRINT0 = 1 << CH_USART0_RX;
10  }
11  
12  void main()
13  {   uint32_t pp;
14      for (pp = 0; pp < BUF_SIZE; pp++)
15          Buffer1[pp] = rand();
16  
17      DMA_IntA_Flag = 0; 
18      DMA_M2M_Init(Buffer1, Buffer2, BUF_SIZE); 
19  
20      NVIC_EnableIRQ(DMA_IRQn); 
21      do {
22          __WFI();
23      } while (DMA_IntA_Flag == 0); 
24  
25      while (1);
26  }

DMA傳輸結束后產生中斷,在中斷函數中將軟件標志置’1’,主函數可以知道DMA傳輸是否已經完成。在實際的項目中,用戶程序可以替換上述21~23行的代碼,執行其它的一些操作。

1.7.2DMA執行USART0的連續發送(硬件觸發)

下面這個例程是使用DMA通過USART0發送一個字符串,需要配置使用USART0的發送請求,并采用開發板上的USER_KEY產生硬件觸發,即按下按鍵后才送出所有數據,用戶可以在PC端的虛擬串口上看到送出的字符串。

首先還是DMA的初始化函數,這個函數與前面的數據塊搬運初始化基本一致,指示CFGXFERCFG寄存器的內容有所變化。

代碼片段3. DMA通過USART0發送字符串01 void DMA_UART_Send(uint8_t *buf, uint32_t length)

02  {   uint32_t ch_cfg_val, xfercount, xfercfg; 
03  
04      LPC_SYSCON->SYSAHBCLKCTRL |= DMA;
05      LPC_DMA->CTRL = 0;
06  
07      LPC_DMA->SRAMBASE = (uint32_t)(&Chan_Desc_Table); 
08  
09      xfercount = length - 1; 
10  ch_cfg_val = 1 << DMA_CFG_PERIPHREQEN | // 外設請求
11                   1 << DMA_CFG_HWTRIGEN |  // 硬件觸發
12                   0 << DMA_CFG_TRIGTYPE |  // 邊沿觸發
13                   0 << DMA_CFG_TRIGPOL;    // 下降沿觸發
14  
15      xfercfg = 0 << DMA_XFERCFG_CFGVALID | // 暫時設置為無效
16                0 << DMA_XFERCFG_RELOAD   | // 沒有下一個描述符
17                0 << DMA_XFERCFG_SWTRIG   | // 沒有軟件觸發
18                1 << DMA_XFERCFG_CLRTRIG  | // 傳輸結束時清除觸發標志
19                1 << DMA_XFERCFG_SETINTA  | // 傳輸結束時設置INTA中斷
20                0 << DMA_XFERCFG_SETINTB  |
21                0 << DMA_XFERCFG_WIDTH    | // 數據寬度為8位
22                1 << DMA_XFERCFG_SRCINC   | // 每次傳輸后源地址遞增
23                0 << DMA_XFERCFG_DSTINC   | // 每次傳輸后目標地址不遞增
24                xfercount << DMA_XFERCFG_XFERCOUNT; // 傳輸長度
25      LPC_DMA->CHANNEL[CH_USART0_TX].CFG = ch_cfg_val; 
26      LPC_DMA->CHANNEL[CH_USART0_TX].XFERCFG = xfercfg; 
27  
28      Chan_Desc_Table[CH_USART0_TX].source = (uint32_t)(&buf[xfercount]);
29      Chan_Desc_Table[CH_USART0_TX].dest   = (uint32_t)(&LPC_USART0->TXDAT);
30      Chan_Desc_Table[CH_USART0_TX].next   = (uint32_t)0L; 
31  
32      LPC_DMA->INTENSET0 =  1 << CH_USART0_TX; 
33      LPC_DMA->ENABLESET0 = 1 << CH_USART0_TX; 
34  
35      LPC_DMA->CTRL = 1; 
36  
37      LPC_DMA->SETVALID0 = 1 << CH_USART0_TX; 
38  }

上述代碼里用橙色標注出與代碼片段1不同的地方。還有一個明顯的不同是,此處所有涉及到DMA通道號時,都換成了CH_USART0_TX

USART0的初始化部分與USART章節的代碼完全一致,現抄錄如下。

代碼片段4.基本UART收發例程的USART0初始化

00  void USART0_init() {
01      LPC_SYSCON->SYSAHBCLKCTRL |= (UART0 | SWM); 
02  
03      LPC_SYSCON->PRESETCTRL &= (UART0_RST_N); 
04      LPC_SYSCON->PRESETCTRL |= ~(UART0_RST_N);
05  
06      ConfigSWM(U0_TXD, P0_4); 
07      ConfigSWM(U0_RXD, P0_0);
08  
09      LPC_SYSCON->UARTCLKDIV = LPC_SYSCON->SYSAHBCLKDIV; // 設置USART時鐘的分頻系數
10      LPC_SYSCON->UARTFRGMULT = 4; 
11      LPC_SYSCON->UARTFRGDIV = 255; 
12      LPC_USART0->BRG = 16 - 1;
13  
14      // 8個數據位,無校驗位,1個停止位,沒有硬件流控,異步模式
15      LPC_USART0->CFG = DATA_LENG_8 | PARITY_NONE | STOP_BIT_1; 
16  
17      LPC_USART0->CTL = 0;
18  
19      LPC_USART0->STAT = 0xFFFF; 
20  
21      LPC_USART0->INTENSET = RXRDY; 
22      NVIC_EnableIRQ(UART0_IRQn);
23  }

接下來是本節的重點。代碼片段3的第11~13行,配置DMA通道為硬件觸發信號的下降沿觸發,下面是初始化PINTINT,使用USER_KEY產生觸發信號,和對應的中斷程序。代碼片段5.初始化按鍵產生DMA硬件觸發信號

01  #define PINTSEL0 0       // 定義引腳中斷0的編號
02  #define KEY_USER P0_1    // 定義按鍵USER_KEY的引腳
03  
04  void PININT0_IRQHandler(void)
05  {
06      if (LPC_PIN_INT->RISE & (1<
07          LPC_PIN_INT->RISE = 1<// 清除上升沿中斷標志
08      if (LPC_PIN_INT->FALL & (1<
09          LPC_PIN_INT->FALL = 1<// 清除下降沿中斷標志
10  }
11  
12  void PINT_Init_Key_User()
13  {
14      LPC_GPIO_PORT->DIRCLR0 = 1 << KEY_USER;   // 配置USER_KEY對應的引腳為輸入
15      LPC_SYSCON->PINTSEL[PINTSEL0] = KEY_USER; // USER_KEY對應對應到引腳中斷0(PINTSEL0)
16      LPC_PIN_INT->ISEL = 0 << PINTSEL0;        // 配置引腳中斷0(PINTSEL0)為邊沿觸發
17      LPC_PIN_INT->IENR = 1 << PINTSEL0;        // 配置引腳中斷0(PINTSEL0)是上升沿觸發
18      LPC_PIN_INT->IENF = 0 << PINTSEL0;        // 配置引腳中斷0(PINTSEL0)不是下降沿觸發
19      LPC_PIN_INT->IST = 0xFF;                  // 清除所有可能的引腳中斷標志
20      NVIC_EnableIRQ(PININT0_IRQn);             // 使能引腳中斷
21  }

上述代碼是對PINTINT的初始化,它配置USER_KEY對應的引腳產生一個中斷信號,確切地說是按鍵按下再抬起時的上升沿將產生中斷。04行的中斷處理程序中,只是簡單地清除可能的上升沿或下降沿中斷標志。

這里要澄清兩個概念,一個是引腳中斷的觸發信號,另一個是DMA的觸發信號。前者是引腳上的信號,用于產生中斷;后者是芯片內部的中斷標志對應的信號,用于觸發DMA傳輸。兩個信號分別有上升沿和下降沿的選項,但兩者是不等價的,本例程中引腳中斷選擇的是上升沿,而DMA觸發信號選擇的是下降沿。

下圖顯示出了這兩個信號之間的關系:

wKgZomWDjhWAP2UqAADYuOAcS-w277.png? ? ? ? ? ? ? ? ? ? ??圖5.引腳中斷與DMA觸發信號的關系圖

圖中的時間點④是觸發DMA傳輸的時間,這個時間點與代碼片段507行的執行相對應。如果清除上升沿中斷的動作被推遲,則DMA傳輸的時間也會被推遲,所以用戶要盡快地響應PINTINT中斷并清除中斷標志,以實現快速高效傳輸。

下面是主函數代碼,主函數中調用了前面介紹過的DMAUSARTPINTINT函數。

代碼片段6.硬件觸發DMA傳輸UART發送數據例程

01  const unsigned char Hello[] = "Hello DMA World!
"; // 待發送的數據串
02  void main()
03  {
04      USART0_init();      // 初始化USART0
05  
06      DMA_IntA_Flag = 0;  // 清除DMA中斷標記
07  
08      DMA_UART_Send((uint8_t *)Hello, sizeof(Hello)-1); // 初始化DMA控制器
09  
10      LPC_DMATRIGMUX->DMA_ITRIG_INMUX1 = 0x05; 
11      PINT_Init_Key_User();
12  
13      NVIC_EnableIRQ(DMA_IRQn); 
14      do {
15          __WFI();
16      }
17      while (DMA_IntA_Flag == 0);
18  
19      while (1);
20  }

這個主函數與前面那個例程(見代碼片段2)的主要區別,就是第1011行配置DMA觸發源和對觸發源(引腳中斷0)的初始化。

這里需要注意的是第10行配置DMA觸發源,一定要在使能DMA時鐘之后執行。本例程中,DMA的時鐘是在DMA_UART_Send()中設置的,見代碼片段3

1.7.3DMA執行USART0的成組發送

這個例程是在上一個例程的基礎上,增加了使用乒乓鏈接的描述符,同時設置成組傳輸。

下圖所示為本例程中乒乓鏈接的描述符鏈。鏈頭描述符指向一個開始字符串Hello,并鏈接到描述符B。描述符A指向一個字符串A,描述符B指向另一個字符串B。傳輸執行的效果是,先發送Hello,然后循環發送SpingBàSpingAàSpingB......

wKgZomWDjhWAIf71AAGIuEduoic486.png圖6.DMA執行USART0的成組發送例程的描述符鏈另外,例程中安排了以成組(Burst)方式發送每個字符串,即每次觸發只發送BURSTPOWER指定長度的數據,見1.5.1的說明。

和上節一樣,例程中的觸發源也是與USER_KEY相連的引腳中斷0

本例程用到下述變量。

  ALIGN(512) DMA_CHDESC_T Chan_Desc_Table[2]; // 所有通道描述符鏈頭數組
  ALIGN(16) DMA_RELOADDESC_T Descriptor_A;    // 描述符A
  ALIGN(16) DMA_RELOADDESC_T Descriptor_B;    // 描述符B
  
  uint8_t DMA_IntA_Flag;    // 中斷A軟件標志
  uint8_t DMA_IntB_Flag;    // 中斷B軟件標志
                          // 1234----1234----1234----1234----
  const uint8_t Hello[] =   ">> Hello my DMA world!
";         // 鏈頭對應的字符串
  const uint8_t StringA[] = ">> Hello dear StringA.
 ";        // 描述符A的字符串
  const uint8_t StringB[] = "<< Hello I am saying String B.
"; // 描述符B的字符串

下面是DMA初始化的代碼代碼片段7.執行USART0的成組發送例程的DMA初始化代碼

01  void DMA_UART_PingPong_Send(uint8_t *buf, uint32_t length)
02  {   uint32_t ch_cfg_val, xfercount, xfercfg; 
03  
04      LPC_SYSCON->SYSAHBCLKCTRL |= DMA;
05      LPC_DMA->CTRL = 0;
06  
07      LPC_DMA->SRAMBASE = (uint32_t)(&Chan_Desc_Table); 
08  
09      xfercount = length - 1; 
10  ch_cfg_val = 1 << DMA_CFG_PERIPHREQEN |   // 外設請求
11                   1 << DMA_CFG_HWTRIGEN |  // 硬件觸發
12                   0 << DMA_CFG_TRIGTYPE |  // 邊沿觸發
13                   0 << DMA_CFG_TRIGPOL |   // 下降沿觸發
14                   1 << DMA_CFG_TRIGBURST | // 成組傳輸模式
15                   3 << DMA_CFG_BURSTPOWER; // 每組為8(23)個數據
16  
17      xfercfg = 0 << DMA_XFERCFG_CFGVALID | // 暫時設置為無效
18                1 << DMA_XFERCFG_RELOAD   | // 有下一個描述符
19                0 << DMA_XFERCFG_SWTRIG   | // 沒有軟件觸發
20                1 << DMA_XFERCFG_CLRTRIG  | // 傳輸結束時清除觸發標志
21                1 << DMA_XFERCFG_SETINTA  | // 傳輸結束時設置INTA中斷
22                0 << DMA_XFERCFG_SETINTB  |
23                0 << DMA_XFERCFG_WIDTH    | // 數據寬度為8位
24                1 << DMA_XFERCFG_SRCINC   | // 每次傳輸后源地址遞增
25                0 << DMA_XFERCFG_DSTINC   | // 每次傳輸后目標地址不遞增
26                xfercount << DMA_XFERCFG_XFERCOUNT; // 傳輸長度
27      LPC_DMA->CHANNEL[CH_USART0_TX].CFG = ch_cfg_val; 
28      LPC_DMA->CHANNEL[CH_USART0_TX].XFERCFG = xfercfg; 
29  
30      Chan_Desc_Table[CH_USART0_TX].source = (uint32_t)(&buf[xfercount]);
31      Chan_Desc_Table[CH_USART0_TX].dest   = (uint32_t)(&LPC_USART0->TXDAT);
32      Chan_Desc_Table[CH_USART0_TX].next   = (uint32_t)& Descriptor_B; 
33  
34      xfercount = sizeof(StringB)- 2; // 去掉字符串結尾的字符’’
35      Descriptor_B.xfercfg = 1 << DMA_XFERCFG_CFGVALID |
36                             1 << DMA_XFERCFG_RELOAD   |
37                             1 << DMA_XFERCFG_CLRTRIG  |
38                             1 << DMA_XFERCFG_SETINTB  |
39                             1 << DMA_XFERCFG_SRCINC   |
40                             xfercount << DMA_XFERCFG_XFERCOUNT;
41      Descriptor_B.source = (uint32_t)(&StringB[xfercount]);
42      Descriptor_B.dest = (uint32_t)(&LPC_USART0->TXDAT);
43      Descriptor_B.next = (uint32_t)&Descriptor_A;
44  
45      xfercount = sizeof(StringA)- 2; // 去掉字符串結尾的字符’’ 
46      Descriptor_A.xfercfg = 1 << DMA_XFERCFG_CFGVALID |
47                             1 << DMA_XFERCFG_RELOAD   |
48                             1 << DMA_XFERCFG_CLRTRIG  |
49                             1 << DMA_XFERCFG_SETINTA  |
50                             1 << DMA_XFERCFG_SRCINC   |
51                             xfercount << DMA_XFERCFG_XFERCOUNT;
52      Descriptor_A.source = (uint32_t)(&StringA[xfercount]);
53      Descriptor_A.dest = (uint32_t)(&LPC_USART0->TXDAT);
54      Descriptor_A.next = (uint32_t)&Descriptor_B;
55  
56      LPC_DMA->INTENSET0 =  1 << CH_USART0_TX; 
57      LPC_DMA->ENABLESET0 = 1 << CH_USART0_TX; 
58  
59      LPC_DMA->CTRL = 1; 
60  
61      LPC_DMA->SETVALID0 = 1 << CH_USART0_TX; 
62  }

DMA控制器中設置的兩個中斷INTAINTB的內部機制完全一致,分為兩個中斷源只是為了讓用戶區分對應的描述符,用戶可以自由安排。本例中設置描述符A執行結束后會產生中斷A,描述符B執行結束后會產生中斷B,因此相比前一個例程中斷處理程序也多了出來INTB的代碼。

代碼片段8.執行USART0的成組發送例程中斷處理程序
01  void DMA_IRQHandler(void)
02  {
03      if (LPC_DMA->INTA0 & (1 << CH_USART0_TX)) {
04          LPC_DMA->INTA0 = 1 << CH_USART0_TX;
05          DMA_IntA_Flag++;
06      }
07      if (LPC_DMA->INTB0 & (1 << CH_USART0_TX)) {
08          LPC_DMA->INTB0 = 1 << CH_USART0_TX; 
09          DMA_IntB_Flag++;
10      }
11      if (LPC_DMA->ERRINT0 & (1 << CH_USART0_TX))
12          LPC_DMA->ERRINT0 = 1 << CH_USART0_TX;
13  }

每次執行完一個描述符后,就會相應地產生一個中斷(INTAINTB),用戶可以自行在代碼片段8的第0509行安插代碼在適當的時候結束整個描述符鏈的DMA傳輸,例如當循環次數滿足一定要求時。

代碼片段9.執行USART0的成組發送例程的主函數

01  void main()
02  {
03      USART0_init();      // 初始化USART0
04  
05      DMA_IntA_Flag = DMA_IntB_Flag = 0;  // 清除DMA中斷標記
06  
07      DMA_UART_PingPong_Send((uint8_t *)Hello, sizeof(Hello)-1); // 初始化DMA控制器
08  
09      LPC_DMATRIGMUX->DMA_ITRIG_INMUX1 = 0x05; 
10      PINT_Init_Key_User();
11  
12      NVIC_EnableIRQ(DMA_IRQn); 
13      while (1)
14          __WFI();
15  }

主函數和前面的代碼片段6基本一致。執行這個例程后,每按一次按鍵DMA會發送8個字符,在串口助手上有如下顯示:

wKgZomWDjhWAQFD2AAIY--ljgGc244.png

END

更多恩智浦AI-IoT市場和產品信息,邀您同時關注“NXP客棧”微信公眾號

wKgZomWDjhWAF7paAABCdkRE230661.jpg ? ? ?

NXP客棧


恩智浦致力于打造安全的連接和基礎設施解決方案,為智慧生活保駕護航。

長按二維碼,關注我們

恩智浦MCU加油站


這是由恩智浦官方運營的公眾號,著重為您推薦恩智浦MCU的產品信息、開發技巧、教程文檔、培訓課程等內容。

wKgZomWDjhaAAHlMAAATNlPH08Y038.jpg ?

長按二維碼,關注我們


原文標題:LPC800前生今世-第九章 直接存儲器訪問 (DMA)

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


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

    關注

    147

    文章

    18925

    瀏覽量

    398244
  • 恩智浦
    +關注

    關注

    14

    文章

    6095

    瀏覽量

    147401

原文標題:LPC800前生今世-第九章 直接存儲器訪問 (DMA)

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

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

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    【「Altium Designer 25 電路設計精進實踐」閱讀體驗】+第九章實例- what?這不就是官方的SAM V71開發板嗎?

    本書最后一的實例, SAM V71開發板翻遍了本書,也沒找到書中有關該實例的資源文件? 去機工電氣,機工電子的官網,公眾號找了一遍,也沒找到半點信息。 再來仔細看下這一的內容 好像就是介紹了下
    發表于 02-14 16:55

    【「Altium Designer 25 電路設計精進實踐」閱讀體驗】+本書概覽與內容特點介紹

    的參考。第七介紹了元器件庫的維護與管理,維護自己的庫有利于高效的設計,減少出錯。 實踐部分第八 介紹了多板系統和線束設計實例第九章 介紹了SAM V71開發板的實例,可以參考這個動手做一個自己的開發板
    發表于 02-14 15:56

    【「Altium Designer 25 電路設計精進實踐」閱讀體驗】+讀后感

    、封裝庫了,相當于的子單元,是構建的基石。 第八、九章節是為我們實例操作了兩個例程,讓我們更好的了解軟件,項目中怎么做。 但是第九章標題有點誤導了我,寫的仿真開發板 我第一眼以為是使用AD軟件怎么仿真
    發表于 02-14 11:38

    抒微智能Surertech受邀參展?第九屆世界無人機大會(深圳)

    抒微智能Surertech受邀參展?第九屆世界無人機大會(深圳)
    的頭像 發表于 02-03 11:40 ?329次閱讀
    抒微智能Surertech受邀參展?<b class='flag-5'>第九</b>屆世界無人機大會(深圳)

    CW32F030 RAM存儲器的介紹

    時鐘頻率進行訪問 ?支持奇偶校驗功能 3 RAM 存儲器操作 用戶可執行的 RAM 存儲器操作包括:讀操作、寫操作。 對 RAM 的讀寫操作支持 8bit、16bit 和 32bit 三種
    發表于 01-12 06:33

    LPC800系列MCU:低功耗與高性能的完美結合

    LPC800系列MCU:低功耗與高性能的完美結合 在電子工程師的日常工作中,選擇合適的微控制(MCU)對于項目的成功至關重要。今天,我們就來詳細探討一下NXP的LPC800系列MCU,看看它有
    的頭像 發表于 12-24 16:40 ?291次閱讀

    CW32 DMA的主要特性

    CW32F030 支持直接內存訪問DMA),無需 CPU 干預,即可實現外設和存儲器之間、外設和外設之間、存儲器
    發表于 12-16 07:14

    CW32L052 DMA直接內存訪問介紹

    傳輸,如FLASH存儲器、UART串口、TIM定時、ADC數模轉換等被配置為DMA通道的觸發源時, 可以產生DMA請求(
    發表于 12-12 07:21

    15屆藍橋杯嵌入式省賽客觀題及參考答案

    1,DMA控制是什么()。A:一個獨立的外設B:一個與MCU并行工作的處理C:一個調節系統時鐘的模塊D:一個處理中斷和事件的單元【解析】DMA
    的頭像 發表于 12-02 21:07 ?468次閱讀
    15屆藍橋杯嵌入式省賽客觀題及參考答案

    芯源的直接內存訪問DMA)技術介紹

    芯片內置 DMA 控制,4 條獨立通道,外設和存儲器之間、外設和外設之間、存儲器存儲器之間的高速數 據傳輸。 每個
    發表于 11-12 07:40

    芯源的片上存儲器介紹

    片上FLASH 閃存由兩部分物理區域組成:主FLASH 存儲器和啟動程序存儲器。 ●● 主 FLASH 存儲器,共 64KB,地址空間為 0x0000 0000 - 0x0000 FFFF。該區
    發表于 11-12 07:34

    第九屆集創賽全國總決賽“紫光同創杯”圓滿落幕

    近日,第九屆全國大學生集成電路創新創業大賽(簡稱“第九屆集創賽”)全國總決賽在上海臨港圓滿落幕。第九屆集創賽覆蓋集成電路全產業鏈,報名隊伍超過7400支,參賽師生逾20000人,參與高校500余家,賽事規模和影響力再創新高!
    的頭像 發表于 09-04 15:20 ?1838次閱讀

    鎧俠第九代 BiCS FLASH? 512Gb TLC 存儲器開始送樣

    融合現有存儲單元與先進的 CMOS 技術,實現投資效益最大化 ? 全球存儲解決方案領導者鎧俠宣布,其采用第九代 BiCS FLASH? 3D 閃存技術的 512Gb TLC存儲器已開始
    發表于 07-28 15:30 ?716次閱讀

    第九章 W55MH32 HTTP Server示例

    本文介紹了在 W55MH32?芯片上實現 HTTP Server?功能,并通過瀏覽修改其網絡地址信息的方法。闡述了 HTTP?協議的概念、特點、應用場景、工作流程、請求方法、響應內容,以及 Web?頁面構成和交互方式。展示了在W55MH32上實現的過程。
    的頭像 發表于 07-24 09:35 ?1108次閱讀
    <b class='flag-5'>第九章</b> W55MH32 HTTP Server示例

    第十五 DMA

    本章介紹DMA直接存儲器存取),其可在不占用CPU的情況下搬數據,支持多種傳輸方向,含控制、通道等配置及相關實驗代碼。
    的頭像 發表于 06-14 16:32 ?1428次閱讀
    第十五<b class='flag-5'>章</b> <b class='flag-5'>DMA</b>