2014-09-19 05:56 AM
Good afternoon,
I made a project and i set ADC1 in independent mode and DMA1 to read the information from the adc and then write it to the memory. In the Datasheet and in the Reference manual is writen that the ADC can max. have 4.8 MSPS at slow channel but the DMA cannot transfer the data so fast, so it overflow.... it stop overflow when i set the ADC at 2.4MSPS ... is there a way to set the DMA to transfer data faster so i can use the ADC at 4.8MSPSThanks you.Best Regards!2014-09-19 08:58 AM
The ADC+DMA is demonstrably capable of rates exceeding 5.1 MSps. Perhaps you have an unrealistically small sample buffer? Perhaps your bus clocks are non-optimal?
1000 Samples, High Priority, Circular2014-09-24 12:30 AM
2014-09-24 12:31 AM
Can you please send me a example code for ADC + DMA working on 5.1 Msps or tell me where I can send you mine, so you can check what do i do wrong if it is not a problem ... thank you
2014-09-24 08:14 AM
How you plan to process data at that rate, now that's a whole different kettle of fish...
// STM32 ADC Rapid 5.143 MSps STM32F3-Discovery - sourcer32@gmail.com
// Conversion + Sample time, 5 + 1.5 Cycles = 14
// 72 MHz / 14 = 5.142857 MHz
/**************************************************************************************/
// FAST ADC1_IN1, ADC1_IN2, ADC1_IN3, ADC1_IN4, ADC1_IN5
// SLOW ADC12_IN6, ADC12_IN7, ADC12_IN8, ADC12_IN9, ADC12_IN10
/**************************************************************************************/
#include ''stm32f3_discovery.h''
#include ''stm32f30x.h''
#include <
stdio.h
>
/**************************************************************************************/
#define BUFSIZE 1000
volatile uint16_t ADCConvertedValues[BUFSIZE];
uint16_t CalibrationValue;
/**************************************************************************************/
void ADC_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOA and GPIOB Periph clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
/* ADC Channels configuration */
/* Configure as analog input */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/**************************************************************************************/
void ADC12_DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* DMA configuration */
/* DMA1 Channel1 Init Test */
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; // The register of a singular ADC
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValues[0];
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = BUFSIZE;
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_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure); // ADC1
}
/**************************************************************************************/
void ADC_Configuration(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
volatile int i;
/* Configure the ADC clocks */
RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div1);
/* Enable ADC1/2 clocks */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);
/* ADC GPIO configuration */
ADC_GPIO_Configuration();
/* ADC DMA Channel configuration */
ADC12_DMA_Configuration();
/* ADC Calibration procedure */
ADC_VoltageRegulatorCmd(ADC1, ENABLE);
/* Insert delay equal to 10 µs */
for(i=0; i<
10000
; i++);
ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single);
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1) != RESET);
CalibrationValue
=
ADC_GetCalibrationValue
(ADC1);
/* ADC configuration */
ADC_CommonInitStructure.ADC_Mode
=
ADC_Mode_Independent
;
ADC_CommonInitStructure.ADC_Clock
=
ADC_Clock_AsynClkMode
;
ADC_CommonInitStructure.ADC_DMAAccessMode
=
ADC_DMAAccessMode_Disabled
; // Not Multi Mode
ADC_CommonInitStructure.ADC_DMAMode
=
ADC_DMAMode_Circular
;
ADC_CommonInitStructure.ADC_TwoSamplingDelay
=
10
;
ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
/* */
ADC_InitStructure.ADC_ContinuousConvMode
=
ADC_ContinuousConvMode_Enable
; // Full On
ADC_InitStructure.ADC_Resolution
=
ADC_Resolution_12b
;
ADC_InitStructure.ADC_ExternalTrigEventEdge
=
ADC_ExternalTrigEventEdge_None
;
ADC_InitStructure.ADC_ExternalTrigConvEvent
=
ADC_ExternalTrigConvEvent_3
; // Not used here
ADC_InitStructure.ADC_DataAlign
=
ADC_DataAlign_Right
;
ADC_InitStructure.ADC_OverrunMode
=
ADC_OverrunMode_Disable
;
ADC_InitStructure.ADC_AutoInjMode
=
ADC_AutoInjec_Disable
;
ADC_InitStructure.ADC_NbrOfRegChannel
=
1
;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_1Cycles5); // PA1 - ADC1_IN2
/* Configures the ADC DMA */
ADC_DMAConfig(ADC1, ADC_DMAMode_Circular);
/* Enable the ADC DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* wait for ADC1 ADRDY */
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY));
/* Enable the DMA channel */
DMA_Cmd(DMA1_Channel1, ENABLE);
/* Start ADC1 Software Conversion */
ADC_StartConversion(ADC1);
}
/**************************************************************************************/
void DMA1_Channel1_IRQHandler(void) // 5.143 KHz (1000 Samples at 5.143 MSps)
{
/* Test on DMA1 Channel1 Transfer Complete interrupt */
if (DMA_GetITStatus(DMA1_IT_TC1))
{
/* Clear DMA1 Channel1 Half Transfer, Transfer Complete and Global interrupt pending bits */
DMA_ClearITPendingBit(DMA1_IT_GL1);
STM_EVAL_LEDToggle(LED3); // 2.571 KHz
}
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the DMA1 CH1 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel
=
DMA1_Channel1_IRQn
;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
=
0
;
NVIC_InitStructure.NVIC_IRQChannelSubPriority
=
1
;
NVIC_InitStructure.NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************/
int main(void)
{
/* Initialize LEDs available on STM32F-Discovery board */
STM_EVAL_LEDInit(LED3);
STM_EVAL_LEDInit(LED4);
/* Turn on LD3 */
STM_EVAL_LEDOn(LED3);
STM_EVAL_LEDOn(LED4);
NVIC_Configuration();
ADC_Configuration();
/* Enable DMA1 Channel1 Transfer Complete interrupt */
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
while(1) // Don't want to exit
{
if (ADCConvertedValues[0] != 0xFFFF)
{
printf(''%03X %03X %03
X'', ADCConvertedValues[0], ADCConvertedValues[1], ADCConvertedValues[2]);
ADCConvertedValues[0] = 0xFFFF;
}
}
}
//******************************************************************************
// Rough SWV support in Keil, STM32F3-Discovery, Make SB10 to connect PB3/SWO
//******************************************************************************
#include <rt_misc.h>
#pragma import(__use_no_semihosting_swi)
struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;
int fputc(int ch, FILE *f)
{
ITM_SendChar(ch);
return(ch);
}
int fgetc(FILE *f)
{
char ch;
ch = 1;
return((int)ch);
}
int ferror(FILE *f)
{
/* Your implementation of ferror */
return EOF;
}
void _ttywrch(int ch)
{
ITM_SendChar(ch);
}
void _sys_exit(int return_code)
{
label: goto label; /* endless loop */
}
//******************************************************************************
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d
'', file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
//******************************************************************************
2014-09-25 12:17 AM
2014-09-25 05:37 AM
Thank you very much for your support. I saw where was my mistake and i fixed it. I made it working at dual interleaved mode + DMA with 9Msps. Thank you very much again.
Best regards!2015-08-09 11:55 AM
Hello. Can you share with the full code (via GitHub or so)?