程序實現(xiàn):
DMA的使用主要是DMA寄存器的初始設置,設置完成后,DMA接到觸發(fā)信號即可自動傳輸數(shù)據(jù)。
設置函數(shù)如下:
void DMAInit(char channel,char trigger,char transMode,char srcMode,char dstMode,
unsigned int src,unsigned int dst,unsigned int size)
{
unsigned int *DMAxCTL,*DMAxSA,*DMAxDA,*DMAxSZ;
DMACTL0 = trigger 《《 (channel 《《 2);
DMACTL1 = 0x04; //DMA收到觸發(fā)請求時,等待當前指令執(zhí)行完成后
switch (channel) //選擇當前設置哪個DMA通道
{
case 0:
DMAxCTL = (unsigned int *)&DMA0CTL;
DMAxSA = (unsigned int *)&DMA0SA;
DMAxDA = (unsigned int *)&DMA0DA;
DMAxSZ = (unsigned int *)&DMA0SZ;
break; //指針 = 0通道控制
case 1:
DMAxCTL = (unsigned int *)&DMA1CTL;
DMAxSA = (unsigned int *)&DMA1SA;
DMAxDA = (unsigned int *)&DMA1DA;
DMAxSZ = (unsigned int *)&DMA1SZ;
break; //指針 = 1通道控制
case 2:
DMAxCTL = (unsigned int *)&DMA2CTL;
DMAxSA = (unsigned int *)&DMA2SA;
DMAxDA = (unsigned int *)&DMA2DA;
DMAxSZ = (unsigned int *)&DMA2SZ;
break; //指針 = 2通道控制
}
switch (transMode) //設置DMA通道的傳輸模式
{
case ‘S’: *DMAxCTL = DMADT_0; break; //單次傳輸
case ‘s’: *DMAxCTL = DMADT_4; break; //重復單次傳輸
case ‘B’: *DMAxCTL = DMADT_1; break; //塊傳輸
case ‘b’: *DMAxCTL = DMADT_5; break; //重復塊傳輸
case ‘I’: *DMAxCTL = DMADT_2; break; //突發(fā)塊傳輸 交錯
case ‘i’: *DMAxCTL = DMADT_6; break; //重復突發(fā)塊傳輸 交錯
}
*DMAxCTL |= (srcMode & 0x04) 《《 2; //源 字或字節(jié)
*DMAxCTL |= (srcMode & 0x03) 《《 8; //源 地址改變方式
*DMAxCTL |= (dstMode & 0x04) 《《 3; //目的 字或字節(jié)
*DMAxCTL |= (dstMode & 0x03) 《《 10; //目的 地址改變方式
*DMAxSA = src;
*DMAxDA = dst;
*DMAxSZ = size;
*DMAxCTL |= DMAEN; //DMA使能
}
函數(shù)比較麻煩,函數(shù)內(nèi)容按參數(shù)設置每個寄存器。DMACTL0 = trigger 《《 (channel 《《 2); 這個是設置對應channel通道的的參考源,不大明白的可以看下DMACTL0的寄存器內(nèi)容;switch (channel)語句則根據(jù)通道設置對應指針指向的寄存器;然后對應設置參數(shù)即可。
當設置成非重復模式時,需要重新置位DMAEN,本程序就函數(shù)DMAReEnable實現(xiàn):
void DMAReEnable(char channel)
{
switch (channel) //使能對應通道
{
case 0: DMA0CTL |= DMAEN; break; //0通道
case 1: DMA1CTL |= DMAEN; break; //1通道
case 2: DMA2CTL |= DMAEN; break; //2通道
}
}
這個函數(shù)比較簡單,只是根據(jù)傳入?yún)?shù)設置對應通道的DMAEN位。
當設置為軟件觸發(fā)時,需要軟件啟動DMA程序如下:
void DMAStart(char channel)
{
switch (channel) //使能對應通道
{
case 0: DMA0CTL |= DMAREQ; break; //0通道
case 1: DMA1CTL |= DMAREQ; break; //1通道
case 2: DMA2CTL |= DMAREQ; break; //2通道
}
}
這個和上個函數(shù)類似:僅僅設置一個控制位,函數(shù)很簡單,不再解釋啦。
程序實現(xiàn)就這么多了,有關詳細內(nèi)容可以下載附件里的程序庫,程序的注釋很詳細。
使用示例:
使用這個程序時,步驟和原來的相同:工程中加入DMA.c文件,然后源文件中包含DMA.h頭文件即可。
示例程序主要如下:
#include 《msp430x16x.h》
#include “DMA.h”
unsigned int a[5] = {8693,5689,2356,23565,5656};
unsigned int b[5];
void main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
ClkInit();
//塊傳輸,5個字(16位) a-》b
DMAInit(0,0x00,‘B’,3,3,(unsigned int)a,(unsigned int)b,5);
DMAStart(0);
//如果需要再次傳輸 而不改變設置,只需調(diào)用DMAReEnable再次啟動傳輸即可
// 如果是重復塊傳輸,則不需要重新使能DMAReEnable 直接啟動即可
//這里僅僅演示了使用方法,實際應用中,應根據(jù)需要選擇適當?shù)挠|發(fā)源。
//
LPM0;
}
示例程序完成功能很簡單,僅僅把一個數(shù)組的值賦給另外一個數(shù)組。數(shù)組地址即是數(shù)組名強制轉換為所需類型(無符號16位),傳入函數(shù)初始化設置。這里為了簡便,設置為軟件啟動。
運行效果如下:
單步運行完啟動DMA傳輸后,結果即出來了;說明DMA傳輸數(shù)據(jù)的速度是很快的。
DMA可以用于對速度要求比較高的程序中。例如:DMA配合硬件乘法器和ADC12模塊,可以很容易的實現(xiàn)比較高頻率的數(shù)字濾波方案。
評論
查看更多