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

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

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

LPC800前生今世-第九章 直接存儲(chǔ)器訪問(wèn) (DMA)

恩智浦MCU加油站 ? 來(lái)源:未知 ? 2023-12-21 08:55 ? 次閱讀

DMA是直接存儲(chǔ)器訪問(wèn)(DirectMemory Access)的縮寫。在MCU芯片中,DMA是除CPU之外,最常見(jiàn)的總線主設(shè)備。作為總線主設(shè)備,DMA控制器可以輸出地址和控制信號(hào)到總線上,主動(dòng)地發(fā)起和控制數(shù)據(jù)傳輸過(guò)程,它能夠按照程序的配置,在兩個(gè)從設(shè)備之間傳輸數(shù)據(jù)。例如在存儲(chǔ)器和I2C模塊之間傳輸數(shù)據(jù),實(shí)現(xiàn)I2C數(shù)據(jù)的發(fā)送或接收,或從ADC讀出數(shù)據(jù)再傳送到USART進(jìn)行發(fā)送。

下圖是LPC82x的部分框圖,圖中醒目標(biāo)出了總線主設(shè)備,和DMA控制器。wKgZomWDjhOAIhgaAAF_2DFruUQ412.png? ? ? ? ? ? ? ? ? ?? ??圖1.LPC82x結(jié)構(gòu)框圖(部分)LPC82x的所有片內(nèi)外設(shè)中,只有DMA控制器是總線主設(shè)備,其它都是總線從設(shè)備,只有主設(shè)備才能主動(dòng)發(fā)起數(shù)據(jù)的傳輸操作。

DMA的優(yōu)勢(shì)是,可以在CPU最少的干預(yù)下,高效地執(zhí)行數(shù)據(jù)塊的傳輸,節(jié)省CPU的時(shí)間,同時(shí)可以在CPU執(zhí)行內(nèi)部操作而不訪問(wèn)總線時(shí),更高效地利用總線的時(shí)間。

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

圖2.DMA傳輸示意圖

產(chǎn)生數(shù)據(jù)傳輸?shù)脑吹刂泛湍繕?biāo)地址:DMA控制器在接到傳輸請(qǐng)求后,在內(nèi)部總線上產(chǎn)生源數(shù)據(jù)地址SA,讀出要傳輸?shù)臄?shù)據(jù),然后再產(chǎn)生存放數(shù)據(jù)的目標(biāo)地址DA,將數(shù)據(jù)寫入指定的地方。

控制每次傳輸后地址的變化:可以控制每次DMA傳輸是涉及到一個(gè)連續(xù)的地址區(qū)域還是單個(gè)獨(dú)立的地址。每次讀寫的源地址和目標(biāo)地址分別改變或不改變,也可以同步地改變。

控制傳輸?shù)臄?shù)據(jù)長(zhǎng)度:軟件需要指定每次DMA傳輸?shù)臄?shù)據(jù)數(shù)量n。

指定傳輸?shù)臄?shù)據(jù)寬度:軟件需要指定每次DMA讀寫的數(shù)據(jù)寬度,一般是以內(nèi)部數(shù)據(jù)總線的寬度為限。對(duì)于32MCU,可以是1個(gè)字節(jié)、2個(gè)字節(jié)(半字)4個(gè)字節(jié)()。

控制傳輸數(shù)據(jù)的節(jié)奏,即傳輸數(shù)據(jù)的時(shí)機(jī):每次DMA讀寫都需要在有傳輸請(qǐng)求時(shí)才會(huì)執(zhí)行。傳輸請(qǐng)求可以來(lái)自于數(shù)據(jù)源設(shè)備,例如ADC轉(zhuǎn)換結(jié)束;傳輸請(qǐng)求也可以來(lái)自于數(shù)據(jù)目標(biāo)設(shè)備,例如SPI的發(fā)送就緒。因此每?jī)纱蝹鬏斦?qǐng)求的間隔可以不一致。DMA的傳輸請(qǐng)求也可以由DMA控制器內(nèi)部產(chǎn)生,用于內(nèi)存中數(shù)據(jù)塊的傳送。

狀態(tài)查詢和中斷控制:DMA控制器的狀態(tài)和中斷可以是多種多樣,通常有傳輸開(kāi)始、傳輸結(jié)束、傳輸錯(cuò)誤等。

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

1.2DMA傳輸與CPU指令的執(zhí)行不管是CPU還是DMA控制器,都要通過(guò)同一條總線訪問(wèn)存儲(chǔ)器和各種片內(nèi)外設(shè),進(jìn)行數(shù)據(jù)傳輸。CPU的基本操作就是取指、譯碼、運(yùn)算、執(zhí)行的過(guò)程,取指操作需要占用總線,執(zhí)行階段的讀數(shù)據(jù)或?qū)憯?shù)據(jù)操作也需要占用總線。DMA控制器可以充分地利用CPU不占用總線的時(shí)間,在總線上傳輸數(shù)據(jù)。

如果在同一個(gè)時(shí)間,CPUDMA控制器都需要占用總線,這種情況下需要有仲裁機(jī)制,協(xié)調(diào)兩個(gè)總線主設(shè)備的動(dòng)作。

如果在總線已經(jīng)被某個(gè)主設(shè)備(例如CPU)占用的時(shí)候,另一個(gè)主設(shè)備(例如DMA控制器)就會(huì)稍作等待,待總線空閑時(shí),再開(kāi)始數(shù)據(jù)傳輸。

從以上描述可以看出,DMA可以在不需CPU干預(yù)的情況下,利用CPU不占用總線的空閑時(shí)間進(jìn)行數(shù)據(jù)傳輸。這樣不但提高了總線的利用率,還減輕了CPU搬運(yùn)數(shù)據(jù)的負(fù)擔(dān),提高了系統(tǒng)的并行性,能夠?qū)崿F(xiàn)更復(fù)雜的控制要求,或降低整體的功耗。

1.3LPC800DMA控制器LPC800DMA控制器具有如下特性:多個(gè)通道,每個(gè)通道唯一地連接到一個(gè)片內(nèi)外設(shè)的輸入或輸出請(qǐng)求,例如USART、SPII2C通信外設(shè)。▲DMA傳輸可以由片內(nèi)或片外事件觸發(fā),每個(gè)DMA通道都可以有多個(gè)觸發(fā)輸入源,每次傳輸只能選擇一個(gè)觸發(fā)源。可以指定每個(gè)DMA通道的優(yōu)先級(jí),當(dāng)通道之間的傳輸需求發(fā)生沖突時(shí),高優(yōu)先級(jí)通道先進(jìn)行傳輸。傳輸描述符機(jī)制,通過(guò)多個(gè)傳輸描述符互聯(lián),可以實(shí)現(xiàn)鏈?zhǔn)降?/span>DMA傳輸控制。每次(每個(gè)傳輸描述符)最多可以傳輸1024個(gè)字(1024x4=4096字節(jié))。地址增量的多種選項(xiàng),允許靈活的數(shù)據(jù)包處理。LPC800各系列的DMA配置如下:

