2014-12-04 12:30 PM
hello guys
I am using stm32f103RETI want to use ADC1 in scan modeI do software start conversion in a timer interrupt and I configured DMA to save conversion values to a memory buffermy configuration code is herevoid Volumes_init(uint32_t *volume_buff) // tuning for 0.1 sec interval interruption{ TIM_TimeBaseInitTypeDef TIM_InitStruct; ADC_InitTypeDef ADC_InitStructure; NVIC_InitTypeDef NVIC_InitStruct; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; // Configure ADC_INPUT_PIN as analog input ------------------------------------ VOLUMES_GPIO_RCC_INIT(); GPIO_StructInit( &GPIO_InitStructure ); GPIO_InitStructure.GPIO_Pin = VOLUME1_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init( VOLUME1_GPIO, &GPIO_InitStructure ); GPIO_InitStructure.GPIO_Pin = VOLUME2_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init( VOLUME2_GPIO, &GPIO_InitStructure ); GPIO_InitStructure.GPIO_Pin = VOLUME3_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init( VOLUME3_GPIO, &GPIO_InitStructure ); GPIO_InitStructure.GPIO_Pin = SENSORS_GND_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init( SENSORS_GND_GPIO, &GPIO_InitStructure ); // ADC configuration ---------------------------------------------------------- VOLUMES_ADC_RCC_INIT(); RCC_ADCCLKConfig( RCC_PCLK2_Div6 ); // 72MHz / 6 = 12MHz // must not exceed 14MHz 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 = 3; ADC_RegularChannelConfig( VOLUMES_ADC, ADC_Channel_9, 1, ADC_SampleTime_1Cycles5 ); ADC_RegularChannelConfig( VOLUMES_ADC, ADC_Channel_8, 2, ADC_SampleTime_1Cycles5 ); ADC_RegularChannelConfig( VOLUMES_ADC, ADC_Channel_15, 3, ADC_SampleTime_1Cycles5 ); ADC_DeInit( VOLUMES_ADC ); // Put everything back to power-on defaults ADC_Init( VOLUMES_ADC, &ADC_InitStructure ); ADC_DMACmd( VOLUMES_ADC, ENABLE ); //ADC_ITConfig (VOLUMES_ADC, ADC_IT_EOC, ENABLE); // DMA Configuration -------------------------------------------- VOLUMES_DMA_RCC_INIT(); DMA_DeInit( DMA1_Channel1 ); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(ADC1->DR)); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(volume_buff); DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 3; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init( DMA1_Channel1, &DMA_InitStructure ); DMA_ITConfig( DMA1_Channel1, DMA_IT_TC, ENABLE ); NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); // TIMERS initialization ---------------------------------------- // 36MHz / 4 = 9MHz / 25 = 360KHz / 45 = 8KHz TIMER_VOLUMES_RCC_INIT(); TIM_Cmd( TIMER_VOLUMES, DISABLE ); TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV4; TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_InitStruct.TIM_Period = 100; // it seems that this timer clock is 72MHz!!! TIM_InitStruct.TIM_Prescaler = 18000; TIM_InitStruct.TIM_RepetitionCounter = 0; TIM_TimeBaseInit( TIMER_VOLUMES, &TIM_InitStruct ); TIM_ITConfig( TIMER_VOLUMES, TIM_IT_Update, ENABLE ); NVIC_InitStruct.NVIC_IRQChannel = TIMER_VOLUMES_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); // starting ----------------------------- TIM_TimeBaseInit( TIMER_VOLUMES, &TIM_InitStruct ); DMA_Cmd( VOLUMES_DMA_Channel, ENABLE ); ADC_Cmd( VOLUMES_ADC, ENABLE ); TIM_Cmd( TIMER_VOLUMES, ENABLE ); }and timer software start conversion IRQ handler is void TIMER_VOLUMES_IRQHandler(void){ GPIO_ResetBits (SENSORS_GND_GPIO, SENSORS_GND_GPIO_PIN); ADC_SoftwareStartConvCmd (VOLUMES_ADC, ENABLE); TIM_ClearITPendingBit ( TIMER_VOLUMES, TIM_IT_Update);}and DMA IRQ handler is void DMA1_Channel1_IRQHandler(void){ GPIO_SetBits (SENSORS_GND_GPIO, SENSORS_GND_GPIO_PIN); DMA_ClearITPendingBit (DMA1_IT_GL1);}the buffer is defined asuint32_t vol[3];and the config function is called asVolumes_init( vol );the problem is that, after dma transfer complete interrupt, the data in memory address is not correct and it seems that only a wrong byte is transferred in every dma requst and a byte increment is done afterwardI mean only first element of vol (vol[0]) has value of 3 bytes and its bytes seems to be nonsenseI can't understand what is wrong herecan anyone help me? #stm32-adc-scan-mode-dma2014-12-04 01:44 PM
Would probably be reading the ADC1->DR as a HalfWord
Also be aware that the Timer's Period and Prescaler are written to the device as N-1, so to divide 72 MHz down to 1 MHz you'd set 72-1 or 71 into the Prescaler, not 722014-12-09 09:54 PM
Thanks clive
The problem was that I was using ADC3 but with channels if ADC1-2. It is weird to see such single-byte incrementation at DMA system! anyway if I did wrong, nothing would be guaranteed to work expectedly Also thanks for my timer mistake correction2014-12-09 09:56 PM
Thanks clive
The problem was that I was using ADC3 but with channels of ADC1-2. It is weird to see such single-byte incrementation at DMA system! anyway if I did wrong, nothing would be guaranteed to work expectedly Also thanks for my timer mistake correction