STM32F4四路ADC采样问题探讨

1.ADC配置

1.1模式确定

主从模式,选择主ADC1模式带动从ADC2模式
ADC模式
交替模式
对应代码段:

/* Enable DMA request after last transfer (Multi-ADC mode)  */
ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);

1.2 时钟初始化ADC

ADC时钟挂在APB2上,这里程序配置为168MHz

RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);

RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,DISABLE);

1.3 引脚选择和初始化

1.3.1 引脚

这里的ADC是加DMA的,需要根据DMA和ADC相关默认引脚来选择
简化来说 PC0–ADC通道10,PC1–ADC通道11…
选定相应引脚

1.3.2 初始化配置

ADC_Init(ADC2, &ADC_InitStructure);
/* ADC2 regular channel5 configuration ****************/
ADC_RegularChannelConfig(ADC2,ADC_Channel_13,1,
ADC_SampleTime_15Cycles);		//PC3
/* ADC1 regular channel5 configuration ************/
ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 2, ADC_SampleTime_15Cycles);		//PA3

ADC_Init(ADC1, &ADC_InitStructure); 

/* ADC1 regular channel5 configuration ****************/
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_15Cycles);		//PC2
/* ADC1 regular channel5 configuration ******************/
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SampleTime_15Cycles);		//PA5
...
ADC_Cmd(ADC1, ENABLE)
ADC_Cmd(ADC2, ENABLE);

2.DMA配置

2.1初始化

确定数据流,这里F4系列的开发板有3个ADC
DMA2

2.2程序配置

/* DMA2 Stream0 channel2 configuration */
DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)aADCConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = ADC_BUF_SIZE;
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_FIFOMode = DMA_FIFOMode_Enable;         
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE);

3.滤波平均

3.1一般滤波方法

这里尝试过其他一些滤波方法,加权滤波,中值滤波,滑动滤波方法,在大数据量下,排序消耗时间和占用资源都比较不好,经测试,一般滤波方法比较好。

u32 adc_filter(u32 cnt,u32 adc_num_value){
	u8 i;
	u32 adc_min=0,adc_max=0;
	u32 adc_sum=0,adc_ave=0;
	for(i=0;i<cnt;i++){
		adc_sum += adc_num_value;
		adc_min=adc_num_value;
		adc_max=adc_num_value;
		
		if(adc_num_value<=adc_min)
			adc_min=adc_num_value;
		if(adc_num_value>=adc_max)
			adc_max=adc_num_value;
	}
	adc_sum -= (adc_max+adc_min);	
	adc_ave=adc_sum/(cnt-2);
	adc_sum=0;
	return adc_ave;
}

3.2 采样计算求值

根据之前规定的组合依次可计算出各采样值,这里优化了浮点计算方法

u8 j,k;
u32 adc_getvalue[4];
memset(&adc_getvalue,0,sizeof(adc_getvalue));
for(j=0;j<40;j++)
{
	for(k=0;k<4;k++)
	adc_getvalue[k] += adc_filter(8,aADCConvertedValue[k]);
}//PC3--[1] PC1--[3] PC2--[0] PA5--[2]
voltage1_calculate=	(float)adc_getvalue[0]*33/(400*4096);
voltage2_calculate=	(float)adc_getvalue[1]*33/(400*4096);
current1_calculate=	(float)adc_getvalue[2]*33/(400*4096);
current2_calculate=	(float)adc_getvalue[3]*33/(400*4096);
	
memset(&adc_getvalue,0,sizeof(adc_getvalue));
	
//减少线差
adc_voltage1=voltage1_calculate;
adc_voltage2=voltage2_calculate;
adc_current1=current1_calculate;
adc_current2=current2_calculate;			

这里相关配置就可以结束了,需注意的是,计算采样时需要定义数组,数组类型也有明确要求。这里附上程序配置相关文件

  • 1
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
STM32F4上使用ADC采样测试纹波的过程可以分为以下几个步骤: 1. 配置ADC模块:使用STM32F4的CubeMX工具或手动编写代码配置ADC模块,设置采样分辨率、采样时间、转换模式等参数。 2. 连接信号源:将待测试的纹波信号连接到STM32F4ADC输入引脚上。 3. 采样:启动ADC转换并等待采样完成。可以采用轮询方式或者中断方式进行采样。 4. 处理数据:将采样得到的原始数据进行处理,例如计算均值、标准差、最大值、最小值等统计量,或者进行频域分析和滤波处理。 下面是一个简单的示例代码,用于采样测试纹波: ```c #include "stm32f4xx.h" #define ADC_CHANNEL 0 // ADC采样通道 #define SAMPLE_SIZE 1000 // 采样点数 uint16_t adc_data[SAMPLE_SIZE]; // 采样数据缓存 void adc_init(void) { ADC_InitTypeDef adc_init; GPIO_InitTypeDef gpio_init; // 1. 配置GPIO引脚为模拟输入模式 gpio_init.Pin = GPIO_PIN_0; gpio_init.Mode = GPIO_MODE_ANALOG; HAL_GPIO_Init(GPIOA, &gpio_init); // 2. 配置ADC模块 __HAL_RCC_ADC1_CLK_ENABLE(); adc_init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; adc_init.Resolution = ADC_RESOLUTION_12B; adc_init.ScanConvMode = DISABLE; adc_init.ContinuousConvMode = ENABLE; adc_init.DiscontinuousConvMode = DISABLE; adc_init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; adc_init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1; adc_init.DataAlign = ADC_DATAALIGN_RIGHT; adc_init.NbrOfConversion = 1; HAL_ADC_Init(&adc_init); // 3. 配置ADC采样通道 ADC_ChannelConfTypeDef adc_channel; adc_channel.Channel = ADC_CHANNEL_0; adc_channel.Rank = 1; adc_channel.SamplingTime = ADC_SAMPLETIME_3CYCLES; HAL_ADC_ConfigChannel(&adc_channel); } void adc_sample(void) { uint32_t i; // 1. 启动ADC采样 HAL_ADC_Start(&hadc1); // 2. 等待采样完成 for (i = 0; i < SAMPLE_SIZE; i++) { while (__HAL_ADC_GET_FLAG(&hadc1, ADC_FLAG_EOC) == RESET); adc_data[i] = HAL_ADC_GetValue(&hadc1); } // 3. 停止ADC采样 HAL_ADC_Stop(&hadc1); } int main(void) { // 初始化ADC模块 adc_init(); // 采样纹波信号 adc_sample(); // 处理采样数据,例如计算均值、标准差、最大值、最小值等统计量, // 或者进行频域分析和滤波处理。 while (1); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值