GZZXB 发表于 2019-5-21 17:13

这里有官方技术吗?看下这个demo问题出在哪里?


ADC扫描3个通道,采用DMA搬运到buff。代码设置如下

为什么只有前面3个单元数据才正确,后面的不搬运了?该怎么改动才能实现将
扫描到的3个通道,顺序一直往buff里填充?
代码是在官方SDK上简单修改而来。

aoyi 发表于 2019-5-22 12:54

你的硬件是怎么连接的呢

drer 发表于 2019-5-22 12:59

初始化代码贴上来瞅瞅

gwsan 发表于 2019-5-22 13:00

楼主本想在哪个通道读出来数据呢

martinhu 发表于 2019-5-22 13:33

本帖最后由 martinhu 于 2019-5-22 18:28 编辑

看你一次扫描只采了3个通道,采样完成之后3个通道的采样数据搬运到buff里面?你用的burst硬件触发,当第一次ADC采样完成后,DMA触发,传送3*6,供18次,
因为ADC结果寄存器只有012有值,所以只看到前面3个数组有值。



根据你描述的需求,我觉得你应该使用DMAC的硬件块(Block)传输,这样每次ADC转换完成后,传输一个请求,DMA传输一次
你可以注意手册上Block和Burst的区别

还有ADC的扫描转换,并不是使能一次,就可以永不停止地扫描转换了。

具体到你这个应用,因为没有BC为0,源地址是不会重载的(在TC为0时候重载),

所以我使用了timer2来触发ADC转换,转换完成后触发一次DMA搬运,
并且使用timer中断计数

GZZXB 发表于 2019-5-22 17:52

//使能DMA触发
Adc_ConfigDmaTrig(DmaSqr);

stcDmaCfg.enMode =DmaBlock;//DmaBurst;                  
stcDmaCfg.u16BlockSize = 0x03u;
stcDmaCfg.u16TransferCnt = 6;         //burst模式,一次触发传输数据大小为 3*1,
stcDmaCfg.enTransferWidth = Dma32Bit;            
stcDmaCfg.enSrcAddrMode = AddressIncrease;
stcDmaCfg.enDstAddrMode = AddressIncrease;
stcDmaCfg.bDestAddrReloadCtl = FALSE;
stcDmaCfg.bSrcAddrReloadCtl = TRUE;//FALSE;
stcDmaCfg.bSrcBcTcReloadCtl = TRUE;//FALSE;
stcDmaCfg.u32SrcAddress = (uint32_t) &(M0P_ADC->SQRRESULT0);
stcDmaCfg.u32DstAddress = (uint32_t)&ADC_Result_Array;
stcDmaCfg.enRequestNum = ADCSQRTrig;                //设置为ADCSQR触发
Dma_InitChannel(DmaCh0,&stcDmaCfg);       

//使能DMA,使能DMA0,启动DMA0
Dma_Enable();
Dma_EnableChannel(DmaCh0);
//Dma_Start(DmaCh0);               
Adc_SQR_Start();

在中断 里
void AdcContIrqCallback(void)
{   
    Adc_GetSqrResult(&u16AdcRestult0, 0);
    Adc_GetSqrResult(&u16AdcRestult2, 1);
    Adc_GetSqrResult(&u16AdcRestult5, 2);

    stcAdcIrqFlag.bAdcSQRIrq = TRUE;
        Adc_SQR_Start();
}

源地址一直递增不能回到,初始化的ad地址
stcDmaCfg.u32SrcAddress = (uint32_t) &(M0P_ADC->SQRRESULT0);
该怎样设置才能实现传输完一个块后,SRC地址返回到初始化DMA的地址?

martinhu 发表于 2019-5-22 18:34

GZZXB 发表于 2019-5-22 17:52
//使能DMA触发
Adc_ConfigDmaTrig(DmaSqr);



目前好像只有TC为0的时候源地址才会重载,所以按照你的需求,一般BC设为3,TC设为1(库函数配置);
ADC的转换你使用软件,每次只能转换一次,或者用timer定时触发ADC转换;
但是这样设置好像不能直接等DMAC传输你需要的次数之后停止,得用别的方式计数停止,
你可以参考我刚才上传的代码,

GZZXB 发表于 2019-5-22 22:21

martinhu 发表于 2019-5-22 18:34
目前好像只有TC为0的时候源地址才会重载,所以按照你的需求,一般BC设为3,TC设为1(库函数配置);
ADC ...

                                       感谢你的回复{:handshake:}
是的所以我认为在不加入软件处理的前提下,一次DMA最多只能搬运16个数据. 也就是BC的最大值.
需要搬运更多的值只能软件介入.用STM32F030 启动一次AD转换是可以一直循环扫描转换的,DMA也是可以循环填充的.看来这个DMA是STM32的低配版吧.

martinhu 发表于 2019-5-23 09:50

GZZXB 发表于 2019-5-22 22:21
感谢你的回复
是的所以我认为在不加入软件处理 ...

对于ADC的连续扫描,如果想要一直不断地扫描,目前是通过循环的硬件触发ADC,比如timer触发,间隔时间可自由调整。
对于DMA搬运次数,以前有个帖子里面讨论过,对于对等大小的源和目的区域,搬运次数可以是65536*16,如果CONFB0.MSK位置1,对于对等的区块搬运,可以永远进行下去,比如从ADC.SqrResult0~ADC.SqrResult2搬运到AdcBuffer~AdcBuffer里面,可以在没有软件干预的情况下永远传输下去。
对于传输源和目的不等的情况,如果源只有一个数据,比如ADC.SqrResult0,那么源地址固定的话,Block为1,TC可以是从1~65536次做到对buffer的堆叠。
像你这样的,源有3个寄存器,目前好像是在目的地址不重载的情况下可以做到对buffer的堆叠,但是需要防止目的buffer的溢出。
页: [1]
查看完整版本: 这里有官方技术吗?看下这个demo问题出在哪里?