系列

通道數(shù)目

觸發(fā)輸入源數(shù)目

LPC80x、LPC81x

0

0

LPC82x

18

9

LPC83x

18

8

LPC84x

25

13

1.3.1DMA寄存器一覽

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

寄存器組

寄存器名稱

功能

說(shuō)明

通用寄存器組

CTL

DMA控制器寄存器

只有一個(gè)控制位,使能DMA控制器

INTSTAT

中斷狀態(tài)寄存器

標(biāo)志是否有掛起的中斷

SRAMBASE

傳輸描述符地址寄存器

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

通道控制寄存器組

ENABLESET0

通道使能寄存器

每個(gè)通道占用一位。表示是否使能對(duì)應(yīng)通道

ENABLECLR0

通道失能寄存器

每個(gè)通道占用一位。表示是否失能對(duì)應(yīng)通道

ACTIVE0

通道激活狀態(tài)寄存器

每個(gè)通道占用一位。表示對(duì)應(yīng)通道是否加載了傳輸描述符

BUSY0

通道忙狀態(tài)寄存器

每個(gè)通道占用一位。表示對(duì)應(yīng)通道是否正在搬運(yùn)數(shù)據(jù)

通道中斷寄存器組

ERRINT0

錯(cuò)誤中斷狀態(tài)寄存器

每個(gè)通道占用一位。表示是否有錯(cuò)誤中斷

INTENSET0

中斷使能寄存器

每個(gè)通道占用一位。表示是否使能對(duì)應(yīng)通道的中斷

INTENCLR0

中斷失能寄存器

每個(gè)通道占用一位。表示是否失能對(duì)應(yīng)通道的中斷

INTA0

中斷A狀態(tài)寄存器

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

INTB0

中斷B狀態(tài)寄存器

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

傳輸控制寄存器

SETVALID0

設(shè)置“有效”控制位寄存器

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

SETTRIG0

設(shè)置“觸發(fā)”控制位寄存器

每個(gè)通道占用一位。用于觸發(fā)對(duì)應(yīng)的通道傳輸

ABORT0

通道中止傳輸寄存器

每個(gè)通道占用一位。用于中止對(duì)應(yīng)的通道傳輸

每個(gè)DMA通道還分別有下表中的三個(gè)寄存器,用于配置各個(gè)通道的參數(shù),將在1.4節(jié)詳細(xì)介紹。

寄存器名稱

功能

說(shuō)明

CFG

通道配置寄存器

用于配置通道的使能、觸發(fā)、成組傳輸(Burst)和優(yōu)先級(jí)的選項(xiàng)

CTLSTAT

通道控制狀態(tài)寄存器

用于標(biāo)示通道的有效和觸發(fā)狀態(tài)

XFERCFG

通道傳輸配置寄存器

用于配置通道的各個(gè)配置選項(xiàng)

1.3.2 DMA傳輸描述符

除了上述寄存器外,LPC800DMA控制器通過(guò)位于內(nèi)存中的傳輸描述符,控制每次的DMA傳輸。每個(gè)傳輸描述符有4個(gè)字(32/),內(nèi)容如下:wKgZomWDjhSAcHgNAAAfGz12R-s782.png多個(gè)傳輸描述符可以構(gòu)成一個(gè)連續(xù)的鏈條或循環(huán)鏈,鏈條中的每一個(gè)描述符對(duì)應(yīng)一次DMA傳輸。傳輸?shù)臄?shù)據(jù)數(shù)量、數(shù)據(jù)寬度以及地址變化的方式等,由XFERCFG寄存器的內(nèi)容指定。

每次DMA傳輸開(kāi)始前,DMA控制器都要把一個(gè)完整的描述符讀入,傳輸描述符中偏移地址為0x0的字會(huì)被傳送到XFERCFG寄存器中,用于控制各項(xiàng)傳輸參數(shù)。一個(gè)鏈條的第一次傳輸參數(shù),需要由軟件直接寫入到XFERCFG寄存器,因此鏈條中的第一個(gè)描述符的第一個(gè)字為保留位。在傳輸開(kāi)始時(shí),DMA控制器會(huì)把傳輸區(qū)的地址讀入內(nèi)部寄存器中。

使用描述符的鏈接特性,可以方便地實(shí)現(xiàn)多種數(shù)據(jù)傳輸控制。

例如需要使用SPI驅(qū)動(dòng)一個(gè)LCD屏幕產(chǎn)生動(dòng)畫(huà)效果時(shí),可以配置為下圖所示的乒乓結(jié)構(gòu)的DMA描述符鏈條,CPU只需要不斷地生成顯示圖片,由DMA控制器平行地進(jìn)行圖片數(shù)據(jù)至LCD屏幕的傳送。

wKgZomWDjhSAQY9AAAFL7cj531c211.png? ? ? ? ? ? ? ? ? ??圖3.乒乓結(jié)構(gòu)的DMA描述符鏈

這里使用了三個(gè)傳輸描述符。第一個(gè)描述符(鏈頭)指示將緩沖區(qū)A的數(shù)據(jù)傳輸?shù)?/span>SPI的發(fā)送寄存器,后面兩個(gè)描述符分別指示緩沖區(qū)B和緩沖區(qū)A的數(shù)據(jù),輪流傳輸?shù)?/span>SPI的發(fā)送寄存器。CPU只需要在對(duì)應(yīng)的緩沖區(qū)準(zhǔn)備好數(shù)據(jù),再設(shè)置對(duì)應(yīng)的描述符為“有效”,接下來(lái)DMA控制器就會(huì)直接把數(shù)據(jù)傳送到SPI模塊進(jìn)行發(fā)送。

1.3.3 DMA傳輸通道每個(gè)通信外設(shè)的發(fā)送傳輸可以產(chǎn)生DMA請(qǐng)求,接收傳輸也可以產(chǎn)生DMA請(qǐng)求。

LPC800DMA控制器非常簡(jiǎn)單,每個(gè)片內(nèi)外設(shè)產(chǎn)生的DMA傳輸請(qǐng)求信號(hào),唯一地連接到一個(gè)固定的DMA通道。即如果把片內(nèi)外設(shè)作為DMA傳輸?shù)脑椿蚰繕?biāo),并且希望由該外設(shè)來(lái)控制傳輸?shù)墓?jié)奏(通過(guò)DMA傳輸請(qǐng)求信號(hào)),則必須使用對(duì)應(yīng)的通道。如果能夠使用其它的方法(例如時(shí)鐘觸發(fā)等),保證外設(shè)不會(huì)發(fā)生數(shù)據(jù)溢出的情況,則可以使用任意通道,但這種用法不能最優(yōu)地利用帶寬時(shí)間,除非需要特殊的時(shí)序控制,一般不建議使用。

每個(gè)通道對(duì)應(yīng)的DMA請(qǐng)求源如下表所示:

wKgZomWDjhSAXLVrAACL8bMrNOk751.pngwKgZomWDjhSAd-bfAABMlOrT-KY420.png

