1.硬件原理
計算機系統(tǒng)中各種常用的數據輸入/輸出方法有查詢方式(包括無條件及條件傳送方式)和中斷方式,這些方式適用于CPU與慢速及中速外設之間的數據交換。但當高速外設要與系統(tǒng)內存或者要在系統(tǒng)內存的不同區(qū)域之間進行大量數據的快速傳送時,就在一定程度上限制了數據傳送的速率。直接存儲器存取(DMA)就是為解決這個問題提出的,采用DMA方式,在一定時間段內,由DMA控制器取代CPU,獲得總線控制權,來實現內存與外設或者內存的不同區(qū)域之間大量數據的快速傳送。
SC2440支持位于系統(tǒng)總線與外圍總線之間的四通道DMA控制。每一通道的DMA都可以處理一下四種情況:
1.源和目的器件均可以在系統(tǒng)總線
2.源器件在系統(tǒng)總線而目的器件在外圍總線
3.源器件在外圍總線而目的器件在系統(tǒng)總線
4.源和目的器件均可以在外圍總線
DMA最大的有點就是可以在沒有CPU干涉的情況下進行數據的傳送。可以通過軟件控制DMA啟動,或者通過內部請求或者外部請求引腳啟動。
2.芯片手冊
3.mini2440電路圖
4.S3C2440寄存器
DISRCx源初始化寄存器,存儲發(fā)送源的地址。
DISRCCx源初始化控制寄存器,[0]控制地址增長模式,[1]用于配置源是在AHB總線還是在APB總線。
DIDSTx目標初始化寄存器,存儲接收目標的地址。
DIDSTCx目標初始化控制寄存器,[0]控制地址增長模式,[1]用于配置源是在AHB總線還是在APB總線,[2]選擇中斷觸發(fā)的時間。
DCONxDMA控制寄存器,
DSTATx狀態(tài)寄存器,只讀。
DCSRCxDMA現在的源地址,只讀。
DCDSTxDMA現在的目標地址,只讀。
DMASKTRIGxDMA屏蔽觸發(fā)寄存器,開啟DMA開關。
dma-uart.c
#include"def.h"
#include"mmu.h"
#include"2440addr.h"
#defineGLOBAL_CLK//相當于定義了FCLK,HCLK,PCLK,UCLK
#definePCLK150000000
#defineUART_CLKPCLK1
#defineUART_BAUD_RATE115200
#defineUART_BRD((int)(UART_CLK/(UART_BAUD_RATE*16)+0.5)-1)
#defineTXD0READY(1<<2)
#defineRXD0READY(1)
#defineSEND_DATA(*(volatileunsignedchar*)0x30200000)
#defineSEND_ADDR(volatileunsignedchar*)0x30200000//發(fā)送源地址
voidDMA_Init(void)
{
rUCON0=rUCON0&0xff3|0xa;//UART0dma收發(fā)
/******DMA0Initialize*****/
rDISRC0=(U32)(SEND_ADDR);
rDISRCC0=(0<<1)|(0<<0);//Src=AHB,Increment
rDIDST0=(U32)UTXH0;//TxFIFOaddress
rDIDSTC0=(1<<1)|(1<<0);//Dst=APB,Fixed;
rDCON0=(0<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(1<<24)|(1<<23)|(1<<22)|(0<<20)|(50);
//handshake,Sync=APB,IntEn,unit,single,dst=UART0,HwReqMode,NoAutoReload,Halfword,
rDMASKTRIG0=(1<<1);//DMA0En
}
voidUart0_Init(void)
{
rGPHCON&=~(0xf<<4)|(0xa<<4);//GPH2,GPH3用作TXD0,RXD0
rGPHUP=0x0c;//GPH2,GPH3內部上拉
rULCON0=0x03;//數據格式:數據位為8位
//rUCON0=0x245;//允許查詢或中斷方式,不使用DMA通道,并設置接收超時
rUFCON0=0x00;//不使用FIFO
rUMCON0=0x00;//不使用流控
rUBRDIV0=UART_BRD;//設置波特率為115200kb/s
}
voidMain(void)
{
volatileunsignedchar*p=SEND_ADDR;
inti;
SEND_DATA=0x41;
for(i=0;i<128;i++)
*p++=0x41+i;
MMU_Init();
Uart0_Init();
DMA_Init();
while(1);
}