This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS570LS3137的ADC1的DMA传输问题



我打算使用DMA来传输ADC1G1的采样结果

使用如下设置

g_dmaCTRLPKT.SADD   =sadd;//ADC的结果地址
g_dmaCTRLPKT.DADD  =dadd;//RAM的目标地址
g_dmaCTRLPKT.CNCTRL  =0;
g_dmaCTRLPKT.FRCNT  =2;
g_dmaCTRLPKT.ELCNT  =24;
g_dmaCTRLPKT.ELDOFFSET  =0;
g_dmaCTRLPKT.ELSOFFSET  =1;
g_dmaCTRLPKT.FRDOFFSET  =0;
g_dmaCTRLPKT.FRSOFFSET  =0;
g_dmaCTRLPKT.PORTASGN  =4;
g_dmaCTRLPKT.RSSIZE  =ACCESS_32_BIT;
g_dmaCTRLPKT.WRSIZE  =ACCESS_32_BIT;
g_dmaCTRLPKT.TTYPE  =FRAME_TRANSFER;
g_dmaCTRLPKT.ADDMODERD  =ADDR_OFFSET;
g_dmaCTRLPKT.ADDMODEWR  =ADDR_INC1;
g_dmaCTRLPKT.AUTOINIT  =AUTOINIT_ON;

发现目标RAM中的数据是第1个32位正确为为源地址的第1个32位的数据,2、3、4个32位数据为第1个32位的相关的位移位的内容,

第5个32位为源地址的第2个32位的数据,依次类推。

我修改为

g_dmaCTRLPKT.ELCNT  =96;

g_dmaCTRLPKT.RSSIZE  =ACCESS_8_BIT;

 g_dmaCTRLPKT.WRSIZE  =ACCESS_8_BIT;