表1.DMA通道與DMA請(qǐng)求源的對(duì)應(yīng)表

1.3.4 DMA觸發(fā)源的選擇

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

*:每一個(gè)DMA通道都輸出一個(gè)觸發(fā)信號(hào),所有通道輸出的觸發(fā)信號(hào)都連接到兩個(gè)多選一的選擇器:DMA_INMUX_INMUX0DMA_INMUX_INMUX1,這兩個(gè)多選一選擇器的輸出可以作為另一個(gè)DMA通道的觸發(fā)源選項(xiàng)之一。這個(gè)配置允許多個(gè)DMA通道的協(xié)同操作。

wKgZomWDjhSAFyZlAAFhs4hBuhg801.png? ? ? ? ? ? ? ? ? ? ? ?圖4.DMA觸發(fā)輸入框圖

上圖為某個(gè)DMA通道的觸發(fā)輸入模塊框圖,每個(gè)通道都有一個(gè)這樣相同的電路用于選擇它的觸發(fā)輸入。 1.4 DMA傳輸?shù)恼?qǐng)求、觸發(fā)與生成傳輸概念每個(gè)通道的DMA觸發(fā)信號(hào)相當(dāng)于這個(gè)通道的總開(kāi)關(guān),只有打開(kāi)這個(gè)總開(kāi)關(guān),才能夠進(jìn)行隨后的DMA傳輸操作。

每次DMA傳輸(即圖2示意中的每一次讀寫)的時(shí)機(jī),則由DMA請(qǐng)求信號(hào)決定。

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

成組傳輸控制和DMA傳輸請(qǐng)求控制組合為四種操作模式,他們與觸發(fā)信號(hào)的關(guān)系如下表所示。

表中的DMA傳輸請(qǐng)求信號(hào)以USARTTXRDY為例:

組合模式

使能成組傳輸(TRIGBURST,見(jiàn)1.5.1節(jié))

使能外設(shè)請(qǐng)求(PERIPHREQEN,見(jiàn)1.5.1節(jié))

操作模式說(shuō)

0

0

0

觸發(fā)信號(hào)用于啟動(dòng)完整的DMA傳輸過(guò)程,只需一個(gè)觸發(fā)信號(hào)即可完成所有數(shù)據(jù)傳輸。

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

1

0

1

每個(gè)DMA傳輸請(qǐng)求(TXRDY),只能傳輸一個(gè)數(shù)據(jù)。

2

1

0

每個(gè)觸發(fā)信號(hào)啟動(dòng)一組DMA傳輸,每組傳送BURSTPOWER(見(jiàn)1.5.1節(jié))個(gè)數(shù)據(jù)。因此總共需要(XFERCOUNT/BURSTPOWER)組的傳輸(即需要相同數(shù)目的觸發(fā)信號(hào)),才能完成所有數(shù)據(jù)。

XFERCOUNT位于XFERCFG寄存器(見(jiàn)1.5.2節(jié))。

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

3

1

1

每個(gè)DMA傳輸請(qǐng)求(TXRDY),只能傳輸一個(gè)數(shù)據(jù)。

表3.成組傳輸和外設(shè)請(qǐng)求與觸發(fā)信號(hào)的關(guān)系表

表中的組合模式0適合于從存儲(chǔ)器至存儲(chǔ)器的數(shù)據(jù)塊拷貝;組合模式1適合于常用的通信模塊的數(shù)據(jù)發(fā)送和接收。

組合模式23則視具體的應(yīng)用情況,由用戶自由發(fā)揮。例如,要在USART上發(fā)送若干個(gè)固定長(zhǎng)度的數(shù)據(jù)包,而發(fā)送每個(gè)數(shù)據(jù)包的時(shí)間需要由定時(shí)器來(lái)決定,則可以使用上述的組合模式3,設(shè)置BURSTPOWER為數(shù)據(jù)包的長(zhǎng)度,設(shè)置SCT定時(shí)器產(chǎn)生觸發(fā)信號(hào)(見(jiàn)表2SCT_DMA0/1)。

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

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

1.5 DMA通道參數(shù)寄存器

1.3.1節(jié)中列出的寄存器,用于控制整個(gè)DMA控制器,以及控制每個(gè)通道的使能、中斷和觸發(fā)等狀態(tài)。每個(gè)通道的具體工作模式,由下述三個(gè)寄存器來(lái)描述。

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

wKgZomWDjhWAZvIUAAHyUtsnSG0901.png

各個(gè)控制域的說(shuō)明如下:▲PERIPHREQEN:使能外設(shè)請(qǐng)求。0 – 使能外設(shè)請(qǐng)求;1 – 不使能外設(shè)請(qǐng)求。

每個(gè)通道的外設(shè)請(qǐng)求來(lái)源是固定的,見(jiàn)表1。例如對(duì)應(yīng)SPI0的發(fā)送就緒信號(hào)(TXRDY)DMA通道,在LPC82x/83x中是通道7,在LPC84x中是通道11HWTRIGEN:使能硬件觸發(fā)。硬件觸發(fā)信號(hào)源由DMA_ITRIG_INMUXn寄存器選擇,見(jiàn)1.3.4節(jié)。0 – 使能硬件觸發(fā);1 – 不使能硬件觸發(fā)。TRIGPOL:觸發(fā)極性。TRIGTYPE:觸發(fā)類型。TRIGPOLTRIGTYPE共同決定如何使用觸發(fā)信號(hào),組合關(guān)系如下表。

TRIGTYPE

TRIGPOL

說(shuō)明

0

0

下降沿觸發(fā)

0

1

上升沿觸發(fā)

1

0

低電平觸發(fā)

1

1

高電平觸發(fā)

TRIGBURST:觸發(fā)成組傳輸。

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

注意:XFERCOUNT必須是BURSTPOWER的倍數(shù)。

SRCBURSTWRAP:成組傳輸中每組傳輸結(jié)束后,是否需要恢復(fù)傳輸?shù)脑吹刂贰?/span>0 – 不恢復(fù)源地址;1 – 恢復(fù)源地址。

這個(gè)控制項(xiàng)適合于重復(fù)地讀出相同的數(shù)據(jù)塊,或相同的一組寄存器。DSTBURSTWRAP:成組傳輸中每組傳輸結(jié)束后,是否需要恢復(fù)傳輸?shù)哪繕?biāo)地址。0 – 不恢復(fù)目標(biāo)地址;1 – 恢復(fù)目標(biāo)地址。

這個(gè)控制項(xiàng)適合于重復(fù)地寫入相同的存儲(chǔ)區(qū),例如重復(fù)地讀出一組傳感器的數(shù)值,軟件只關(guān)心即時(shí)的數(shù)值,而不關(guān)心數(shù)值變化的過(guò)程。CHPRIORITY:設(shè)置本通道的優(yōu)先級(jí)。在多個(gè)通道同時(shí)請(qǐng)求獲得總線進(jìn)行傳輸時(shí),優(yōu)先級(jí)高的通道先得到總線的使用權(quán)限。

