Question
ADC samples get corrupted at end of sampling series
Posted on August 04, 2013 at 13:51
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 whatI am using, but is working and gives the same corrupted data) Here are some sample images: EDITstart: I expanded theADCdata
array to be initialized asADCdata
[7200+160] instead ofADCdata
[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... EDITfinished. 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_ADCCLKConfig(RCC_PCLK2_Div6);
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);
//DMA_ADC_Initialization();
//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);
//ADC_DMACmd(ADC1, ENABLE);
//Enable timer 1 compare as external trigger
//ADC_ExternalTrigConvCmd(ADC1, ENABLE);
//Enable ADC1
ADC_Cmd(ADC1, ENABLE);
/*
//Reset ADC1 calibration register
ADC_ResetCalibration(ADC1);
//Wait until ADC1 reset is done
while(ADC_GetResetCalibrationStatus(ADC1) == SET);
//Start ADC1 calibration
ADC_StartCalibration(ADC1);
//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);
//Base
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;
NVIC_Init(&NVIC_InitStructure);
//Clear timer
TIM_SetCounter(TIM1, 0);
//Interrupt
TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);
}
void TIMER1_Enable(void)
{
//Clear timer
TIM_SetCounter(TIM1, 0);
//Enable timer
TIM_Cmd(TIM1, ENABLE);
}
void TIMER1_Disable(void)
{
//Disable timer
TIM_Cmd(TIM1, DISABLE);
}
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);
j++;
if(j == 7200)
{
TIMER1_Disable();
printf(''_plotEnable\n'');
for(i = 0; i < 7200; i++)
{
printf(''%u, '', (uint16_t) (ADCdata[i] & 0x0FFF));
}
printf(''\n'');
}
//Clear timer 1 compare interrupt
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);
}
void main(void)
{
TIMER1_Enable();
while(TRUE)
{
}
}
#adc-timer-cortexm3