2009-08-21 10:52 PM
AD at higest posible speed with DMA
2011-05-17 04:20 AM
Hi folks, im trying to get the the stm32 to sample at 1M Samples/sec but only getting max the half .... what is wrong ???
I use Timer1 and DMA to trigger Ad converter. The timer is triggering at 1MHz in this config. I have a scope on the OC1 to check with a scope, that im getting triggered at 1MHz. i have a 8MHz Xtal, at the pll multiplier is set to 7 = 56Mhz /f void InitTIM1(void) { TIM_TimeBaseInitTypeDef TIM1_TimeBaseStructure; TIM_OCInitTypeDef TIM1_OCInitStructure; TIM1_TimeBaseStructure.TIM_Prescaler = 0; TIM1_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM1_TimeBaseStructure.TIM_Period = 55; // TIM1_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM1_TimeBaseStructure.TIM_RepetitionCounter = 0x0; TIM_TimeBaseInit(TIM1, &TIM1_TimeBaseStructure); // using a scope to see the frequency ... TIM1_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM1_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM1_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; TIM1_OCInitStructure.TIM_Pulse = 10; TIM1_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC1Init(TIM1,&TIM1_OCInitStructure); // TIM1 counter enable TIM_Cmd(TIM1,ENABLE); // TIM1 main Output Enable TIM_CtrlPWMOutputs(TIM1,ENABLE); } AD Setup... void ADC_init(void) { ADC_InitTypeDef ADC_InitStructure; ADC_DeInit(ADC1); 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_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init( ADC1, &ADC_InitStructure ); // ADC1 Regular Channel 2 Configuration ADC_RegularChannelConfig( ADC1, ADC_Channel_8, 1, ADC_SampleTime_1Cycles5); // Enable ADC1 DMA ADC_DMACmd(ADC1, ENABLE); // Enable ADC1 external trigger ADC_ExternalTrigConvCmd(ADC1, ENABLE); // Enable ADC1 ADC_Cmd(ADC1, ENABLE); } DMA setup : void DMA_init(void) { DMA_InitTypeDef DMA_InitStructure; // Reconfig the DMA channel 1 //DMA_DeInit(DMA1); DMA_DeInit(DMA1_Channel1_BASE ); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ECG_Buff[0]; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = ECG_BUFF_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_Low; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init( DMA1_Channel1_BASE, &DMA_InitStructure ); // Enable DMA Channel1 Transfer half and Complete interrupt // DMA_ITConfig(DMA1_Channel1_BASE, DMA_IT_TC | DMA_IT_HT, ENABLE); DMA_ITConfig(DMA1_Channel1_BASE, DMA_IT_TC , ENABLE); // Enable DMA Channel1 DMA_Cmd( DMA1_Channel1_BASE, ENABLE ); } void RCC_Configuration(void) { RCC_DeInit(); RCC_HSEConfig(RCC_HSE_ON); HSEStartUpStatus = RCC_WaitForHSEStartUp(); if(HSEStartUpStatus == SUCCESS) { FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); FLASH_SetLatency(FLASH_Latency_2); RCC_HCLKConfig(RCC_SYSCLK_Div1); RCC_PCLK2Config(RCC_HCLK_Div1); RCC_PCLK1Config(RCC_HCLK_Div2); RCC_ADCCLKConfig(RCC_PCLK2_Div4); RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_7); RCC_PLLCmd(ENABLE); while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { } RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); while(RCC_GetSYSCLKSource() != 0x08) { } } RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_TIM1 | RCC_APB2Periph_USART1| RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE); }2011-05-17 04:20 AM
Hi,
Try this in your ADC configuration : ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; Hope this helps you Cheers, STOne-32.2011-05-17 04:20 AM
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; Yes that can help a lot ;) But if you start the conversion from within a timer interrupt event like: ADC_SoftwareStartConvCmd(ADC1, ENABLE); and you only want to threat 1 value at the time in the ADC EOC interrupt handler than enabling the ADC_ContinuousConvMode isn't necessary. cheers Guy