目标地址和源地址完全一致,为何???

  • Xiaofeng,

       你前面程序里面关于DMA的设置有些问题,你需要注意的是你设置的是两个frame和24个elements,而你的ELDOFFSET设置的又是0,这个会终端地址里面的数据的覆盖。我们的datasheet里面有关于你设置不同的frame和element对应的offset地址的计算公式,你可以仔细参考一下。

    如果你不想那么麻烦,你可以直接设置为1个frame,然后数据全是element,传输方式设置为frame transfer。读写的位数设为32位,因为我们ADC是10位或12位的,这样不会造成数据的不准确。同时ELDOFFSET设为4.参考的配置如下:

    g_dmaCTRL CFG_CH0 =
    {
    (uint32)(&(adcREG1->GxBUF[1])),
    (uint32)&adcData,
    0,
    1,
    D_SIZE,
    4,
    0,
    0,
    0,
    4,
    ACCESS_32_BIT,
    ACCESS_32_BIT,
    FRAME_TRANSFER,
    ADDR_FIXED,
    ADDR_INC1,
    AUTOINIT_ON,
    0,
    };

    谢谢

  • 我的问题没有描述清楚,我使用的一组6个通道的转换,采用直接使用ADC的RAM中6个通道的数据DMA到更大的RAM中

    你的示例中采用ADDR_FIXED是否每次只传输adcREG1->GxBUF[1]的32位数据啊

    所以我源地址必须采用ADDR_OFFSET的方式,根据你的提示我试了一下,

    应该是这样的,采用ADDR_OFFSET方式,element传输的偏移量是以字节为单位固定,而不是以ACCESS_32_BIT、ACCESS_16_BIT计算的,估计frame的偏移量也是如此的

    而如果采用ADDR_INC1方式,element、frame的偏移量的设置就不起作用了,固定的加1是以ACCESS_32_BIT、ACCESS_16_BIT确定的

    改为如下粗步查看,可以正常使用

    g_dmaCTRLPKT.SADD   =sadd;//ADC的结果地址
    g_dmaCTRLPKT.DADD  =dadd;//RAM的目标地址
    g_dmaCTRLPKT.CNCTRL  =0;
    g_dmaCTRLPKT.FRCNT  =2;
    g_dmaCTRLPKT.ELCNT  =24;
    g_dmaCTRLPKT.ELDOFFSET  =0;
    g_dmaCTRLPKT.ELSOFFSET  =4;  //修改处
    g_dmaCTRLPKT.FRDOFFSET  =0;
    g_dmaCTRLPKT.FRSOFFSET  =0;
    g_dmaCTRLPKT.PORTASGN  =4;
    g_dmaCTRLPKT.RSSIZE  =ACCESS_32_BIT;
    g_dmaCTRLPKT.WRSIZE  =ACCESS_32_BIT;
    g_dmaCTRLPKT.TTYPE  =FRAME_TRANSFER;
    g_dmaCTRLPKT.ADDMODERD  =ADDR_OFFSET;
    g_dmaCTRLPKT.ADDMODEWR  =ADDR_INC1;
    g_dmaCTRLPKT.AUTOINIT  =AUTOINIT_ON;

  • xiaofeng,

    确实我提供的例程是基于一个ADC的通道的转换寄存器来配置的,所以地址模式设为了ADDR_FIXED的参数。如果像你描述的采用的是6个通道的数据,确实要采用offset的配置。

    同时谢谢你的尝试和实例分享。

    谢谢

  • 你好 还有个问题能否帮我看一下

    我给6个通道的ADC1的group1分配了24word的转换结果的RAM空间,我采用连续采样时,采样结果依次存储到这个RAM中,共4组结果,进行循环覆盖;

    但是我采用单次采样时,这个空间只存储一次采样结果并循环覆盖,也就是不使用剩余的18个word;

    我想和连续采样一样存储4组结果,循环覆盖,需要哪些设置。

  • Xiaofeng,

      按照你所说的,我们的ADC如果是但是采样的话,采样的结果是需要在采样结束后读出来的,不然会被覆盖掉。这个和连续采样的工作方式不一样的。

    我们可以这样分析,因为单次采样的话,它在采样结束后就可以出发中断,然后读取数据,这样就不会造成数据的覆盖;而对于多通道连续采样的话,这个过程是没有一个结束标志位出发中断的,只有当你采样的数据个数大于你设定的group fifi的大小个数才会出发中断,所以这个时候才可以去获得数据。

    谢谢

  • 你好,我又遇到一个问题,我采用DMA传输ADC1的GROUP1的RAM的数据时,采用多个结果传输,门限为4,为开辟的group1的ram结果的大小;

    我发现DMA传输的周期减少了大约5倍,约为0.2ms,实际上group1的采样时间为10us,4组的话是40us;

    设置如下,adcREG1->G1DMACR=0x00000001U  //

                                                         |0x00000004U

                                                         |0x00040000U;

                    adcREG1->GxINTCR[1]=0x00000004U;

    我开放了frame中断,对单位时间内的frame中断次数进行了统计,得出DMA的传输的传输频率变慢了,将门限设为1中断次数并没有改变,不知道这个门限怎么设!!

    有没有多个结果的ADC的DMA传输的实例啊???

    采用adcREG1->G1DMACR=0x00000001U ;方式 即单次结果就进行DMA传输。

    需要将DMA的源地址改为BUF0;采用单word一次DMA传输,结果和被采样的实际信号(方波)比较是正确的,大约10us进行一次DMA,固定源地址BUF0读取6个通道/次的数据;这么做DMA请求会不会频率太高,要用到其他的DMA传输时会有影响啊。当然实际应用时我的采样周期可以适当调低一点。

    还有CCS能不能看两个breakpoint之间运行多少时间的方法啊???

  • Xiaofeng,

      你提到的门限指的是哪一个参数?

    多个ADC转换结果的DMA传输的例程,我们官方暂时还没有的,有空的话,我可以试着做一个。

    另外关于CCS测断点之间运行时间的方法,我印象应该是有的,以前在做C2000的时候有用到过。你可以google或百度一下看看。

    谢谢