新聞中心

        第7課:DMA

        作者: 時間:2016-11-11 來源:網絡 收藏
        A用來連接外部設備和內部設備之間的數據傳輸。有了它就可以繞開CPU,直接進行數據傳輸。但同時A的傳輸也會用到數據總線。所以它的使用也是有利有弊的。

        A利用了有限狀態機來分析。它分成3個狀態。

        本文引用地址:http://www.104case.com/article/201611/316800.htm

        狀態1等待REQ,一切狀態為0

        狀態2這個狀態已經接受到了REQ,這個時候把CNT中的值導入到DMA中的CURR—TC中,然后ACK就變成了1

        狀態3這個時候分為2個有限狀態機,子機用來作數據傳輸,從源地址取數據,再寫到目標地址。而主機負責計數,以及計數到0的中斷等。。。

        其實 有限狀態機FSM這種分析方法簡單來說就是把過程的變化無視掉,轉而只看狀態穩定后的結果。

        以下來介紹在傳輸中的3種基本分類。

        第一類 是 單元式 和 突發式 unit and brust

        unit 發送1個Byte,而brust發送4個。

        第2類 服務類 單一服務 和 連續服務 single and whole

        單一服務本質上來講就是做一個原子操作 必須再從狀態1到狀態3再走一遍,也就是說 需要等待REQ的這比有請求。而連續服務則在CURR_TC中的計數到0才停止。但是需要注意的一點:雖然是連續的,但是它也要短暫的釋放數據總線,來給“饑渴”的CPU控制。

        第3類 請求式和握手式 demand and shake

        請求式就是當ACK結束整個一次傳輸后,恢復到0,發現REQ仍然是1的話,繼續進行傳輸。

        而shake mode 指的是 ,ACK完成一次傳輸后,一定要等到REQ 變成0,來確認才能繼續進行。不然會一直等待。

        請求式單服務,握手式單服務,握手式全服務,請求式全服務。一般如果是外設對外設的話,推薦使用請求全服務。

        而從速度上來講,連續服務的確比單服務快一點。

        簡單說下需要設置的寄存器。

        因為我們有4組DMA,每組要設置的寄存器是9個,所以總共算術36個。

        在9個中,前4個設置源地址,源地址的控制,目標地址,目標地址的控制等選項。

        第5個是DMA控制寄存器,它要可以設置DMA的模式等具體的內容。

        第6,7個是看源地址和目標地址在現在的數值。

        而第8個是看CT內部計數器中,遞減到了幾。

        第9個是控制DMA啟動和停止的寄存器。例如在單一模式下,傳完一次 on/off位會自動置0,需要再次置1才能再次傳輸

        以下來進行舉例:

        寫一個程序 利用分別利用DMA傳輸1M數據,另外一個正常拷貝,利用定時器PWM來計時 并輸出到UART串口中。基本上除了中斷,前2次用到的設備這次都利用到了。

        #include"s3c2440.h"
        #define UART_CLK 50000000
        #define UART_BAUD_RATE 115200
        #define UART_BRD (int)(UART_CLK/(UART_BAUD_RATE *16))-1

        int n=0; //定義外部變量

        void init_uart()
        {
        rGPHCON |=0xa0;
        rGPHUP = 0x0c;
        rULCON0 = 0x3;
        rUCON0 = 0x5;
        rUFCON0 = 0;
        rUMCON0 = 0;
        rUBRDIV0 = UART_BRD;
        }

        void init_timer0() //初始化pwm,0.5秒計65535次數
        {
        rTCFG0 = 0x63;
        rTCFG1 = 0x1;
        rTCNTB0 = 0xFFFF;
        rTCON = 0xa;
        rTCON = 0x9;
        }

        void init_irq()
        {
        rINTMOD = 0;
        rINTMSK = ~(1<<10);//計時到0進入ISR,其中進行計數的累加,和小燈亮暗處理,小燈亮暗 為了說明進入了中斷
        }

        void uart_write(char *data)
        {
        while (*data !=

        主站蜘蛛池模板: 涪陵区| 乌拉特中旗| 屯昌县| 比如县| 剑河县| 建阳市| 宜兰市| 沂水县| 晋宁县| 探索| 绥芬河市| 山西省| 资中县| 旬阳县| 富川| 苗栗市| 大方县| 沧州市| 察哈| 临沧市| 齐河县| 新巴尔虎左旗| 晋中市| 德惠市| 那曲县| 天长市| 石家庄市| 比如县| 和林格尔县| 呼图壁县| 韶关市| 明星| 东台市| 阳江市| 吉木萨尔县| 湖南省| 平遥县| 隆安县| 波密县| 峨眉山市| 晋州市|