2013-08-04 04:51 AM
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
2013-08-04 08:52 AM
Unfortunately this looks to be one of those incomplete examples. If you have stuff that doesn't work, don't selectively summarize/editoralize the code to the point where critical detail is lost.
I would probably have done different things in the interrupt, like clearing it on entry after confirming the source. I would have made sure to have bounds tested the index. Doing printf's there and waiting on EOC cause it the dwell in there too long. I don't think this causes the loss of samples. The NVIC priority parameters appear bogus, again not impacting things, but probably something to look harder at. From the example it's not exactly clear, where and what size the buffer actually is.2013-08-04 09:27 AM
You are right, the size of the array is missing (but mentioned in the text), but that is the only thing that I can see. And what I meant about ''stripping'' the code is like you mentioned, I use printf in an interrupt routine, dont use DMA atm because the same corrupted data happend without DMA so it is just useless information, so I stripped it... The code is still fully runnable?