0 – 最高優(yōu)先級(jí);7 – 最低優(yōu)先級(jí)。

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

wKgZomWDjhWAX_oHAAIeMtFOje4522.png

該寄存器的內(nèi)容給出了當(dāng)前DMA傳輸?shù)母黜?xiàng)參數(shù)。一個(gè)傳輸描述符指定的一次傳輸結(jié)束后,DMA控制器會(huì)自動(dòng)地讀入鏈條中的下一個(gè)描述符,描述符的第一個(gè)字的內(nèi)容會(huì)加載到XFERCFG寄存器,見(jiàn)1.3.2節(jié)的說(shuō)明。

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

1 – 設(shè)置此位表示該通道的觸發(fā)條件立即滿足。

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

1 – 清除。當(dāng)前描述符指示的傳輸結(jié)束后,清除觸發(fā)條件。

注意:只有軟件觸發(fā)條件和邊沿觸發(fā)條件可以被清除,而電平觸發(fā)條件不能被清除。SETINTA:當(dāng)前描述符的傳輸結(jié)束后,是否產(chǎn)生中斷標(biāo)志INTA。0 – 不產(chǎn)生中斷標(biāo)志;1 – 產(chǎn)生中斷標(biāo)志。▲SETINTB:當(dāng)前描述符的傳輸結(jié)束后,是否產(chǎn)生中斷標(biāo)志INTB。0 – 不產(chǎn)生中斷標(biāo)志;1 – 產(chǎn)生中斷標(biāo)志。

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

注意:如果要求的數(shù)據(jù)寬度是16位或32位,則傳輸?shù)牡刂芬脖仨毞謩e是2字節(jié)或4字節(jié)對(duì)齊的。SRCINC:表示每次傳輸一個(gè)數(shù)據(jù)后,源地址的增量變化。0 – 地址無(wú)變化。

1 – 地址按數(shù)據(jù)寬度+1,指向數(shù)據(jù)區(qū)中的下一個(gè)數(shù)據(jù)。

2 – 地址按數(shù)據(jù)寬度+2。

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

SRCINCDSTINC取值為0,最常見(jiàn)的應(yīng)用場(chǎng)景是面對(duì)外設(shè)寄存器的讀寫,例如傳送一個(gè)數(shù)據(jù)塊至SPI0TXDAT,或從USARTRXDAT讀出一組數(shù)據(jù)至存儲(chǔ)區(qū)。

SRCINCDSTINC取值為1,最常見(jiàn)的應(yīng)用場(chǎng)景對(duì)一個(gè)連續(xù)的存儲(chǔ)區(qū)的讀寫。

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

傳輸?shù)淖止?jié)總數(shù)為:(XFERCOUNT + 1) *WIDTH。

注意1:在DMA傳輸過(guò)程中,DMA控制器會(huì)遞減該數(shù)值,因此不能在傳輸過(guò)程中或傳輸結(jié)束后,讀出該域而得知預(yù)設(shè)的傳輸數(shù)目。

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

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

當(dāng)失能DMA控制器時(shí),見(jiàn)CTRL寄存器。

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

通常的情況是,當(dāng)準(zhǔn)備好一個(gè)描述符A,尤其是使用描述符鏈時(shí),描述符A所對(duì)應(yīng)的存儲(chǔ)區(qū)的數(shù)據(jù)可能還沒(méi)有準(zhǔn)備好,循環(huán)的乒乓結(jié)構(gòu)就是一個(gè)很好的例子。這種情況下,就需要先設(shè)置描述符ACFGVALID=0,待數(shù)據(jù)區(qū)準(zhǔn)備好后再設(shè)置它為有效。這樣延遲設(shè)置描述符有效,是通過(guò)SETVALID0寄存器來(lái)完成。

SETVALID0寄存器的每一位對(duì)應(yīng)一個(gè)DMA通道,第n位寫’1’表示延遲設(shè)置通道n的描述符有效。

使用SETVALID0寄存器實(shí)現(xiàn)延遲設(shè)置描述符有效,是為了避免設(shè)置錯(cuò)誤。設(shè)想一下,當(dāng)DMA控制器已經(jīng)在運(yùn)行鏈上的某個(gè)描述符B時(shí),軟件無(wú)法知道另一個(gè)描述符A是否已經(jīng)被讀入DMA控制器。如果它還未被讀入DMA控制器,則可以直接操作描述符A所在的存儲(chǔ)區(qū);如果它已經(jīng)被讀入DMA控制器,則應(yīng)該操作XFERCFG寄存器。

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

經(jīng)過(guò)以上介紹可以看到,如果當(dāng)前加載到DMA控制器的描述符是有效的,設(shè)置SETVALID0寄存器表示延遲設(shè)置鏈中下一個(gè)描述符為有效,此時(shí)CTLSTAT寄存器的VALIDPENDING為‘1’,標(biāo)示這種狀態(tài);當(dāng)下一個(gè)描述符被讀入DMA控制器時(shí),經(jīng)延遲的設(shè)置描述符有效的操作才最終完成,此時(shí)VALIDPENDING位被清除。如果當(dāng)前加載到DMA控制器的描述符是無(wú)效的,設(shè)置SETVALID0寄存器表示改變當(dāng)前這個(gè)描述符為有效,不需經(jīng)過(guò)延遲,操作立即生效。

使用這種延遲機(jī)制,軟件可以從容地先準(zhǔn)備好描述符鏈,然后再按部就班地準(zhǔn)備好數(shù)據(jù)區(qū),逐步推進(jìn)數(shù)據(jù)傳輸進(jìn)程,而不必費(fèi)周折查詢等待DMA控制器的狀態(tài)。

1.7若干DMA傳輸例程

本節(jié)的幾個(gè)例程,分別展示幾種DMA的常見(jiàn)用法。所有例程都會(huì)用到這樣幾個(gè)結(jié)構(gòu)體。

結(jié)構(gòu)體DMA_CHDESC_T是所有通道的描述符鏈中的第一個(gè)描述符。

typedef struct {

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

uint32_t source; // DMA傳輸源數(shù)據(jù)區(qū)的末地址

uint32_t dest; // DMA傳輸目標(biāo)數(shù)據(jù)區(qū)的末地址

uint32_t next; // 鏈接到下一個(gè)描述符

} DMA_CHDESC_T;

所有通道的第一個(gè)描述符,需要按順序放在一個(gè)DMA_CHDESC_T數(shù)組中,而且這個(gè)數(shù)組的開(kāi)始地址必須是512字節(jié)對(duì)齊的內(nèi)存地址:

ALIGN(512) DMA_CHDESC_T Chan_Desc_Table[];

每個(gè)通道的第一個(gè)描述符,必須放在這個(gè)數(shù)組中與通道編號(hào)對(duì)應(yīng)的單元中。例如USART1_RX_DMA通道的第一個(gè)描述符需要放在數(shù)組的第2個(gè)單元中(見(jiàn)表1)。

