OpenEdv-开源电子网

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

关于ADC采集使用DMA

[复制链接]

10

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
99
金钱
99
注册时间
2016-7-7
在线时间
13 小时
发表于 2017-12-7 13:55:57 | 显示全部楼层 |阅读模式
1金钱
就是代码如下      DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;                      //外设地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)s_astAdcResult;                     //内存地址
  ADC_RegularChannelConfig(ADC1, ADC_Channel_10,1,ADC_SampleTime_239Cycles5);  ADC_RegularChannelConfig(ADC1, ADC_Channel_11,2,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_12,3,ADC_SampleTime_239Cycles5);

s_astAdcResult 是一个结构体。
static struct tagAdcResult
{
    u32 unPreSensor1;
    u32 unPreSensor2;
    u32 unStopclamp;

}s_astAdcResult[10];


我想知道ADC_Channel_12,什么时候采集数据结束,有没有什么标志位之类的。、
怎么单独读取ADC_Channel_12的数据




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2017-12-7 14:29:41 | 显示全部楼层
本帖最后由 275891381 于 2017-12-7 14:30 编辑

打开dma的中断吧,采集完了会有中断
//PA0--ADC_Channel_0  PA1--ADC_Channel_1  PA4--ADC_Channel_4   PA5--ADC_Channel_5   
//PA6--ADC_Channel_6  PA7--ADC_Channel_7  PB0--ADC_Channel_8   PB1--ADC_Channel_9
//内部参考电压 ADC_Channel_Vrefint--ADC_Channel_17
void  Adc_Init(void)
{        
                        GPIO_InitTypeDef  GPIO_InitStructure;
                        ADC_InitTypeDef  ADC_InitStructure;
            DMA_InitTypeDef DMA_InitStructure;
            NVIC_InitTypeDef NVIC_InitStructure;
       
                        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO, ENABLE );   

                        RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //72M/6=12,ADC最大时间不能超过14M   
                                                                                                                                                 
                        GPIO_InitStructure.GPIO_Pin =GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;       
                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;               
                        GPIO_Init(GPIOA, &GPIO_InitStructure);


                        ADC_DeInit(ADC1);  //将外设 ADC1 的全部寄存器重设为缺省值
                        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;        //ADC工作模式:ADC1和ADC2工作在独立模式
                        ADC_InitStructure.ADC_ScanConvMode =ENABLE;        //多信道扫描模式
                        ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  //模数转换工作在连续转换模式
                        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;   //外部触发转换关闭
                        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;        //ADC数据右对齐
                        ADC_InitStructure.ADC_NbrOfChannel = CH_NUM;        //此处开7个信道(可开的为1~16)
                        ADC_Init(ADC1, &ADC_InitStructure);        //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器


                        //ADC1,ADC通道x,规则采样顺序值为y,采样时间为239.5周期
                        ADC_RegularChannelConfig(ADC1, ADC_Channel_4,1, ADC_SampleTime_239Cycles5 );               
                        ADC_RegularChannelConfig(ADC1, ADC_Channel_5,2, ADC_SampleTime_239Cycles5 );
                        ADC_RegularChannelConfig(ADC1, ADC_Channel_6,3, ADC_SampleTime_239Cycles5 );
                        ADC_TempSensorVrefintCmd(ENABLE); //开启内部温度传感器,参考电压通道
                        ADC_RegularChannelConfig(ADC1, ADC_Channel_Vrefint,4, ADC_SampleTime_239Cycles5 );

                        //开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数)
                        ADC_DMACmd(ADC1, ENABLE);       //使能ADC1的DMA传输         
                        ADC_Cmd(ADC1, ENABLE);           //使能指定的ADC1
                        ADC_ResetCalibration(ADC1);        //复位指定的ADC1的校准寄存器
                        while(ADC_GetResetCalibrationStatus(ADC1));        //获取ADC1复位校准寄存器的状态,设置状态则等待
                        ADC_StartCalibration(ADC1);                //开始指定ADC1的校准状态
                        while(ADC_GetCalibrationStatus(ADC1));                //获取指定ADC1的校准程序,设置状态则等待
                        ADC_SoftwareStartConvCmd(ADC1, ENABLE);          //软件启动AD转换
     /* Enable the DMA Interrupt */
                        NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;   
                        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA1_Channel1_IRQHandler_NVIC_IRQChannelPreemptionPriority;     // 优先级设置
                        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
                        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
                        NVIC_Init(&NVIC_InitStructure);               
                        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
                        DMA_DeInit(DMA1_Channel1);   //将DMA的通道1寄存器重设为缺省值
                        DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)ADC1_DR_Address;  //DMA外设ADC基地址
                        DMA_InitStructure.DMA_MemoryBaseAddr =    (u32)&AD_Value;        //DMA内存基地址
                        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //内存作为数据传输的目的地
                        DMA_InitStructure.DMA_BufferSize = CH_NUM;  //DMA通道的DMA缓存的数据单元大小
                        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
                        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
                        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //数据宽度为16位
                        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
                        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(DMA1_Channel1, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道
                        DMA_ClearFlag(DMA1_Channel1_IRQn);                                 // 清除DMA所有标志
                        DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);
                        DMA_Cmd(DMA1_Channel1, ENABLE);           //启动DMA通道
}                                  


void DMA1_Channel1_IRQHandler(void)
{
                u8 i=0;
    if(DMA_GetITStatus(DMA1_FLAG_TC1))
    {
            DMA_ClearFlag(DMA1_FLAG_GL1);         // 清除标志
            for(i=0;i<CH_NUM;i++)
                                                         AD_float_v=(float)AD_Value/(float)AD_Value[CH_NUM-1]*1.2*1000;
                                 //AD_float_v=(float)AD_Value/4096.0*3.3*1000;
                             //添加滤波函数
    }
}

回复

使用道具 举报

10

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
99
金钱
99
注册时间
2016-7-7
在线时间
13 小时
 楼主| 发表于 2017-12-7 16:11:47 | 显示全部楼层
275891381 发表于 2017-12-7 14:29
打开dma的中断吧,采集完了会有中断
//PA0--ADC_Channel_0  PA1--ADC_Channel_1  PA4--ADC_Channel_4   PA ...

这个中断是3个通道的数据全部采集产生的,还是单个通道采集完就产生的。,我想要的是,比如通道5,他是第二个转换的,我就是想要这个通道转换完成的标志,而不是3个通道全部转换完成的标志。
回复

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2017-12-7 16:31:07 | 显示全部楼层
S火星人S 发表于 2017-12-7 16:11
这个中断是3个通道的数据全部采集产生的,还是单个通道采集完就产生的。,我想要的是,比如通道5,他是第 ...

这个就不知道了,没这么精细过
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-10 18:33

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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