DSP28335入门教程:ADC to DMA 后篇

好,接着ADC to DMA 前篇我们继续,后篇主要是举例子加以理解这三个函数:

    DMACH1BurstConfig(3,1,10);          //burst传输
    DMACH1TransferConfig(9,1,0);        //transfer传输
    DMACH1WrapConfig(1,0,0,1);          //wrap传输

还是上一个程序:

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

#define ADC_CKPS   0x1   // ADC module clock = HSPCLK/2*ADC_CKPS   = 25.0MHz/(1*2) = 12.5MHz
#define ADC_SHCLK  0xf   // S/H width in ADC module periods                        = 16 ADC clocks
#define BUF_SIZE   40    // Sample buffer size

// Global variable for this example
Uint16 j=0;

#pragma DATA_SECTION(DMABuf1,"DMARAML4");
volatile Uint16 DMABuf1[BUF_SIZE];

volatile Uint16 *pDMADest;
volatile Uint16 *pDMASource;
__interrupt void local_DINTCH1_ISR(void);

void main(void)
{
    Uint16 i;

    // step 1. 时钟配置
    InitSysCtrl();                  //初始系统时钟
    EALLOW;                         //允许编辑受保护的寄存器
    SysCtrlRegs.HISPCP.all = 0x3;   //配置高速外设时钟 HSPCLK = SYSCLKOUT/6 = 25M
    EDIS;                           //禁止编辑,与EALLOW成对出现

    // Step 2. 初始化GPIO
    //本例不需要

    // Step 3. CUP和PIE中断配置
    DINT;                           //禁用CPU中断
    InitPieCtrl();                  //寄存器复位置零
    IER = 0x0000;                   //清除CPU中断标识
    IFR = 0x0000;

    InitPieVectTable();              //初始中断向量表
    EALLOW;
    PieVectTable.DINTCH1= &local_DINTCH1_ISR;
    EDIS;

    IER = M_INT7 ;                  //Enable INT7 (7.1 DMA Ch1)
    EnableInterrupts();             //使能PIE和CPU中断

    // Step 4. 初始化外设
    InitAdc();                      //使能ADC时钟和校准

    //配置ADC
    AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
    AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;
    AdcRegs.ADCTRL1.bit.SEQ_CASC = 0;       // 0 Non-Cascaded Mode
    AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 0x1;
    AdcRegs.ADCTRL2.bit.RST_SEQ1 = 0x1;
    AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;  //选择管脚ADCINA0
    AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;  //ADCINA1
    AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x8;  //ADCINB0
    AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x9;  //ADCINB1
    AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x0;
    AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x1;
    AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x8;
    AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x9;
    AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 3;   // Set up ADC to perform 4 conversions for every SOC

    //Step 5. User specific code
    DMAInitialize();                  //DMA初始化
    for (i=0; i

现象

我们现在来作如下改动,其他地方不变:

    DMACH1BurstConfig(3,1,1);          //burst传输
    DMACH1TransferConfig(9,1,0);        //transfer传输
    DMACH1WrapConfig(100,0,100,1);          //wrap传输
    DMACH1ModeConfig(DMA_SEQ1INT,PERINT_ENABLE,ONESHOT_DISABLE,CONT_DISABLE,SYNC_DISABLE,SYNC_SRC,
                     OVRFLOW_DISABLE,SIXTEEN_BIT,CHINT_END,CHINT_ENABLE);
    StartDMACH1();
    AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 0x1; // 触发一次ADC转换
    for(;;){}                           // 在此停住
    for(i=0;i<10;i++)
    {
        for(j=0;j<1000;j++){}
        AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;    //Normally ADC will be tied to ePWM, or timed routine
    }  

现在来看看程序运行的结果:

DSP28335入门教程:ADC to DMA 后篇_第1张图片

DSP28335入门教程:ADC to DMA 后篇_第2张图片

我们可以看到,DMABuf1只有四个数据,分别存了四通道的转换值。并且暂停后程序停在了for循环处,表明没有进入中断。

DMACH1BurstConfig

因为只进行了一次ADC转换,所以也就只触发传输了一帧,共4个WORD的数据。所以由

DMACH1BurstConfig(3,1,1);          //burst传输

这个函数我们知道,1帧传输数据是这样的:

ADCRESULT0->DMABuf1[0],ADCRESULT1->DMABuf1[1],ADCRESULT2->DMABuf1[2],ADCRESULT3->DMABuf1[3]

DMACH1TransferConfig

DMACH1TransferConfig(9,1,0);        //transfer传输

只传输了1帧,没有达到第一个参数指定的10帧,所以不会触发中断。第二个参数1,第三个参数0,所以,现在源数据的指针指向的是ADCRESULT4,目的指针指向的还是上一帧后的DMABuf1[3]。

因为只传了一帧,所以第二个参数在这里起不到任何作用。

我们把9改成0再运行看看:

DMACH1TransferConfig(0,1,0);        //transfer传输

DSP28335入门教程:ADC to DMA 后篇_第3张图片

没错,进入了中断。

我们改到传2帧,DMACH1TransferConfig(1,-3,1);

DMACH1TransferConfig(1,-3,1);        //transfer传输
//...
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 0x1; // 触发一次ADC转换
for(j=0;j<1000;j++){}               //延迟
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 0x1; // 再触发一次ADC转换
for(;;){}
//...

看结果

DSP28335入门教程:ADC to DMA 后篇_第4张图片

-3的偏移导致源指针从ADCRESULT3回到了ADCRESULT0。而目的地址指针从DMABuf1[3]偏移+1移到了DMABuf1[4],第二帧的目的地址就从DMABuf1[4]开始了。还发现两帧之后也进入了DMA中断。

DMACH1WrapConfig

我们继续,仅改成如下

    DMACH1BurstConfig(3,1,1);          //没变
    DMACH1TransferConfig(100,0,0);     //不起作用
    DMACH1WrapConfig(0,0,0,4);         //实现循环

再看看结果:

DSP28335入门教程:ADC to DMA 后篇_第5张图片

没错,效果和和上面的DMACH1TransferConfig(1,-3,1);完全一样!

每1帧后,源数据指针等于&ADCRESULT0往后累加0,所以每帧后都回到ADCRESULT0。每1帧后,目的地址指针等于&DMABuf1[0]往后累加4。(即第一帧后指向DMABuf1[4],第二帧后指向DMABuf1[8],第三帧后指向DMABuf1[12]……以此类推)

还有一点要说的是 ,

DMACH1TransferConfig(9,0,0);        //transfer传输
DMACH1WrapConfig(0,0,0,4);          //wrap传输

这两个函数都会导致地址偏移,但是不会同时发生,可以在DMACH1TransferConfig函数原型中看到TRANSFER_STEP is ignored when WRAP occurs,就是说,不管是源地址和目的地址,如果发生了DMACH1WrapConfig回绕,那么DMACH1TransferConfig的第二和第三个参数就被忽略掉。

如果不想要DMACH1WrapConfig进行循环呢,我要怎么关闭这个功能?这个功能没有所谓的disable,把wrapsize位字段设置为大于transfersize位字段就行。官方手册解释如下:

DSP28335入门教程:ADC to DMA 后篇_第6张图片

好了,例子就举这么多,不知道各位明白没有,原谅老笨的文采太差。

 

番外篇

前篇的分析中还有一点没有交代:

    //...
    AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;  //选择管脚ADCINA0
    AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;  //ADCINA1
    AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x8;  //ADCINB0
    AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x9;  //ADCINB1
    AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x0;
    AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x1;
    AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x8;
    AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x9;
    AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 3;   // Set up ADC to perform 4 conversions for every SOC
    //...
    DMACH1WrapConfig(1,0,0,1);          //wrap传输
    //...

为什么CONV00-CONV07都设置了通道,最后却只开了4个转换(conversion)?

不知道你发现没有,CONV04-CONV07的通道设置和CONV00-CONV03是重复的,依次是通道0x0,0x1,0x2,0x8,0x9。

实际上只是转换了通道0x0,0x1,0x2,0x8,0x9,因为通道一样,所以CONV04-CONV07和CONV00-CONV03一样,都是

通道0x0,0x1,0x2,0x8,0x9的转换结果。

DMACH1WrapConfig(1,0,0,1)第一个参数表示2帧后回绕源地址,所以源地址在ADCRESULT0-ADCRESULT7循环,结果也是正确的。

到这里有人就会想到的了,那我设置成DMACH1WrapConfig(0,0,0,1),让源地址在ADCRESULT0-ADCRESULT3循环不是也行?没错,

第一个参数改成0也行,那是必然的,至于例程为什么这么做,估计是在尽量短的例程里展现最全的用法。

以下是改成DMACH1WrapConfig(0,0,0,1)的结果:

DSP28335入门教程:ADC to DMA 后篇_第7张图片

DSP28335入门教程:ADC to DMA 后篇_第8张图片

 

好了,ADC to DMA篇的教程就到结束了。

 

 

 

 

你可能感兴趣的:(DSP28335)