結(jié)構(gòu)體DMA_RELOADDESC_T適用于其它描述符。所有描述符必須位于16字節(jié)對(duì)齊的內(nèi)存地址。

typedef struct {

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

uint32_t source; // DMA傳輸源數(shù)據(jù)區(qū)的末地址

uint32_t dest; // DMA傳輸目標(biāo)數(shù)據(jù)區(qū)的末地址

uint32_t next; // 鏈接到下一個(gè)描述符

} DMA_RELOADDESC_T;

1.7.1DMA執(zhí)行內(nèi)存中的數(shù)據(jù)塊拷貝

使用DMA的最簡(jiǎn)單應(yīng)用就是在內(nèi)存中拷貝一個(gè)數(shù)據(jù)塊,這是一個(gè)非常有效率的搬移數(shù)據(jù)塊的方法,尤其是數(shù)據(jù)量比較大時(shí),CPU可以同時(shí)執(zhí)行更多的操作。DMA拷貝數(shù)據(jù)塊不涉及到任何外設(shè)請(qǐng)求,使用軟件觸發(fā),所以也不涉及到任何硬件的觸發(fā)。

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

wKgZomWDjhWAQg70AAAtAqdSbxI093.png下面是初始化DMA控制器,并啟動(dòng)DMA的函數(shù)。代碼片段1.使用DMA在內(nèi)存中拷貝一個(gè)數(shù)據(jù)塊

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 | // 暫時(shí)設(shè)置為無(wú)效
12                0 << DMA_XFERCFG_RELOAD   | // 沒(méi)有下一個(gè)描述符
13                1 << DMA_XFERCFG_SWTRIG   | // 軟件觸發(fā)
14                1 << DMA_XFERCFG_CLRTRIG  | // 傳輸結(jié)束時(shí)清除觸發(fā)標(biāo)志
15                1 << DMA_XFERCFG_SETINTA  | // 傳輸結(jié)束時(shí)設(shè)置INTA中斷
16                0 << DMA_XFERCFG_SETINTB  |
17                2 << DMA_XFERCFG_WIDTH    | // 數(shù)據(jù)寬度為32位
18                1 << DMA_XFERCFG_SRCINC   | // 每次傳輸后源地址遞增
19                1 << DMA_XFERCFG_DSTINC   | // 每次傳輸后目標(biāo)地址遞增
20                xfercount << DMA_XFERCFG_XFERCOUNT; // 傳輸長(zhǎng)度
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  }

在這個(gè)例程中,用到了宏定義CH_USART0_RX,這是對(duì)應(yīng)USART0接收方向的DMA通道號(hào)(見(jiàn)表1),在頭文件中定義了所有的通道號(hào):

#define CH_USART0_RX 0 // USART0接收就緒

#define CH_USART0_TX 1 // USART0發(fā)送就緒

#define CH_USART1_RX 2 // USART1接收就緒

#define CH_USART1_TX 3 // USART1發(fā)送就緒

......

......

Chan_Desc_Table所有通道的描述符鏈頭構(gòu)成的數(shù)組,這個(gè)數(shù)組的起始地址必須是512字節(jié)對(duì)齊的。

ALIGN(512) DMA_CHDESC_T Chan_Desc_Table[1];

在本例程中,由于使用的是通道0,而沒(méi)有使用其它通道,所以在數(shù)組中只配置了一個(gè)單元。

原則上,這個(gè)數(shù)組中對(duì)應(yīng)不使用的通道的描述符單元,可以挪做其它用途。

在這個(gè)例程里,配置好所有的寄存器和描述符,并且使能了整個(gè)DMA控制器后,在第33行配置了對(duì)應(yīng)的傳輸符為有效,該語(yǔ)句執(zhí)行后DMA傳輸立即開(kāi)始了。

如果第13行沒(méi)有配置XFERCFG的“軟件觸發(fā)”位,執(zhí)行第33行后DMA通道還需要等待觸發(fā)信號(hào)才能開(kāi)始傳輸,第34行就是由軟件發(fā)出DMA觸發(fā)信號(hào)的另一種途徑。

由上面的介紹可以看出,可以有多種方式,靈活地安排啟動(dòng)DMA傳輸?shù)臅r(shí)機(jī)和方法,讓用戶可以更加有效地安排自己的應(yīng)用流程。

下面是這個(gè)例程的主函數(shù)和中斷處理程序。

代碼片段2.使用DMA拷貝一個(gè)數(shù)據(jù)塊的中斷函數(shù)和主函數(shù)

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傳輸結(jié)束后產(chǎn)生中斷,在中斷函數(shù)中將軟件標(biāo)志置’1’,主函數(shù)可以知道DMA傳輸是否已經(jīng)完成。在實(shí)際的項(xiàng)目中,用戶程序可以替換上述21~23行的代碼,執(zhí)行其它的一些操作。

1.7.2DMA執(zhí)行USART0的連續(xù)發(fā)送(硬件觸發(fā))

下面這個(gè)例程是使用DMA通過(guò)USART0發(fā)送一個(gè)字符串,需要配置使用USART0的發(fā)送請(qǐng)求,并采用開(kāi)發(fā)板上的USER_KEY產(chǎn)生硬件觸發(fā),即按下按鍵后才送出所有數(shù)據(jù),用戶可以在PC端的虛擬串口上看到送出的字符串。

首先還是DMA的初始化函數(shù),這個(gè)函數(shù)與前面的數(shù)據(jù)塊搬運(yùn)初始化基本一致,指示CFGXFERCFG寄存器的內(nèi)容有所變化。

代碼片段3. DMA通過(guò)USART0發(fā)送字符串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 | // 外設(shè)請(qǐng)求
11                   1 << DMA_CFG_HWTRIGEN |  // 硬件觸發(fā)
12                   0 << DMA_CFG_TRIGTYPE |  // 邊沿觸發(fā)
13                   0 << DMA_CFG_TRIGPOL;    // 下降沿觸發(fā)
14  
15      xfercfg = 0 << DMA_XFERCFG_CFGVALID | // 暫時(shí)設(shè)置為無(wú)效
16                0 << DMA_XFERCFG_RELOAD   | // 沒(méi)有下一個(gè)描述符
17                0 << DMA_XFERCFG_SWTRIG   | // 沒(méi)有軟件觸發(fā)
18                1 << DMA_XFERCFG_CLRTRIG  | // 傳輸結(jié)束時(shí)清除觸發(fā)標(biāo)志
19                1 << DMA_XFERCFG_SETINTA  | // 傳輸結(jié)束時(shí)設(shè)置INTA中斷
20                0 << DMA_XFERCFG_SETINTB  |
21                0 << DMA_XFERCFG_WIDTH    | // 數(shù)據(jù)寬度為8位
22                1 << DMA_XFERCFG_SRCINC   | // 每次傳輸后源地址遞增
23                0 << DMA_XFERCFG_DSTINC   | // 每次傳輸后目標(biāo)地址不遞增
24                xfercount << DMA_XFERCFG_XFERCOUNT; // 傳輸長(zhǎng)度
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  }

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

