寄存器说明
下面主要说一下DMA需要配置的一些寄存器。
地址寄存器
DmaRegs.CHx.SRC_BEG_ADDR_SHADOW
DmaRegs.CHx.SRC_ADDR_SHADOW
DmaRegs.CHx.DST_BEG_ADDR_SHADOW
DmaRegs.CHx.DST_ADDR_SHADOW
( x = 1~6 )
以上四个寄存器分别为源地址及目标地址寄存器及其影子寄存器,每次DMA传输开始时,影子寄存器中的值装载入对应的地址寄存器。
burst 寄存器
DmaRegs.CHx.BURST_SIZ.all
DmaRegs.CHx.SRC_BURST_STEP
DmaRegs.CHx.DST_BURST_STEP
( x = 1~6 )
DmaRegs.CHx.BURST_SIZ.all值为0~31
单个burst传输的words个数为( DmaRegs.CHx.BURST_SIZ.all + 1 ) ,此处的word 长度固定为16bits,无论DMA总线宽度选16或是32。
若DMA总线宽度为32,则单个burst传输的words个数只能为偶数,即,若DmaRegs.CHx.BURST_SIZ.all + 1为奇数,则实际单个burst传输的words个数为DmaRegs.CHx.BURST_SIZ.all + 2。
SRC_BURST_STEP及DST_BURST_STEP为每个word传输完成后源地址及目标地址增加量。
若DMA总线宽度为32,且配置SRC_BURST_STEP及DST_BURST_STEP为2,则可实现burst中每个word间地址的连续增加。
若DMA总线宽度为16,且配置SRC_BURST_STEP及DST_BURST_STEP为1,此时可实现burst中每个word间地址的连续增加。
transfer 寄存器
DmaRegs.CHx.TRANSFER_SIZE
DmaRegs.CHx.SRC_TRANSFER_STEP
DmaRegs.CHx.DST_TRANSFER_STEP
( x = 1~6 )
DmaRegs.CHx.TRANSFER_SIZE值为0~65535
单次传输的burst个数为( DmaRegs.CHx.TRANSFER_SIZE + 1 )
SRC_TRANSFER_STEP及DST_TRANSFER_STEP为每个burst传输完成后源地址及目标地址增加量,这两个寄存器在使用WRAP模式时被忽略。
若DMA总线宽度为32,且配置SRC_TRANSFER_STEP及DST_TRANSFER_STEP为2,则可实现每个burst间地址的连续增加。
若DMA总线宽度为16,且配置SRC_TRANSFER_STEP及DST_TRANSFER_STEP为1,则可实现每个burst间地址的连续增加。
MODE 寄存器
DmaRegs.CHx.MODE
(x = 1~6)
寄存器定义在reference guide中给出,不再赘述。
说一下ONESHOT,如果该位置1,一次触发将完成一次传输中所有burst,若置0,则每次触发只能完成一个burst的传输。
例程实验
通过Xintf zone6 外扩SRAM。对外部SRAM进行初始化,在其中定义了一个长度为1024,首地址为0x18FC00的无符号整型数组,并利用DMA将其值传输至内部SRAM中首地址为0x00C000的数组。
下面是C程序代码,该程序需要使用TI官方的DMA库函数。
// Includes /
#include "DSP28x_Project.h"
#define BUF_SIZE 1024 // Sample buffer size
#pragma DATA_SECTION(DMABuf1,"DMARAML4");
#pragma DATA_SECTION(DMABuf2,"ZONE6DATA");
volatile Uint16 DMABuf1[BUF_SIZE];
volatile Uint16 DMABuf2[BUF_SIZE];
volatile Uint16 *DMADest;
volatile Uint16 *DMASource;
interrupt void local_DINTCH1_ISR(void);
void init_zone6(void);
void main( void )
{
Uint16 i;
// System Initialization
InitSysCtrl();
// Configure PLL
// Configure Interrupt(s)
// 1. Disable global interrupt
DINT;
// 2. Initialize PIE
InitPieCtrl();
// 3. Disable ALL interrupts and clear ALL interrupts pending flags in CPU level
IER = 0x0000;
IFR = 0x0000;
// 4. Initialize PIE Vector Table
InitPieVectTable();
// 5. Initialize user data
// 6. Configure interrupt handler(s) (PieVectTable, EALLOW protected)
EALLOW;
PieVectTable.DINTCH1= &local_DINTCH1_ISR;
EDIS;
// 7. Enable used interrupt in PIE (PieCtrlRegs.PIEIER)
// 8. Enable used interrupt in CPU (IER)
IER = M_INT7 ;
// 9. Initialize peripheral(s) (including peripheral-level configuration)
init_zone6();
CpuTimer0Regs.TCR.bit.TSS = 1; //Stop Timer0 for now
// Initialize DMA
DMAInitialize();
// Initialize buffer data in Xintf sram
for (i=0; i<BUF_SIZE; i++)
{
DMABuf1[i]