请问STM32的ADC,对于指定通道如何实现多次采样后再将AD值通过DMA传入内存

-网上有很多ADC与DMA结合的例程,但是发现都是每次ADC转换完成就通过DMA传输给内存。
-我现在希望达到这样的效果,为了让AD转换值更稳定,需要其连续转换10次后,再通过DMA传输给内存,但是不知道怎么设置这个10次这个值。
-之前的方法一直是在ADC终端里,通过软件判断转换次数,达到10次后再软件赋给指定内存,不知道这次能不能用DMA实现这个方法。

多次采集取平均值即可,给你个我写的四通道转换,想更平稳的话可以在条件允许的情况下简单的用下递推平均滤波

/*********************************************************************************
 * 文件名  :ADC.c
 * 描述    :ADC模块
 * 库版本  :ST3.5.0   
 * 编写时间:2013年12月3日
 * 编写人  :LiuHui
 *
 *
 * 修改时间:2013年7月8
 * 修改内容:
 *          @1更改ADC通道为PC0~3
 *          @2加入过采样,提高精度减小波动 
 *  @!!!!
 *  程序在开发板和核心板上运行完全正常,放到SD板上ADC_ConvertedValue[1]总是等于ADC_ConvertedValue[0]
 *  原因未查明,初步判断为DMA问题,使用SD卡型时勿用ADC_ConvertedValue[1]
 *  原因现已查明为SD板问题  
 *  @!!!!
*/
#include "system.h"
#include "ADC.h"
vu16 ADC_ConvertedValue[Sample_Num][Channel_Num];
void ADC_DMA_Config(void)
{
 DMA_InitTypeDef DMA_InitStructure;
             
 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
 DMA_DeInit(DMA1_Channel1);
 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
 DMA_InitStructure.DMA_BufferSize = Sample_Num*Channel_Num;
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不变
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址递增
 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
 DMA_InitStructure.DMA_Priority = DMA_Priority_High;
 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
 DMA_Init(DMA1_Channel1, &DMA_InitStructure);
 DMA_Cmd(DMA1_Channel1,ENABLE);
}
void ADC1_Config(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 ADC_InitTypeDef ADC_InitStructure;
 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
 GPIO_Init(GPIOC, &GPIO_InitStructure);
 ADC_DMA_Config();
 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
// ADC_DeInit(ADC1);
 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//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_InitStructure.ADC_NbrOfChannel = Channel_Num;//通道数目
 ADC_Init(ADC1, &ADC_InitStructure); 
// ADC_TempSensorVrefintCmd(ENABLE);//使能片内温度传感器
 
 RCC_ADCCLKConfig(RCC_PCLK2_Div6); //PCLK 6分频
 ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);//通道,转换次序,转换时间
 ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_55Cycles5);
 ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3, ADC_SampleTime_55Cycles5);
 ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 4, ADC_SampleTime_55Cycles5);
// ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 6, ADC_SampleTime_239Cycles5);
 
 ADC_DMACmd(ADC1, ENABLE);
 
 ADC_Cmd(ADC1, ENABLE);
 ADC_ResetCalibration(ADC1);
 while(ADC_GetResetCalibrationStatus(ADC1));
 ADC_StartCalibration(ADC1);//开始校准
 while(ADC_GetCalibrationStatus(ADC1));
 ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能ADC的软件转换启动功能
}
uint16_t ReadADCAverageValue(uint16_t Channel)
{
 uint8_t i;
 uint32_t sum = 0;
 for(i=0; i<Sample_Num; i++)
 {
  sum+=ADC_ConvertedValue[i][Channel];
 }
 return (sum/Sample_Num);
}


头文件
#ifndef __ADC_H
#define __ADC_H
/*使用示例:
*
 printf("%d\r\n",ADC_ConvertedValue[0]);
 printf("%d\r\n",ADC_ConvertedValue[1]);
 printf("%d\r\n",ADC_ConvertedValue[2]);
 printf("о?:%f\r\n",(1.43-(ADC_ConvertedValue[3]*3.3/4096))/0.0043+25);
*
 sprintf(ch,"AD0 Value Is:%5d.",ADC_ConvertedValue[0]);
 printf("%s",ch);
 LCD_ShowString(20,20,(uint8_t*)ch,Color[i]);
 sprintf(ch,"AD1 Value Is:%5d.",ADC_ConvertedValue[1]);
 printf("%s",ch);
 LCD_ShowString(20,40,(uint8_t*)ch,Color[i]);
 sprintf(ch,"AD2 Value Is:%5d.",ADC_ConvertedValue[2]);
 printf("%s",ch);
 LCD_ShowString(20,60,(uint8_t*)ch,Color[i]);
 sprintf(ch,"AD3 Value Is:%5d.",ADC_ConvertedValue[3]);
 printf("%s",ch);
 LCD_ShowString(20,80,(uint8_t*)ch,Color[i]);
*/
#define Channel_Num  4
#define Sample_Num  10
extern vu16 ADC_ConvertedValue[Sample_Num][Channel_Num];
void ADC1_Config(void);
uint16_t ReadADCAverageValue(uint16_t Channel);
#endif