USART0的初始化部分與USART章節(jié)的代碼完全一致,現(xiàn)抄錄如下。

代碼片段4.基本UART收發(fā)例程的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; // 設(shè)置USART時(shí)鐘的分頻系數(shù)
10      LPC_SYSCON->UARTFRGMULT = 4; 
11      LPC_SYSCON->UARTFRGDIV = 255; 
12      LPC_USART0->BRG = 16 - 1;
13  
14      // 8個(gè)數(shù)據(jù)位,無(wú)校驗(yàn)位,1個(gè)停止位,沒(méi)有硬件流控,異步模式
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  }

接下來(lái)是本節(jié)的重點(diǎn)。代碼片段3的第11~13行,配置DMA通道為硬件觸發(fā)信號(hào)的下降沿觸發(fā),下面是初始化PINTINT,使用USER_KEY產(chǎn)生觸發(fā)信號(hào),和對(duì)應(yīng)的中斷程序。代碼片段5.初始化按鍵產(chǎn)生DMA硬件觸發(fā)信號(hào)

01  #define PINTSEL0 0       // 定義引腳中斷0的編號(hào)
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<// 清除上升沿中斷標(biāo)志
08      if (LPC_PIN_INT->FALL & (1<
09          LPC_PIN_INT->FALL = 1<// 清除下降沿中斷標(biāo)志
10  }
11  
12  void PINT_Init_Key_User()
13  {
14      LPC_GPIO_PORT->DIRCLR0 = 1 << KEY_USER;   // 配置USER_KEY對(duì)應(yīng)的引腳為輸入
15      LPC_SYSCON->PINTSEL[PINTSEL0] = KEY_USER; // USER_KEY對(duì)應(yīng)對(duì)應(yīng)到引腳中斷0(PINTSEL0)
16      LPC_PIN_INT->ISEL = 0 << PINTSEL0;        // 配置引腳中斷0(PINTSEL0)為邊沿觸發(fā)
17      LPC_PIN_INT->IENR = 1 << PINTSEL0;        // 配置引腳中斷0(PINTSEL0)是上升沿觸發(fā)
18      LPC_PIN_INT->IENF = 0 << PINTSEL0;        // 配置引腳中斷0(PINTSEL0)不是下降沿觸發(fā)
19      LPC_PIN_INT->IST = 0xFF;                  // 清除所有可能的引腳中斷標(biāo)志
20      NVIC_EnableIRQ(PININT0_IRQn);             // 使能引腳中斷
21  }

上述代碼是對(duì)PINTINT的初始化,它配置USER_KEY對(duì)應(yīng)的引腳產(chǎn)生一個(gè)中斷信號(hào),確切地說(shuō)是按鍵按下再抬起時(shí)的上升沿將產(chǎn)生中斷。04行的中斷處理程序中,只是簡(jiǎn)單地清除可能的上升沿或下降沿中斷標(biāo)志。

這里要澄清兩個(gè)概念,一個(gè)是引腳中斷的觸發(fā)信號(hào),另一個(gè)是DMA的觸發(fā)信號(hào)。前者是引腳上的信號(hào),用于產(chǎn)生中斷;后者是芯片內(nèi)部的中斷標(biāo)志對(duì)應(yīng)的信號(hào),用于觸發(fā)DMA傳輸。兩個(gè)信號(hào)分別有上升沿和下降沿的選項(xiàng),但兩者是不等價(jià)的,本例程中引腳中斷選擇的是上升沿,而DMA觸發(fā)信號(hào)選擇的是下降沿。

下圖顯示出了這兩個(gè)信號(hào)之間的關(guān)系:

wKgZomWDjhWAP2UqAADYuOAcS-w277.png? ? ? ? ? ? ? ? ? ? ??圖5.引腳中斷與DMA觸發(fā)信號(hào)的關(guān)系圖

圖中的時(shí)間點(diǎn)④是觸發(fā)DMA傳輸?shù)臅r(shí)間,這個(gè)時(shí)間點(diǎn)與代碼片段507行的執(zhí)行相對(duì)應(yīng)。如果清除上升沿中斷的動(dòng)作被推遲,則DMA傳輸?shù)臅r(shí)間也會(huì)被推遲,所以用戶要盡快地響應(yīng)PINTINT中斷并清除中斷標(biāo)志,以實(shí)現(xiàn)快速高效傳輸。

下面是主函數(shù)代碼,主函數(shù)中調(diào)用了前面介紹過(guò)的DMA、USARTPINTINT函數(shù)。

代碼片段6.硬件觸發(fā)DMA傳輸UART發(fā)送數(shù)據(jù)例程

01  const unsigned char Hello[] = "Hello DMA World!
"; // 待發(fā)送的數(shù)據(jù)串
02  void main()
03  {
04      USART0_init();      // 初始化USART0
05  
06      DMA_IntA_Flag = 0;  // 清除DMA中斷標(biāo)記
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  }

這個(gè)主函數(shù)與前面那個(gè)例程(見(jiàn)代碼片段2)的主要區(qū)別,就是第1011行配置DMA觸發(fā)源和對(duì)觸發(fā)源(引腳中斷0)的初始化。

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

1.7.3DMA執(zhí)行USART0的成組發(fā)送

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

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

wKgZomWDjhWAIf71AAGIuEduoic486.png圖6.DMA執(zhí)行USART0的成組發(fā)送例程的描述符鏈另外,例程中安排了以成組(Burst)方式發(fā)送每個(gè)字符串,即每次觸發(fā)只發(fā)送BURSTPOWER指定長(zhǎng)度的數(shù)據(jù),見(jiàn)1.5.1的說(shuō)明。

和上節(jié)一樣,例程中的觸發(fā)源也是與USER_KEY相連的引腳中斷0。

本例程用到下述變量。

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

