注册 登录
查看: 248|回复: 1

如何设置DMA连续搬运ADC转换完成数据

[复制链接]
发表于 2017-8-29 13:47:35 | 显示全部楼层 |阅读模式
山外哥
        我想利用PIT周期性触发ADC采样,然后利用MDA搬运ADC完成的数据。目前发现:比如ADC转换完成3次,但是DMA只能搬运一次的数据。您觉得为什么呢?
我根据您的例程进行写的,代码DMA的初始化如下:
void DMA1ADC0Init(DMA_CHn CHn, void *SADDR, void *DADDR,  DMA_BYTEn byten,uint32 cfg)
{
    uint8 BYTEs = (byten == DMA_BYTE1 ? 1 : (byten == DMA_BYTE2 ? 2 : (byten == DMA_BYTE4 ? 4 : 16 ) ) ); //计算每次传输字节数

    SIM_SCGC7 |= SIM_SCGC7_DMA_MASK;                        //开启时钟 P313页 bit1表示DMA                 
    SIM_SCGC6 |= SIM_SCGC6_DMAMUX1_MASK;                    //DMAMUX1  时钟           

    /* 配置 DMA 通道 的 传输控制块 TCD */
    DMA_SADDR(CHn) =    (uint32)SADDR;                      // 设置  源地址
    DMA_DADDR(CHn) =    (uint32)DADDR;                      // 设置目的地址
    DMA_SOFF(CHn)  =    0x00u;                              // 设置源地址偏移 = 0x0, 即不变
    DMA_DOFF(CHn)  =    BYTEs;                              // 每次传输后,目的地址加 BYTEs
    DMA_ATTR(CHn)  =    (0
                         | DMA_ATTR_SMOD(0x0)               // 源地址模数禁止  Source address modulo feature is disabled
                         | DMA_ATTR_SSIZE(byten)            // 源数据位宽 :DMA_BYTEn  。    SSIZE = 0 -> 8-bit ,SSIZE = 1 -> 16-bit ,SSIZE = 2 -> 32-bit
                         | DMA_ATTR_DMOD(0x0)               // 目标地址模数禁止
                         | DMA_ATTR_DSIZE(byten)            // 目标数据位宽 :DMA_BYTEn  。  设置参考  SSIZE
                        );


    DMA_CR &= ~DMA_CR_EMLM_MASK;                                // CR[EMLM] = 0

    //当CR[EMLM] = 0 时:
    DMA_NBYTES_MLNO(CHn) =   DMA_NBYTES_MLNO_NBYTES(BYTEs); // 通道每次传输字节数,这里设置为BYTEs个字节。注:值为0表示传输4GB */

    /* 配置 DMA 传输结束后的操作 */
    DMA_SLAST(CHn)      =   0;                              //调整  源地址的附加值,主循环结束后恢复  源地址
    DMA_DLAST_SGA(CHn)  =   0;                             //调整目的地址的附加值,主循环结束后恢复目的地址
    DMA_CSR(CHn)        =   (0
                             | DMA_CSR_BWC(3)               //带宽控制,每读一次,eDMA 引擎停止 8 个周期(0不停止;1保留;2停止4周期;3停止8周期)
                             //| DMA_CSR_DREQ_MASK            //主循环结束后停止硬件请求
                             | DMA_CSR_INTMAJOR_MASK        //主循环结束后产生中断
                            );

    /* 配置 DMA 触发源 P455 */
    DMAMUX_CHCFG_REG(DMAMUX1_BASE_PTR, (CHn - 16)) = (0     /*(CHn - 16) 需要独立配置*/
            | DMAMUX_CHCFG_ENBL_MASK                        /* Enable routing of DMA request */
            | DMAMUX_CHCFG_SOURCE(DMA_ADC0)                 /* 通道触发传输源:     */
                                           );
    /*使能ADC0  DMA  P921 */  
    ADC0_SC2 |= 0x00000004;

    DMA_DIS(CHn);                                    
    DMA_IRQ_CLEAN(CHn);
    DMA_EN(CHn);                        //使能DMA 硬件请求
}


回复

使用道具 举报

 楼主| 发表于 2017-8-29 13:48:59 | 显示全部楼层
主函数:
    DMA1ADC0Init(DMA_CH16, (void *)(&(ADC0_R(0))), (void *)BUFF0_U, DMA_BYTE2, DADDR_KEEPON);   
    ADC0Init();
    PIT0Init();      
    while(1)
    {
       for(i = 0;i < 3 ; i++)
       {
            
          a = BUFF0_U[i];
        
       }
        
    }
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回列表 返回顶部