追问

请问是谁来调用的ReadADCAverageValue,是在DMA的中断,还是在还是在需要调用ADC值之前的代码中进行?

追答

主程序需要使用ADC转换的数据的时候,比如读取通道10直接调用ReadADCAverageValue(0x00);

温馨提示:内容为网友见解,仅供参考
无其他回答

STM32CubeMX配置-ADC多通道配置(DMA)
首先,ADC数据采集可以通过两种方式实现:一种是轮询方式,直接在数组中处理采集数据;另一种是中断模式,ADC在完成采样后会触发中断,中断处理完数据后关闭ADC并重新开启。本文将重点介绍轮询采集的配置步骤。配置步骤如下:设置ADC通道及其参数:在STM32CubeMX中,通过Sequencer参数来控制通道顺序,比如Rank1...

STM32 ADC多通道转换详解(附源代码)
STM32ADC多通道转换描述:通过ADC连续采集11路模拟信号,并由DMA传输至内存。配置ADC为扫描并连续转换模式,设置ADC时钟为12MHZ。每次转换完成,DMA循环将数据传输至内存。ADC可连续采集N次以计算平均值。最终,通过串口输出最终转换结果。程序如下:为大家提供以下资料供参考:- ADC读取光照传感器 - 深度剖...

STM32U5 ADC+DMA配置演示
首先,我们以ADC1为例进行标准请求模式的配置演示。选取ADC1的四个通道,设置为扫描模式与连续转换,通过DMA传输转换结果,并让DMA工作在外设字到内存字的循环传输模式。配置过程中,使用CubeMx进行初始化,确保DMA通道的正确设置。实际代码中,运行结果显示已成功获取四个通道的转换数据。接着,我们转向ADC...

【STM32学习】——ADC模数转换器
AD_ContinuousConvMode = ENABLE;ADC_SoftwareStartConvCmd(ADC1, ENABLE); \/\/ 移至初始化函数通过四个通道(如PA0电位器和PA1-PA3传感器)进行测量,采用AD_GetValue函数获取每个通道的值,代码示例如下:uint16_t AD_GetValue(uint8_t ADC_Channel) { ADC_RegularChannelConfig(ADC1, ADC_Channe...

(四)ADC与DMA传输【HAL】
使用DMA解决ADC转换数据存储问题,配置DMA通道,使其在ADC转换完成后自动将数据从外设移到内存,简化数据处理过程。代码编写时,初始化ADC和DMA,使用连续转换模式,期间通过DMA传输数据到内存。在while循环中,持续输出ADC值,并处理数据,如转换电压、温度值计算。连接硬件后,烧写程序,通过串口调试助手查看...

STM32的ADC模块应用与配置方法详解
此外,可以使用DMA(直接内存访问)来实现数据的直接存储,减轻主处理器的负担。最后,根据需要配置中断,以便在ADC转换完成时触发中断。示例代码演示了如何配置和使用STM32的ADC模块进行单次转换。此代码展示了初始化ADC1模块并进行单次转换的过程,首先通过相应的函数进行配置,然后在循环中使用`ADC1_Read(...

STM32之ADC通道顺序设置
将会先采样ADC10通道,后面依次采样通道ADC11、ADC12、ADC13 假如通道ADC10、ADC11、ADC12、ADC13的通道号设置一样的话,那么DMA输出到内存得到的四个通道的值将是不确定的,四个值基本相同,如下图 分别设置好通道的采样顺序后,DMA端就可以精确的输出每一个通道的采样值,如下图 ...

STM32外设ADC的配置和应用
配置ADC时,要考虑到分辨率、采样周期与转换周期,如在STM32F4xx中,12bits分辨率下,单次转换时间约为0.5us。多通道扫描和ADC与DMA的协同工作,可以提高数据采集效率。在硬件受限时,可以采用软件方法如采样平均或数字滤波来提升采样精度,甚至通过软件校准来纠正偏差。了解ADC的配置和应用对于精确控制和...

STM32的ADC和DAC
在实际应用中,例如在STM32F429IGT6上,通过ADC定时器触发和DMA实现快速采样,但要确保ADC时钟速度大于定时器触发速度,以避免采样速度滞后。ADC的精度受外部输入阻抗和内部结构影响,需注意信号源的阻抗以减小转换误差。同时,多通道ADC使用时需考虑通道间串扰问题,可通过增加采样间隔时间来缓解。I\/O引脚...

STM32 ADC详解
ADC转换的触发可以是寄存器配置、内部定时器、外部IO或DMA。转换周期由ADC_SMPR1和ADC_SMPR2寄存器中的SMP[2:0]位设置,总转换时间包括采样时间和12个周期。数据寄存器分为规则数据寄存器和注入数据寄存器,分别存储规则通道和注入通道的转换数据。中断功能可以产生4种中断:DMA溢出中断、规则通道转换完成中断...

相似回答