2010-10-12 04:22 AM
hi.
i am trying to activate the adc module with the following program : __IO uint16_t ADCConvertedValue; int main(void) { int temp=0; setsystemclock(); //set system clock to 24Mhz3 //rcc CONFIGURATION RCC->AHBENR=RCC_AHBENR_DMA1EN; //dma clock enable RCC->APB2ENR=RCC_APB2ENR_IOPCEN | RCC_APB2ENR_ADC1EN; //portc and ADC clock enable. //GPIO CONFIGURATION GPIOC->CRL=0x0;// ADC1_IN14 // DMA configuration: DMA1_Channel1->CCR= DMA_CCR1_CIRC | DMA_CCR1_PSIZE_0 | DMA_CCR1_MSIZE_0 | DMA_CCR1_PL_1; //Circular mode,Read from peripheral,Peripheral size 16-bits, Memory size 16-bits, Channel priority level High. DMA1_Channel1->CNDTR=1; //bytes to be transmitted. Check only 1 channel DMA1_Channel1->CPAR = 0x4001244C; //adc address DMA1_Channel1->CMAR=(uint32_t)&ADCConvertedValue; DMA1_Channel1->CCR |= CCR_ENABLE_Set; //ADC configuration ADC1->CR1=ADC_CR1_SCAN; ADC1->CR2=ADC_CR2_ALIGN | ADC_CR2_EXTSEL ; //data align right , software start ADC1->SMPR1=0;// 1.5 cycles conversion time ADC1->SQR3=0; ADC1->SQR1|=ADC_SQR1_SQ14_0; ADC1->CR2 |=ADC_CR1_SCAN ; /* Enable ADC1 DMA */ ADC1->CR2 |=ADC_CR2_ADON; /* Enable ADC1 */ ADC1->CR2 |=ADC_CR2_RSTCAL ;//reset calibration while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0x00); //wait for end of ADC1 reset calibration register ADC1->CR2 |=ADC_CR2_CAL;/* Start ADC1 calibaration */ while((ADC1->CR2 & ADC_CR2_CAL) != 0x00);/* Check the end of ADC1 calibration */ ADC1->CR2 |=ADC_CR2_SWSTART |ADC_CR2_EXTTRIG; /* Start ADC1 Software Conversion */ while(1) { if((ADC1->SR&ADC_SR_EOC)>0) { temp=ADC1->DR; ADC1->CR2 |=ADC_CR2_SWSTART |ADC_CR2_EXTTRIG; /* Start ADC1 Software Conversion */ temp=temp+1; } } } but if i put GND in PC4 which is channel 14 i dont get zero in ADC1->DR. why what am i doing wrong? thanks.2010-10-12 05:44 AM
So, are you using DMA or Polled IO?
2010-10-12 06:24 AM
basicly i am just trying to activate the adc module in diffrent modes.
in this emaple i used the dma for polling the adc but i dont realy need it. as i understand using the dma for polling makes it faster right? any way if i could activate it even with out the DMA it would be great. so what am i doing worg? thanks.2010-10-12 07:46 AM
i found what was wrong the channel selection was wrog as i figure it out the line:
ADC1->SQR3=0xe;//channel number first conversion determines that the first sequnce of conversion will be channel 14 right?2010-10-12 10:14 AM
This also works..
int main(void) { int led, adc; GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStructure; /* Initialise LEDs LD3&LD4, both off */ STM32vldiscovery_LEDInit(LED3); STM32vldiscovery_LEDInit(LED4); led = 0; STM32vldiscovery_LEDOff(LED3); STM32vldiscovery_LEDOff(LED4); /* Enable ADC1 and GPIOC clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE); /* Configure PC.04 (ADC Channel14) as analog input -------------------------*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOC, &GPIO_InitStructure); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channel14 configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5); // ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_1Cycles5); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); /* Start ADC1 Software Conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); while(1) { if (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == SET) { adc = ADC_GetConversionValue(ADC1); /* Probably overkill */ ADC_ClearFlag(ADC1, ADC_FLAG_EOC); /* Start ADC1 Software Conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); led ^= 1; if (led) STM32vldiscovery_LEDOff(LED3); else STM32vldiscovery_LEDOn(LED3); } } /* does not exit - kind of important */ return(adc); }2010-10-13 11:35 PM
hi
thanks for your replay. i noticed that you changed the conversion to 5 cycle why? why would i like to make the adc slower? whats the down side of using the DMA? doesnt it makes it faster?2010-10-14 12:47 AM
> why would i like to make the adc slower?
That depends on the output impedance of what you connect to the ADC. If you meet the requirements from table 42 in the stm32f100x[468B] manual for 1.5 cycles, then go for it.2010-10-14 01:46 AM
2010-10-14 02:26 AM
RAin (the output impedance of the thing you connect to the ADC) must be at most 400 ohms to get correct readings with 1.5 cycles sample time. You can, for example, not connect a 10 kOhm pot directly, but the output from an OP-amp in a buffer configuration is probably OK.
I guess (someone correct me if I'm wrong) it is because the current needed for the conversion have to be delivered very fast for a short sample time.2010-10-14 03:47 AM
hi.
i have aquestion: if i want the measure sevrel channels it the fastest way what are my options and how? thanks.