AnsweredAssumed Answered

ADC samples get corrupted at end of sampling series

Question asked by Phataas on Aug 4, 2013
Latest reply on Aug 4, 2013 by Phataas
MCU: Cortex M3, STM32F103VC

I am using a DDS to generate a constant sinusoidal wave. I am sampling this wave and the last 160 samples are almost all garbage. No matter if I sample 7000 samples or 360, the last 160 is way off. I have ruled out that DDS is the problem by sampling the MCU 3V3 pin and it still gives error on the last 160 samples.

I was wondering if anyone else have had similar problem or see any error in my code?

(code shown below are a simplified/shortcut version of what I am using, but is working and gives the same corrupted data)

Here are some sample images:

I expanded the ADCdata array to be initialized as ADCdata[7200+160] instead of ADCdata[7200] when sampling 7200 and I did not get corrupted data. This might mean the the ADC is not the one corrupting the data but something else? Don't see what it can be though...


Here are relevant code:

void ADC_Initialization(void)
    GPIO_InitTypeDef GPIO_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;
    //ADC clk = APB2 clk / 6 = 72MHz/6 = 12MHz. MAX 14MHz.
    RCC_APB2PeriphClockCmd( (RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC) , ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    //ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    //ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    ADC_Init(ADC1, &ADC_InitStructure);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_7Cycles5);
    //Enable timer 1 compare as external trigger
    //ADC_ExternalTrigConvCmd(ADC1, ENABLE);
    //Enable ADC1
    ADC_Cmd(ADC1, ENABLE);
    //Reset ADC1 calibration register
    //Wait until ADC1 reset is done
    while(ADC_GetResetCalibrationStatus(ADC1) == SET);
    //Start ADC1 calibration
    //Wait until ADC1 calibration is done
    while(ADC_GetCalibrationStatus(ADC1) == SET);
    //DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
void TIMER1_Init(void)
    NVIC_InitTypeDef NVIC_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    //Enable Timer 2 clock
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period = 60167;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
    TIM_ARRPreloadConfig(TIM1, ENABLE);
    //Register with Nested Vectored Interrupt Controller (NVIC).
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0B;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0B;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    //Clear timer
    TIM_SetCounter(TIM1, 0);
void TIMER1_Enable(void)
    //Clear timer
    TIM_SetCounter(TIM1, 0);
    //Enable timer
    TIM_Cmd(TIM1, ENABLE);
void TIMER1_Disable(void)
    //Disable timer
void TIM1_CC_IRQHandler(void)
    uint16_t i;
    static uint16_t j = 0;
    LED(LED1, ON);
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    while( !ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) );
    ADCdata[j] = ADC_GetConversionValue(ADC1);
    if(j == 7200)
        for(i = 0; i < 7200; i++)
            printf("%u, ", (uint16_t) (ADCdata[i] & 0x0FFF));
    //Clear timer 1 compare interrupt
    TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);
void main(void)