下面是DMA初始化的代碼代碼片段7.執(zhí)行USART0的成組發(fā)送例程的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 |   // 外設(shè)請(qǐng)求
11                   1 << DMA_CFG_HWTRIGEN |  // 硬件觸發(fā)
12                   0 << DMA_CFG_TRIGTYPE |  // 邊沿觸發(fā)
13                   0 << DMA_CFG_TRIGPOL |   // 下降沿觸發(fā)
14                   1 << DMA_CFG_TRIGBURST | // 成組傳輸模式
15                   3 << DMA_CFG_BURSTPOWER; // 每組為8(23)個(gè)數(shù)據(jù)
16  
17      xfercfg = 0 << DMA_XFERCFG_CFGVALID | // 暫時(shí)設(shè)置為無(wú)效
18                1 << DMA_XFERCFG_RELOAD   | // 有下一個(gè)描述符
19                0 << DMA_XFERCFG_SWTRIG   | // 沒(méi)有軟件觸發(fā)
20                1 << DMA_XFERCFG_CLRTRIG  | // 傳輸結(jié)束時(shí)清除觸發(fā)標(biāo)志
21                1 << DMA_XFERCFG_SETINTA  | // 傳輸結(jié)束時(shí)設(shè)置INTA中斷
22                0 << DMA_XFERCFG_SETINTB  |
23                0 << DMA_XFERCFG_WIDTH    | // 數(shù)據(jù)寬度為8位
24                1 << DMA_XFERCFG_SRCINC   | // 每次傳輸后源地址遞增
25                0 << DMA_XFERCFG_DSTINC   | // 每次傳輸后目標(biāo)地址不遞增
26                xfercount << DMA_XFERCFG_XFERCOUNT; // 傳輸長(zhǎng)度
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; // 去掉字符串結(jié)尾的字符’’
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; // 去掉字符串結(jié)尾的字符’’ 
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控制器中設(shè)置的兩個(gè)中斷INTAINTB的內(nèi)部機(jī)制完全一致,分為兩個(gè)中斷源只是為了讓用戶區(qū)分對(duì)應(yīng)的描述符,用戶可以自由安排。本例中設(shè)置描述符A執(zhí)行結(jié)束后會(huì)產(chǎn)生中斷A,描述符B執(zhí)行結(jié)束后會(huì)產(chǎn)生中斷B,因此相比前一個(gè)例程中斷處理程序也多了出來(lái)INTB的代碼。

代碼片段8.執(zhí)行USART0的成組發(fā)送例程中斷處理程序
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  }

每次執(zhí)行完一個(gè)描述符后,就會(huì)相應(yīng)地產(chǎn)生一個(gè)中斷(INTAINTB),用戶可以自行在代碼片段8的第0509行安插代碼在適當(dāng)?shù)臅r(shí)候結(jié)束整個(gè)描述符鏈的DMA傳輸,例如當(dāng)循環(huán)次數(shù)滿足一定要求時(shí)。

代碼片段9.執(zhí)行USART0的成組發(fā)送例程的主函數(shù)

01  void main()
02  {
03      USART0_init();      // 初始化USART0
04  
05      DMA_IntA_Flag = DMA_IntB_Flag = 0;  // 清除DMA中斷標(biāo)記
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  }

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

wKgZomWDjhWAQFD2AAIY--ljgGc244.png

END

更多恩智浦AI-IoT市場(chǎng)和產(chǎn)品信息,邀您同時(shí)關(guān)注“NXP客?!蔽⑿殴娞?hào)

wKgZomWDjhWAF7paAABCdkRE230661.jpg ? ? ?

NXP客棧


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

長(zhǎng)按二維碼,關(guān)注我們

恩智浦MCU加油站


這是由恩智浦官方運(yùn)營(yíng)的公眾號(hào),著重為您推薦恩智浦MCU的產(chǎn)品信息、開(kāi)發(fā)技巧、教程文檔、培訓(xùn)課程等內(nèi)容。

wKgZomWDjhaAAHlMAAATNlPH08Y038.jpg ?

長(zhǎng)按二維碼,關(guān)注我們


原文標(biāo)題:LPC800前生今世-第九章 直接存儲(chǔ)器訪問(wèn) (DMA)

文章出處:【微信公眾號(hào):恩智浦MCU加油站】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。


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

    關(guān)注

    146

    文章

    16667

    瀏覽量

    347769
  • 恩智浦
    +關(guān)注

    關(guān)注

    14

    文章

    5788

    瀏覽量

    104682

原文標(biāo)題:LPC800前生今世-第九章 直接存儲(chǔ)器訪問(wèn) (DMA)

