zerorobert 发表于 2025-5-24 20:22

适用于嵌入式ADC RC低通滤波




#define                ADC_SMPILE_NUM                4
#define                ADC_CHANNEL_NUM                6
uint16_t adc1Value;

// Filtered measurement variables
uint32_tadcFilterSum;
uint16_tadcFilteredAdcVal;

uint16_t _ADC_GetSingleReading(uint8_t adcChannel)
{
        uint32_t adcval =adc1Value+
                                        adc1Value+
                                        adc1Value+
                                        adc1Value;
        return         adcval>>2;
}

void hdl_adcInit(void){

        GPIO_InitTypeDef GPIO_InitStruct;
        RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);
        RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOB, ENABLE);

        GPIO_StructInit(&GPIO_InitStruct);
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_4/*|GPIO_Pin_5*/|GPIO_Pin_6|GPIO_Pin_7;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStruct.GPIO_Mode =GPIO_Mode_AIN;
        GPIO_Init(GPIOA, &GPIO_InitStruct);
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
        GPIO_Init(GPIOB, &GPIO_InitStruct);
       
        DMA_InitTypeDef DMA_InitStruct;
        RCC_AHBPeriphClockCmd(RCC_AHBENR_DMA1, ENABLE);
        DMA_DeInit(DMA1_Channel1);
        DMA_StructInit(&DMA_InitStruct);
        //DMA transfer peripheral address
        DMA_InitStruct.DMA_PeripheralBaseAddr = (u32) & (ADC1->DR);
        //DMA transfer memory address
        DMA_InitStruct.DMA_MemoryBaseAddr = (u32)adc1Value;
        //DMA transfer direction from peripheral to memory
        DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
        //DMA cache size
        DMA_InitStruct.DMA_BufferSize = ADC_SMPILE_NUM*ADC_CHANNEL_NUM;
        //After receiving the data, the peripheral address is forbidden to move backward
        DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        //After receiving the data, the memory address is shifted backward
        DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
        //Define the peripheral data width to 16 bits
        DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
        //Define the memory data width to 16 bits
        DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
        //Cycle conversion mode
        DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
        //DMA priority is high
        DMA_InitStruct.DMA_Priority = DMA_Priority_High;
        //M2M mode is disabled
        DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
        DMA_InitStruct.DMA_Auto_reload = DMA_Auto_Reload_Disable;
        DMA_Init(DMA1_Channel1, &DMA_InitStruct);
        DMA_Cmd(DMA1_Channel1, ENABLE);
               
        ADC_DeInit(ADC1);
        ADC_InitTypeDefADC_InitStruct;
        ADC_StructInit(&ADC_InitStruct);
        //Enable ADC clock
        RCC_APB2PeriphClockCmd(RCC_APB2ENR_ADC1, ENABLE);
        ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
        //ADC prescale factor
        ADC_InitStruct.ADC_PRESCARE = ADC_PCLK2_PRESCARE_2;
        //Set ADC mode to continuous conversion mode
        ADC_InitStruct.ADC_Mode = ADC_Mode_Continue;
        //AD data right-justified
        ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStruct.ADC_ExternalTrigConv = ADC1_ExternalTrigConv_T2_TRIG;
        ADC_Init(ADC1, &ADC_InitStruct);

        //Enable the channel
        ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 0, ADC_Samctl_8_5);//1
        ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 0, ADC_Samctl_8_5);//2
        ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 0, ADC_Samctl_8_5);//3
        ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 0, ADC_Samctl_8_5);//4
        ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 0, ADC_Samctl_8_5);//5
        ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 0, ADC_Samctl_8_5);//6
//Enable ADCDMA
        ADC_DMACmd(ADC1, ENABLE);
        //Enable AD conversion
        ADC_Cmd(ADC1, ENABLE);
        ADC_ExternalTrigConvConfig(ADC1,ADC1_ExternalTrigConv_T1_CC1);
        ADC1->CR |=(1<<24)|(3<<19);//下降沿触发 ,512 个延时周期
        ADC_ExternalTrigConvCmd(ADC1, ENABLE);
}

// adc samp
void TIM3_init(void){
   RCC_APB1PeriphClockCmd(RCC_APB1ENR_TIM3, ENABLE);
        uint32_t arr =72000000L /100 -1;//100hz adc采样率
        TIM3->CR1 =(1<<7)|(1<<2);
        TIM3->PSC =0;
        TIM3->ARR =arr;
        TIM3->DIER =(1<<0);
               
        NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPriority = 2;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);
        TIM3->CR1|=(1<<0);//enable tim1
}

void ADCs_Init(void)
{
        hdl_adcInit();
        delay_ms(5000);
        // Setup the filtered ADC value filters
        adcFilteredAdcVal = _ADC_GetSingleReading(_ADC_VS_CH);
        adcFilterSum = (adcFilteredAdcVal << ADC_V_FILTER_SHIFT);
        adcFilteredAdcVal = _ADC_GetSingleReading(_ADC_IS_CH);
        adcFilterSum = (adcFilteredAdcVal << ADC_I_FILTER_SHIFT);
        adcFilteredAdcVal = _ADC_GetSingleReading(_ADC_VB_CH);
        adcFilterSum = (adcFilteredAdcVal << ADC_V_FILTER_SHIFT);
        adcFilteredAdcVal = _ADC_GetSingleReading(_ADC_IB_CH);
        adcFilterSum = (adcFilteredAdcVal << ADC_I_FILTER_SHIFT);
        TIM3_init();
}

// Measurement indices (first 4 must be measured ADC values)
#define ADC_NUM_MEASUREMENTS 6

#define _ADC_VS_CH 4
#define _ADC_IS_CH 2
#define _ADC_VB_CH 3
#define _ADC_IB_CH 1
#define _ADC_TE_CH 6
#define _ADC_TI_CH 5

#define ADC_MEAS_VS_INDEX    (_ADC_VS_CH-1)//0
#define ADC_MEAS_IS_INDEX    (_ADC_IS_CH-1)//1
#define ADC_MEAS_VB_INDEX    (_ADC_VB_CH-1)//2
#define ADC_MEAS_IB_INDEX    (_ADC_IB_CH-1)//3
#define ADC_MEAS_TI_INDEX    (_ADC_TI_CH-1)//4
#define ADC_MEAS_TE_INDEX    (_ADC_TE_CH-1)//5
//
// Low-pass digital filter parameters
//From: https://www.edn.com/design/systems-design/4320010/A-simple-software-lowpass-filter-suits-embedded-system-applications
//
//K      Bandwidth (normalized to 1Hz)   Rise Time (Samples)
//1      0.1197                            3
//2      0.0466                            8
//3      0.0217                            16
//4      0.0104                            34
//5      0.0051                            69
//6      0.0026                            140
//7      0.0012                            280
//8      0.0007                            561
//
#define ADC_V_FILTER_SHIFT3
#define ADC_I_FILTER_SHIFT6

// ADC Interrupt control macros
#define _ADC_DIS_INT() TIM3->CR1&=~(1<<0)
#define _ADC_EN_INT()TIM3->CR1|=(1<<0)

szt1993 发表于 2025-7-31 23:02

适用于嵌入式ADC RC低通滤波
页: [1]
查看完整版本: 适用于嵌入式ADC RC低通滤波