初级会员
- 积分
- 52
- 金钱
- 52
- 注册时间
- 2024-3-16
- 在线时间
- 9 小时
|
1金钱
各位大佬,我用stm32f030f4p6 单通道ADC单次采样+DMA中断搬运数据,通过模拟开关4052切换通道采样参考电阻和热电阻电压。已经把采样周期调到最高了还是有几十的跳动,把数据进行中值平均滤波之后,参考电阻的ADC值会好很多基本上跳1~2有时会有4左右上下,但是热电阻还会有十几的跳动。是程序配置有问题,还是ADC单通道单次转换在main里循环开启转换一开始都会不准?改成连续转换得到比如30个值通过DMA搬运到一个数组中,然后切换模拟开关再采集完成所有通道再做滤波会有效果吗。
我下面的代码不知道是不是有问题望指正
#include "adc.h"
ADC_BUFF PT100_BUFF = {0};
void ADC_PT100_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
ADC_InitTypeDef ADC_InitStruct = {0};
NVIC_InitTypeDef NVIC_InitStruct = {0};
DMA_InitTypeDef DMA_InitStruct = {0};
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); //开启GPIOC的RCC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //开启ADC1的RCC时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //开启DMA1的RCC时钟
ADC_ClockModeConfig(ADC1, ADC_ClockMode_SynClkDiv4);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStruct);
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;//单次转换
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//无外部触发
ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;//精度12位
ADC_Init(ADC1, &ADC_InitStruct);
ADC_ChannelConfig(ADC1, ADC_Channel_1, ADC_SampleTime_239_5Cycles);
ADC_GetCalibrationFactor(ADC1);
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_OneShot);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));
DMA_InitStruct.DMA_BufferSize = 1;//初始化NDTR计数值
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;//从外设到内存
DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)PT100_BUFF.pt100_Val;//内存基地址
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;//*dis
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&ADC1->DR);
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_Init(DMA1_Channel1, &DMA_InitStruct);
DMA_Cmd(DMA1_Channel1, ENABLE);
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPriority = 0;
NVIC_Init(&NVIC_InitStruct);
}
#if 0
uint16_t Get_Channel_Value()
{
ADC_ChannelConfig(ADC1, ADC_Channel_1 , ADC_SampleTime_239_5Cycles);
ADC_StartOfConversion(ADC1);
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
return ADC_GetConversionValue(ADC1);
}
#endif
#if 1
void DMA1_Channel1_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC1))
{
DMA_ClearITPendingBit(DMA1_IT_TC1);
DMA_Cmd(DMA1_Channel1,DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel1,1);
// DMA_ClearITPendingBit(DMA1_IT_TC1);
DMA_Cmd(DMA1_Channel1,ENABLE);
PT100_BUFF.adcFlag = 1;
}
}
#endif
//中值平均滤波
uint16_t Get_Adc_Average(uint16_t ARRY[])
{
int i,n,m,tmp=0,sum=0;
for(n=0;n<51;n++)
{
for(m=0;m<(51-n);m++)
{
if(ARRY[m]>ARRY[m+1])
{
tmp = ARRY[m];
ARRY[m] = ARRY[m+1];
ARRY[m+1] = tmp;
}
}
}
for(i=1;i<51;i++)
{
sum+=ARRY;
}
return sum/50;
}
#ifndef __ADC_H__
#define __ADC_H__
#include "stm32F0xx.h"
#include "systick.h"
typedef struct
{
uint16_t pt100_Val[52];
uint8_t adcFlag;
}ADC_BUFF;
extern ADC_BUFF PT100_BUFF;
extern void ADC_PT100_Init(void);
extern uint16_t Get_Channel_Value();
extern uint16_t Get_Adc_Average(uint16_t ARRY[]);
#endif
int main()
{
Systick_Init(48);
Delay_Ms(1000);//启动延时
GPIO_Int();
GPIOInfrared_Config();
RCC_GetClocksFreq(&RCC_Clocks);
ADC_PT100_Init();
while(1)
{
uint16_t adcarr[52] = {0} , adcarr1[52] = {0} , adcarr2[52] = {0} , adcarr3[52] = {0};//存放adc值以用来进行中值平均滤波的存储数组
GPIO_ResetBits(GPIOA,GPIO_Pin_5);//使能cd4052 INH
//cd4052地址选择 A=0,B=0 选择接通通道为X0,Y0 采集PT100_1adc
GPIO_ResetBits(GPIOA,GPIO_Pin_3);
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
//Tim_Delay_Us(50);
Delay_Ms(10);
for(i=0;i<52;i++)
{
ADC_StartOfConversion(ADC1);//开启规则通道转换
while(!PT100_BUFF.adcFlag);
PT100_BUFF.adcFlag = 0;
adcarr = PT100_BUFF.pt100_Val[0];
}
|
|