发新帖我要提问
12
返回列表
打印
[MCU]

官方例程Example_2833xAdcToDMA的分析

[复制链接]
楼主: tfqi
手机看帖
扫描二维码
随时随地手机跟帖
21
tfqi|  楼主 | 2019-8-5 14:55 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
// INT7.1
__interrupt void local_DINTCH1_ISR(void)     // DMA Channel 1
{
    // To receive more interrupts from this PIE group, acknowledge this interrupt
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;

    // Next two lines for debug only to halt the processor here
    // Remove after inserting ISR Code
    __asm ("      ESTOP0");
    for(;;);
}

使用特权

评论回复
22
tfqi|  楼主 | 2019-8-5 14:56 | 只看该作者
现象
我们现在来作如下改动,其他地方不变:

    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
    }

使用特权

评论回复
23
tfqi|  楼主 | 2019-8-5 14:56 | 只看该作者

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

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


使用特权

评论回复
24
tfqi|  楼主 | 2019-8-5 14:56 | 只看该作者
DMACH1BurstConfig
因为只进行了一次ADC转换,所以也就只触发传输了一帧,共4个WORD的数据。所以由

DMACH1BurstConfig(3,1,1);          //burst传输
这个函数我们知道,1帧传输数据是这样的:

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

使用特权

评论回复
25
tfqi|  楼主 | 2019-8-5 14:58 | 只看该作者
DMACH1TransferConfig
DMACH1TransferConfig(9,1,0);        //transfer传输
只传输了1帧,没有达到第一个参数指定的10帧,所以不会触发中断。第二个参数1,第三个参数0,所以,现在源数据的指针指向的是ADCRESULT4,目的指针指向的还是上一帧后的DMABuf1[3]。

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

使用特权

评论回复
26
tfqi|  楼主 | 2019-8-5 14:58 | 只看该作者

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

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

没错,进入了中断。

使用特权

评论回复
27
tfqi|  楼主 | 2019-8-5 14:58 | 只看该作者
我们改到传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(;;){}
//...


使用特权

评论回复
28
tfqi|  楼主 | 2019-8-5 14:59 | 只看该作者

看结果

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


使用特权

评论回复
29
tfqi|  楼主 | 2019-8-5 14:59 | 只看该作者
DMACH1WrapConfig
我们继续,仅改成如下

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

使用特权

评论回复
30
tfqi|  楼主 | 2019-8-5 15:00 | 只看该作者
再看看结果:



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

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


使用特权

评论回复
31
tfqi|  楼主 | 2019-8-5 15:00 | 只看该作者
还有一点要说的是 ,

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


使用特权

评论回复
32
tfqi|  楼主 | 2019-8-5 15:01 | 只看该作者

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

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


使用特权

评论回复
33
tfqi|  楼主 | 2019-8-5 15:01 | 只看该作者
番外篇
前篇的分析中还有一点没有交代:

    //...
    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传输
    //...

使用特权

评论回复
34
tfqi|  楼主 | 2019-8-5 15:01 | 只看该作者
为什么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也行,那是必然的,至于例程为什么这么做,估计是在尽量短的例程里展现最全的用法。

使用特权

评论回复
35
tfqi|  楼主 | 2019-8-5 15:02 | 只看该作者

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


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


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则