OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2881|回复: 8

dma ADC 多次采集

[复制链接]

23

主题

130

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
314
金钱
314
注册时间
2015-1-25
在线时间
83 小时
发表于 2017-8-1 10:06:25 | 显示全部楼层 |阅读模式
30金钱
本帖最后由 neuangel 于 2017-8-1 14:59 编辑

遇到的问题:
只能开机采样一次,然后dma无法多次取得采样结果



/****************ADC_INIT*************************/void Adc1_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        ADC_InitTypeDef ADC_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);

        
         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;                                 //PA1端口配置,控制电路被采样部分开始上电
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                  //推挽输出
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
         GPIO_Init(GPIOA, &GPIO_InitStructure);        
        RCC_ADCCLKConfig(RCC_PCLK2_Div6);        
        ADC_DeInit(ADC1);
        ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;

        ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//DMA循环扫描
        
        ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
        ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
        ADC_InitStructure.ADC_NbrOfChannel=1;

        ADC_InitStructure.ADC_ScanConvMode=DISABLE;
        ADC_Init(ADC1,&ADC_InitStructure);
        
        ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);
        ADC_Cmd(ADC1,ENABLE);
        ADC_DMACmd(ADC1,ENABLE);
        
        ADC_ResetCalibration(ADC1);
        while(ADC_GetResetCalibrationStatus(ADC1));
        ADC_StartCalibration(ADC1);        
        while(ADC_GetCalibrationStatus(ADC1));        

        ADC_SoftwareStartConvCmd(ADC1,ENABLE);//启动        
        
}

/***********************DMA_ADC_CONFIG***************************************/


void DMA_ADC_Enable(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);        //使能DMA传输
        
    DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
        DMA_InitStructure.DMA_PeripheralBaseAddr                 =                 cpar;  //DMA外设ADC基地址
        DMA_InitStructure.DMA_MemoryBaseAddr                 =                 cmar;;  //DMA内存基地址
        DMA_InitStructure.DMA_DIR                                         =                DMA_DIR_PeripheralSRC;        //外设为源地址
        DMA_InitStructure.DMA_BufferSize                                =                 cndtr;  //DMA通道的DMA缓存的大小
        DMA_InitStructure.DMA_PeripheralInc                         =                 DMA_PeripheralInc_Disable;  //外设地址寄存器不变
        DMA_InitStructure.DMA_MemoryInc                         =                 DMA_MemoryInc_Disable;  //内存地址寄存器递增
        DMA_InitStructure.DMA_PeripheralDataSize                 =                 DMA_PeripheralDataSize_HalfWord;  //16位
        DMA_InitStructure.DMA_MemoryDataSize                         =                 DMA_MemoryDataSize_HalfWord;
        DMA_InitStructure.DMA_Mode                                 =                 DMA_Mode_Circular;//循环模式
        DMA_InitStructure.DMA_Priority                                 =                 DMA_Priority_High; //DMA通道 x拥有中优先级
        DMA_InitStructure.DMA_M2M                                 =                 DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
        DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel
         DMA_Cmd(DMA_CHx, ENABLE);  //使能USART1 TX DMA1 所指示的通道

}

/**************************MAIN********************************/
vu16 temp_adc1;

int main(void )
{
     Adc1_init();
     DMA_ADC_Enable(DMA1_Channel1,(u32)&ADC1->DR,(u32)&temp_adc1,1);
    while(1)

    {

           printf("temp_adc1_dma  =   %f\r\n",(float)temp_adc1*3.3/4096);
      /*******************************************************************************
          问题:temp_adc1采集到的数值是开机时的数值,不变化,我的想法是,实时采集adc的数据


          我也曾尝试:是不是adc采样一次, 就关闭了,然后按照下面的各种测试,均不可
                      //                DMA_Cmd(DMA1_Channel1, ENABLE);
                      //                delay_ms(10);
                      //                ADC_Cmd(ADC1,ENABLE);
                     //                ADC_SoftwareStartConvCmd(ADC1,ENABLE);



      ***********************************************************************************/

     }
}

