1、引言
由于UART串行口的廣泛應用,在傳統的8位和16位的處理器以及32位處理器中,一般都帶有UART串行口。傳統的基于UART的數據通訊中,采用的方式一般有兩種,查詢式和中斷式。查詢方式下CPU的負擔較重,浪費了處理器的能力,不能夠很好的處理其他的事件;中斷方式可以在接收到信息或需要發送數據時產生中斷,在中斷服務程序中完成數據的接收與發送。相對于查詢方式,中斷方式的CPU利用率要高。在CPU任務簡單的系統中,使用中斷方式確實是一種好方法。但是在復雜的系統中,比如移動機器人,處理器需要處理串行口通信,多個傳感器數據的采集以及處理,實時軌跡的生成,運動軌跡插補以及位置閉環控制等等任務,牽扯到多個中斷的優先級分配問題。為了保證數據發送與接收的可靠性,需要把UART的中斷優先級設計較高,但是系統可能還有其他的需要更高優先級的中斷,必須保證其定時的準確,這樣就有可能造成串行通訊的中斷不能及時響應,從而造成數據丟失。為此,筆者在采用S3c44b0x設計移動機器人控制器時,為了保證串行通訊的數據及時可靠的接收,同時兼顧其它任務不受影響,采用了基于DMA和中斷方式相結合的UART串行通信方式。DMA是 Direct Memory Access的縮寫,意思是“存儲器直接訪問”,它是一種高速的數據傳輸操作,允許在外部設備和存儲器之間直接讀/寫數據,即不通過CPU,也不需要 CPU干預。整個數據傳輸操作是在一個稱作DMA控制器的控制下進行的。CPU除了在數據傳輸開始和結束時做一點處理外,在傳輸過程中可以進行其他的工作。這樣,在大部分時間里,CPU和輸入/輸出設備都處于并行的操作狀態。其基本原理可以查閱教科書,此處不贅述。這里僅介紹S3c44c0x的DMA控制器。
2、S3c44b0x中的DMA控制器和UART的特性
S3c44b0x采用ARM7TDMI核,具有4 通道的DMA控制器,并且對應有4個中斷。其中兩個DMA通道稱做ZDMA(通用DMA),連接在SSB(系統總線)上,另外兩個DMA通道稱做 BDMA(橋DMA),連接于SSB和SPB(外設總線)之間的接口層。連接于SSB上的ZDMA控制器可以用于從存儲器到存儲器,從存儲器到固定目標的 I/O存儲器,和從I/O 設備到存儲器之間的數據傳輸。另外的兩個BDMA 控制器主要作用是在外部存儲器和內部外設之間傳輸數據,這里的I內部外設包括SIO,IIS,TIMER和UART等。BDMA與ZDMA可以通過軟件啟動,也可以通過硬件啟動。此設計中我們使用UART0,與其對應的DMA通道為BDMA0。其控制器框圖如圖1所示。
S3c44b0x的UART單元提供2個獨立的異步串行I/O口,每個口均可以工作于中斷模式或者DMA模式,即 UART可以產生內部中斷請求或者DMA請求,在CPU的串行I/O口之間傳送數據,支持高達115.2KBPS的傳輸速率,每個UART通道包含2個 16位的分別用于發送和接收的FIFO通道。
3、硬件電路設計
由于S3c44b0x自帶支持UART的DMA控制器,所以關于DMA硬件部分不需要作任何的工作。S3C44B0X的I/O口電壓為3.3V,而PC機一端的串口采用RS232電平,所以中間要經過電平轉換,在此采用SP3232E芯片。連接電路如圖2所示。
4、基于DMA和中斷相結合的通訊軟件設計
在以S3C44B0X為核心組成的移動機器人中,采用3路PWM定時器驅動3個直流電機,通用的GPIO口和A/D口連接外部的紅外和超聲以及激光傳感器,使用UART0完成與上位機(PC)的數據交換,這些數據是單向的(從上位機發送給S3c44b0x),主要是上位機傳給機器人控制器的各種命令信息,但是命令信息的發送時間上是不具有規律性的,即間隔時間不定。為了充分的利用CPU,減少數據丟失的風險,我們利用UART的DMA模式來完成數據的接收。軟件部分主要是針對具體的應用,對DMA控制器以及UART作適當的初始化。UART的初始化比較簡單,主要是通訊數據格式、波特率等的設置,這些與其他控制器相同,只要設置相關的寄存器即可。注意UART設置成不使用自動流控制,不使用紅外線傳輸模式,關鍵要注意UART0設置成DMA模式而不是中斷模式,并且要使能FIFO緩沖區(根據需要,使用16字節的接收緩沖區),這樣在接收緩沖區滿時,會產生DMA請求而不是中斷請求。限于篇幅,具體的寄存器定義以及串行口的初始化不做詳悉介紹,可以參考文獻[1][2]。
DMA控制器的初始化也比較簡單,主要是相關寄存器的設置。與BDMA0相關的在本系統中用到的寄存器以及相關定義見表1,具體寄存器的名稱定義以及物理地址見參考文獻[1][2]。
表1 S3c44b0x的BDMA相關寄存器的定義
在初始化時要正確設置目標(緩沖區的)首地址、數據傳輸的方向、源寄存器的首地址、地址指針是否遞增以及遞增方向、DMA計數器等等。相關代碼以及注釋如下:
#define RAM_ADDRESS 0xc200000 //定義接收數據的緩沖區,根據硬件而定。在我們的系統中擴展的SDRAM 存儲空間從0x0C00000~0x0C7fffff,占用S3c44b0x的bank 6。
#define size 16 //定義DMA的計數器,根據需要設定,可以選擇的選項是4、8、2和16
char *Buf;
Buf=(unsigned char*) RAM_ADDRESS; //指針指向起始地址
BDISRC0=(11<<28)+(int)(rURxH0); /*以字節為單位傳送;因為DMA操作時是將UART的寄存器中的數據讀出放置到設定的緩沖區,所以源寄存器的地址應該是固定到;UART的接收保存寄存器rURxH0,同時位[29:28]應該設置成 0b11。*/
BDIDES0=(10<<30)+(01<<28)+ Buf); /*傳輸方向模式設定為從內部設備(UART口)到外部存儲器(SDRAM),目標存儲器(SDRAM)使用地址遞增的方向,將數據順次放置到緩沖區中*/
BDICNT0=(10<<30)+(1<<26)+(3<<22)+(1<<21)+(0& lt;<20)+size;/*設置UART0使用BDMA0通道,在DMA計數到0時自動重載和自動啟動,計數結束產生中斷,每次DMA操作移動 16字節數據到設定地緩沖區*/
BDICNT0 |= (1<<20);//使能DMA
BDCON0 = 0x0<<2;//允許外部DMA請求
數據接收:這一部分工作由初始化好后的DMA控制器依靠硬件來完成。接收數據不定時,初始化UART0的接收緩沖區為16字節,當接收緩沖區滿時,會產生DMA請求,然后在DMA控制器的控制下,將UART的接收FIFO中的16字節的數據轉移到指定的緩沖區中(SRAM),當數據轉移完畢(DMA 計數到0)后,要做兩件事情:一是自動重載和自動啟動,即自動重新設置好目標(緩沖區)首地址和源地址(UART接收寄存器)以及DMA計數器,準備好下次DMA請求;另外產生DMA中斷。DMA中斷服務程序要做的工作很簡單,只要對全局標志RECEIVE_FLAG置位,通知主程序有新的命令需要處理。這樣主程序可以直接處理RAM中的數據,而不需要花費時間去讀取UART的接收緩沖區。
數據處理:當主程序通過查詢全局標志RECEIVE_FLAG,如果為1,則知道有新的命令,可以直接讀取命令緩沖區,同時對RECEIVE_FLAG清零。然后按照一定的算法對接收的數據做出解析,這部分內容不做重點討論。
5、試驗及結論
為了驗證基于DMA的通訊的有效性,筆者做了對比試驗。把負責軌跡插補的定時中斷優先級設計成最高(中斷時間間隔50毫秒,中斷服務程序執行時間約需要30毫秒),然后一個機器人采用中斷方式接收上位機連續發送的100組命令,另一個采用基于DMA的方式接收上位機連續發送的100組命令。然后在機器人主程序中通過讀取UART的狀態寄存器判斷出現錯誤(主要是數據溢出錯誤,即緩沖區有接收數據而沒有及時讀取,被新的數據覆蓋)的次數。軟件采用C語言,用ADS1.2編譯調試。試驗結果如表2。實驗證明了第二種方式的有效性。
表2:對比試驗結果
本文作者的創新點在于:在UART通訊中,通過采取DMA方式,直接將UART接收的數據轉移到設定好的RAM區,然后設置相應的全局標志,通知主程序數據可用就可以了。開發人員不需要到UART的緩沖區中讀取數據,直接讀RAM就可以了。與采用中斷方式或者查詢方式的串行口通訊方式相比較,不僅僅可以節省CPU通訊時用于接收數據的時間,同時可以防止UART接收的數據由于沒有及時被讀取而丟失,提高了通訊的可靠性。
參考文獻:
(1)嵌入式系統開發與應用,田澤編著,北京航空航天大學出版社,2005年5月第一版;
(2)S3C44B0X RISC MICROPROCESSOR ,SAMSUNG ElECTRONICS
(3)ARM微控制器基礎與實戰,周立功等編著,北京航空航天大學出版社,2003年11月第1版.
(4) 魏永清 萬寶年,具有軟件模擬FIFO緩沖區的串口通信模塊設計,微計算機信息 2006年第7-2期:64-66