我打算使用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;
目标地址和源地址完全一致,为何???
Ken Wang:
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, };
谢谢
XiaoFeng Jiang:
回复 Ken Wang:
我的问题没有描述清楚,我使用的一组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;
Ken Wang:
回复 XiaoFeng Jiang:
xiaofeng,
确实我提供的例程是基于一个ADC的通道的转换寄存器来配置的,所以地址模式设为了ADDR_FIXED的参数。如果像你描述的采用的是6个通道的数据,确实要采用offset的配置。
同时谢谢你的尝试和实例分享。
谢谢
XiaoFeng Jiang:
回复 Ken Wang:
你好 还有个问题能否帮我看一下
我给6个通道的ADC1的group1分配了24word的转换结果的RAM空间,我采用连续采样时,采样结果依次存储到这个RAM中,共4组结果,进行循环覆盖;
但是我采用单次采样时,这个空间只存储一次采样结果并循环覆盖,也就是不使用剩余的18个word;
我想和连续采样一样存储4组结果,循环覆盖,需要哪些设置。
Ken Wang:
回复 XiaoFeng Jiang:
Xiaofeng,
按照你所说的,我们的ADC如果是但是采样的话,采样的结果是需要在采样结束后读出来的,不然会被覆盖掉。这个和连续采样的工作方式不一样的。
我们可以这样分析,因为单次采样的话,它在采样结束后就可以出发中断,然后读取数据,这样就不会造成数据的覆盖;而对于多通道连续采样的话,这个过程是没有一个结束标志位出发中断的,只有当你采样的数据个数大于你设定的group fifi的大小个数才会出发中断,所以这个时候才可以去获得数据。
谢谢
XiaoFeng Jiang:
回复 Ken Wang:
你好,我又遇到一个问题,我采用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之间运行多少时间的方法啊???
Ken Wang:
回复 XiaoFeng Jiang:
Xiaofeng,
你提到的门限指的是哪一个参数?
多个ADC转换结果的DMA传输的例程,我们官方暂时还没有的,有空的话,我可以试着做一个。
另外关于CCS测断点之间运行时间的方法,我印象应该是有的,以前在做C2000的时候有用到过。你可以google或百度一下看看。
谢谢
TI中文支持网