最佳答案

查看完整内容[请看2#楼]

应该是 disable 吧,我传到指定的temp_adc1这里,固定的地址呢, //后面是之前的 注释
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

23

主题

130

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
314
金钱
314
注册时间
2015-1-25
在线时间
83 小时
 楼主| 发表于 2017-8-1 10:06:26 | 显示全部楼层
翼间 发表于 2017-8-2 10:14
DMA_InitStructure.DMA_MemoryInc                         =                 DMA_MemoryInc_Disable;  ...

应该是 disable 吧,我传到指定的temp_adc1这里,固定的地址呢,

//后面是之前的 注释
回复

使用道具 举报

23

主题

130

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
314
金钱
314
注册时间
2015-1-25
在线时间
83 小时
 楼主| 发表于 2017-8-1 10:08:08 | 显示全部楼层
              //                DMA_Cmd(DMA1_Channel1, ENABLE);
                      //                delay_ms(10);
                      //                ADC_Cmd(ADC1,ENABLE);
                     //                ADC_SoftwareStartConvCmd(ADC1,ENABLE);

这几行命令,后面都跟有使能关闭


                     //                DMA_Cmd(DMA1_Channel1, DISABLE);
                      //                delay_ms(10);
                      //                ADC_Cmd(ADC1,DISABLE);
                     //                ADC_SoftwareStartConvCmd(ADC1,DISABLE);
回复

使用道具 举报

23

主题

130

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
314
金钱
314
注册时间
2015-1-25
在线时间
83 小时
 楼主| 发表于 2017-8-1 10:58:37 | 显示全部楼层
大家给看看呀,dma开机只能得到一次数据,在无法更新,对照了好多的参考程序,还是没有找到问题所在,求看看
回复

使用道具 举报

23

主题

130

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
314
金钱
314
注册时间
2015-1-25
在线时间
83 小时
 楼主| 发表于 2017-8-1 15:00:34 | 显示全部楼层
再顶一次
回复

使用道具 举报

1

主题

192

帖子

0

精华

高级会员

Rank: 4

积分
597
金钱
597
注册时间
2014-4-14
在线时间
104 小时
发表于 2017-8-1 16:58:20 | 显示全部楼层
先初始化DMA,但不要使能DMA,再初始化ADC,开始ADC转换,再使能DMA试试看,目前就这个程序跟我的也就是顺序有点差别而已。但我的正常。
回复

使用道具 举报

23

主题

130

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
314
金钱
314
注册时间
2015-1-25
在线时间
83 小时
 楼主| 发表于 2017-8-2 09:49:41 | 显示全部楼层
翼间 发表于 2017-8-1 16:58
先初始化DMA,但不要使能DMA,再初始化ADC,开始ADC转换,再使能DMA试试看,目前就这个程序跟我的也就是顺 ...

按照你的方法试了,还是不行
回复

使用道具 举报

1

主题

192

帖子

0

精华

高级会员

Rank: 4

积分
597
金钱
597
注册时间
2014-4-14
在线时间
104 小时
发表于 2017-8-2 10:14:51 | 显示全部楼层
本帖最后由 翼间 于 2017-8-2 10:16 编辑

   DMA_InitStructure.DMA_MemoryInc                         =                 DMA_MemoryInc_Disable;  //内存地址寄存器递增这一句的注释和代码是矛盾的,代码是禁止了地址内存递增。
回复

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2017-8-20
在线时间
4 小时
发表于 2017-8-21 18:03:30 | 显示全部楼层
本帖最后由 zqw丶freshman 于 2017-8-21 18:54 编辑
翼间 发表于 2017-8-1 16:58
先初始化DMA,但不要使能DMA,再初始化ADC,开始ADC转换,再使能DMA试试看,目前就这个程序跟我的也就是顺 ...

可以贴一下程序参考一下吗?(初始化的程序)
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-20 22:53

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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