文章出處:【微信號(hào):NXP_SMART_HARDWARE,微信公眾號(hào):恩智浦MCU加油站】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    第九章-PID整定方法 STM32PID驅(qū)動(dòng)編碼 STM32PID控制電機(jī)轉(zhuǎn)速

    控制、PID循跡、PID跟隨、遙控、避障、PID角度控制、視覺(jué)控制、電磁循跡、RTOS等功能。 ?# 第九章-PID整定方法 ## 9.1-調(diào)整合適的采樣周期和PID調(diào)參方法 正如
    的頭像 發(fā)表于 08-21 16:37 ?658次閱讀
    <b class='flag-5'>第九章</b>-PID整定方法 STM32PID驅(qū)動(dòng)編碼<b class='flag-5'>器</b> STM32PID控制電機(jī)轉(zhuǎn)速

    請(qǐng)問(wèn)DMA控制可以減輕CPU負(fù)擔(dān)嗎?

    直接存儲(chǔ)器訪問(wèn) ( DMA )控制,可以在內(nèi)存和/或外設(shè)之間傳輸數(shù)據(jù),而不需要 CPU 參與每次傳輸。合理利用
    的頭像 發(fā)表于 03-28 09:41 ?507次閱讀
    請(qǐng)問(wèn)<b class='flag-5'>DMA</b>控制<b class='flag-5'>器</b>可以減輕CPU負(fù)擔(dān)嗎?

    LPC800 MCU技術(shù)資源合集:純干貨,快接??!

    作為恩智浦新一代基于Arm Cortex-M0+的微控制,LPC800系列不僅顯著提升了性能,還極大地降低了功耗,提高了能效,加之廣泛的伙伴生態(tài)合作體系支持,為嵌入式開(kāi)發(fā)者提供了一個(gè)簡(jiǎn)單易用
    的頭像 發(fā)表于 12-27 08:10 ?414次閱讀
    <b class='flag-5'>LPC800</b> MCU技術(shù)資源合集:純干貨,快接??!

    LPC800前生今世-第八 引腳中斷和引腳組合邏輯 (Pin Interrupt &amp; Pin Pattern)

    外部引腳可以觸發(fā)芯片內(nèi)部的中斷,這是每一個(gè)通用MCU都具備的基本功能。 在LPC800中,所有外部引腳都可以配置為產(chǎn)生中斷的觸發(fā)源。每個(gè)引腳不但可以獨(dú)立地觸發(fā)中斷,還可以和其它引腳的信號(hào)狀態(tài)進(jìn)行組合
    的頭像 發(fā)表于 12-14 16:20 ?1546次閱讀
    <b class='flag-5'>LPC800</b><b class='flag-5'>前生</b><b class='flag-5'>今世</b>-第八<b class='flag-5'>章</b> 引腳中斷和引腳組合邏輯 (Pin Interrupt &amp; Pin Pattern)

    隨機(jī)訪問(wèn)存儲(chǔ)器(RAM)和只讀存儲(chǔ)器(ROM)的區(qū)別

    在數(shù)字電子設(shè)備中,存儲(chǔ)器是至關(guān)重要的部分。它負(fù)責(zé)存儲(chǔ)和檢索數(shù)據(jù),以支持各種計(jì)算和數(shù)據(jù)處理任務(wù)。在存儲(chǔ)器市場(chǎng)中,有兩種主要的類型:隨機(jī)訪問(wèn)存儲(chǔ)器
    的頭像 發(fā)表于 12-05 15:46 ?1658次閱讀
    隨機(jī)<b class='flag-5'>訪問(wèn)</b><b class='flag-5'>存儲(chǔ)器</b>(RAM)和只讀<b class='flag-5'>存儲(chǔ)器</b>(ROM)的區(qū)別

    存儲(chǔ)器到外設(shè)DMA動(dòng)態(tài)訪問(wèn)技術(shù)

     存儲(chǔ)器到外設(shè)數(shù)據(jù)復(fù)制的一個(gè)例子是大量數(shù)據(jù)應(yīng)該通過(guò)通信外設(shè)(例如UART)傳輸?shù)那闆r;如果沒(méi)有DMA,CPU將需要在傳輸數(shù)據(jù)時(shí)進(jìn)行“阻塞”(通常傳輸速度相對(duì)較慢,取決于通信協(xié)議的速度),或者使用中斷來(lái)管理傳輸(由于中斷上下文切換,這會(huì)增加額外的處理開(kāi)銷)。
    發(fā)表于 11-27 15:22 ?417次閱讀

    第九章 數(shù)模和模數(shù)轉(zhuǎn)換

    電子發(fā)燒友網(wǎng)站提供《第九章 數(shù)模和模數(shù)轉(zhuǎn)換.ppt》資料免費(fèi)下載
    發(fā)表于 11-18 09:14 ?0次下載
    <b class='flag-5'>第九章</b> 數(shù)模和模數(shù)轉(zhuǎn)換

    簡(jiǎn)單易用,設(shè)計(jì)靈活!LPC800微控制,加速實(shí)現(xiàn)從8位到32位的平穩(wěn)升級(jí)!

    從8位向32位平臺(tái)升級(jí),是嵌入式開(kāi)發(fā)的大勢(shì)所趨。如何讓這個(gè)過(guò)程更平穩(wěn)、更絲滑?恩智浦給出的解決方案就是——LPC800系列32位微控制。 作為新一代基于Arm Cortex-M0+的微控制
    的頭像 發(fā)表于 11-10 08:15 ?382次閱讀
    簡(jiǎn)單易用,設(shè)計(jì)靈活!<b class='flag-5'>LPC800</b>微控制<b class='flag-5'>器</b>,加速實(shí)現(xiàn)從8位到32位的平穩(wěn)升級(jí)!

    LPC800 前生今世-第七 輸入輸出控制(GPIO)

    各系列引腳數(shù) 沒(méi)有單獨(dú)的模擬比較供電引腳,其它封裝都有單獨(dú)的模擬比較供電引腳。 從表 1 可以看出,所有 LPC800 產(chǎn)品的引腳利用率是非常高的,除了供電引腳外,所有其它引腳,包含調(diào)試引腳、外接晶振的引腳和所有具有模擬功
    的頭像 發(fā)表于 11-02 08:55 ?585次閱讀
    <b class='flag-5'>LPC800</b> <b class='flag-5'>前生</b><b class='flag-5'>今世</b>-第七<b class='flag-5'>章</b> 輸入輸出控制<b class='flag-5'>器</b>(GPIO)

    STM32基礎(chǔ)知識(shí):串口通信-DMA方式

    直接存儲(chǔ)器訪問(wèn) (DMA) : 用于在外設(shè)與存儲(chǔ)器之間以及存儲(chǔ)器
    的頭像 發(fā)表于 10-26 11:48 ?4755次閱讀
    STM32基礎(chǔ)知識(shí):串口通信-<b class='flag-5'>DMA</b>方式

    LPC800前生今世 第六-開(kāi)關(guān)矩陣(SWM: Switch Matrix)

    總體概述 開(kāi)關(guān)矩陣顧名思義就是一個(gè)由多個(gè),甚至多組開(kāi)關(guān)組成的陣列,這個(gè)陣列的目的就是把片內(nèi)外設(shè)的輸入輸出信號(hào)線,按照用戶的意向,通過(guò)編程連接到特定的外部引腳上。 開(kāi)關(guān)矩 陣可以為LPC800的使用者
    的頭像 發(fā)表于 10-26 09:25 ?1806次閱讀
    <b class='flag-5'>LPC800</b><b class='flag-5'>前生</b><b class='flag-5'>今世</b> 第六<b class='flag-5'>章</b>-開(kāi)關(guān)矩陣(SWM: Switch Matrix)

    LPC800前生今世 第五-系統(tǒng)配置模塊SYSCON

    模塊之間的配置或資源分配,則需要統(tǒng)一在Syscon中進(jìn)行,例如時(shí)鐘的分頻、各功能模塊的復(fù)位、低功耗模式的配置等。 1.1 SYSCON的基本特征 LPC800全系列的每個(gè)型號(hào)都標(biāo)配系統(tǒng)配置模塊(SYSCON),不同子系列的功能基本差不多。 不同子系列之間差別主要體現(xiàn)在整體功能的
    的頭像 發(fā)表于 10-19 11:25 ?586次閱讀
    <b class='flag-5'>LPC800</b><b class='flag-5'>前生</b><b class='flag-5'>今世</b> 第五<b class='flag-5'>章</b>-系統(tǒng)配置模塊SYSCON

    LPC800前生今世 第四-系列總覽指南書(shū)中的例程和項(xiàng)目文件

    供的ZIP文件解壓到某個(gè)目錄下(例如Workspace_IAR),就可以看到這個(gè)工作區(qū)的文件和其它一些目錄,下面是目錄截圖: LPC80
    的頭像 發(fā)表于 10-12 08:55 ?379次閱讀
    <b class='flag-5'>LPC800</b><b class='flag-5'>前生</b><b class='flag-5'>今世</b> 第四<b class='flag-5'>章</b>-系列總覽指南書(shū)中的例程和項(xiàng)目文件

    中國(guó)科學(xué)家成功研制“九章三號(hào)” 255個(gè)光子的量子計(jì)算原型機(jī)

    ? ? ? ?中國(guó)科學(xué)家再立新功,中國(guó)科學(xué)技術(shù)大學(xué)潘建偉、陸朝陽(yáng)、劉乃樂(lè)等組成的研究團(tuán)隊(duì)與中國(guó)科學(xué)院上海微系統(tǒng)與信息技術(shù)研究所、國(guó)家并行計(jì)算機(jī)工程技術(shù)研究中心成功研制“九章三號(hào)”量子計(jì)算原型機(jī)
    的頭像 發(fā)表于 10-11 17:06 ?1317次閱讀

    九章云極完成3億元融資,加速多模態(tài)大模型行業(yè)落地

    2023年6月,九章云極宣布產(chǎn)品體系升級(jí),發(fā)布DataCanvas Alaya九章元識(shí)大模型、DingoDB多模向量數(shù)據(jù)庫(kù)等多款產(chǎn)品,構(gòu)成“AIFS人工智能基礎(chǔ)軟件”“DataPilot數(shù)據(jù)領(lǐng)航員”產(chǎn)品體系。至此,九章云極成功構(gòu)
    的頭像 發(fā)表于 10-09 10:10 ?858次閱讀