初级会员 
  
	- 积分
 - 58
 
        - 金钱
 - 58 
 
       - 注册时间
 - 2024-3-16
 
      - 在线时间
 - 11 小时
 
 
 
 | 
 
5金钱 
各位大佬,我用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]; 
        } 
 
 |   
 
 
 
 
 
 |