Moin,
> Leider wird im DMA Array immer nur der erste Wert beschrieben.
Was meinst du damit genau?
Hast du den ADC mal per Hand ausgelesen ob die Werte wirklich ankommen?
Die Werte sollen ja ins ADC_BUFF[2] geschrieben werden. Ich
initialisiere das Array mit {10,10}. Der erste Wert ändert sich dann und
der zweite bleibt 10.
Also zumindest der Kanal 8 wird richtig ausgelesen.
Danke für den Hinweis. Habe jetzt das Halfword in Word geändert und nu
läufts korrekt ;-)
Der Name ADC_Buff_NoOfBytes war ein wenig verwirrend, eigentlich ist es
nur die Anzahl der Elemente im enum ;-)
Ma Kra schrieb:> Hallo, mich interessiert, wie schnell die Werte ausgelesen werden> können? Kann man evt. eine Zahl in Samples pro Sekunde ermitteln?> Gruss> MK_Munich
Muß man nicht ermitteln, ist aus dem Datenblatt ersichtlich.
Im STM32F405xx, STM32F407xx Datenblatt stehen in der Tat einige Werte
(siehe Tabelle 65)...
Sie gehen von 2 Msps bis 6 Msps bei fADC = 30 MHz und tS = 3 ADC cycles.
Die 6 Msps werden nur bei 12-bit resolution Interleave Triple ADC mode
erreicht. (Wie auch immer dies geht... Ich muss noch viel lesen.)
Gruss MK_Munich
Sternius schrieb:> Danke für den Hinweis. Habe jetzt das Halfword in Word geändert und nu> läufts korrekt ;-)> Der Name ADC_Buff_NoOfBytes war ein wenig verwirrend, eigentlich ist es> nur die Anzahl der Elemente im enum ;-)
Da Du den DMA2 verwendest, noch ein kleiner Hinweis:
http://www.st.com/st-web-ui/static/active/en/resource/technical/document/errata_sheet/DM00037591.pdf
DMA2 data corruption when managing AHB and APB peripherals in a
concurrent way
Description
When the DMA2 is managing AHB Peripherals (only peripherals embedding
FIFOs) and
also APB transfers in a concurrent way, this generates a data corruption
(multiple DMA
access).STM32F40x and STM32F41x silicon limitations STM32F40x and
STM32F41x
14/38 Doc ID 022183 Rev 4
When this condition occurs:
• The data transferred by the DMA to the AHB peripherals could be
corrupted in case of
a FIFO target.
• For memories, it will result in multiple access (not visible by the
Software) and the data
is not corrupted.
• For the DCMI, a multiple unacknowledged request could be generated,
which implies
an unknown behavior of the DMA.
AHB peripherals embedding FIFO are DCMI, CRYPTO, and HASH. On sales
types without
CRYPTO, only the DCMI is impacted. External FIFO controlled by the FSMC
is also
impacted.
Workaround
Avoid concurrent AHB (DCMI, CRYPTO, HASH, FSMC with external FIFO) and
APB
transfer management using the DMA2.
Hallo alle zusammen, ich habe den Quelltext von fast eins zu eins
übernommen und weiterhin viele weite Beispiele aus dem Internet
ausprobiert aber ich bekomme den DMA nicht zum laufen. Die ADC
Umwandlung funktioniert selbst funktioniert bereits. Es wird aber kein
einziger wert vom DMA übertragen. Hat hier vielleicht noch jemand einen
Hinweis?
Hier der Quelltext:
void init_adc_test(void)
{
/***********************************************************************
*******************************
*Create structures and initalize them [OK]
************************************************************************
******************************/
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_StructInit(&GPIO_InitStructure);
ADC_StructInit(&ADC_InitStructure);
ADC_CommonStructInit(&ADC_CommonInitStructure);
DMA_StructInit(&DMA_InitStructure);
/***********************************************************************
*******************************
* 2.0 Set up the clocks are needed for the ADC [??]
************************************************************************
******************************/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);
/***********************************************************************
*******************************
* 3.0 Initialization of the GPIO Pins [OK]
************************************************************************
******************************/
/* Analog channel 12 configuration : PC.01 PC.02 PC.04 PC.05
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/***********************************************************************
*******************************
* 4.0 Config the ADC1 [OK: Conversation is running (checked the memory
of the data register)]
************************************************************************
******************************/
ADC_DeInit();
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//data
converted will be shifted to right
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//Input voltage
is converted into a 12bit number giving a maximum value of 4096
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //the conversion
is continuous, the input data is converted more than once
ADC_InitStructure.ADC_ExternalTrigConv =
ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_NbrOfConversion = 4;//I think this one is clear
:p
ADC_InitStructure.ADC_ScanConvMode = ENABLE;//The scan is configured
in one channel
ADC_Init(ADC1,&ADC_InitStructure);//Initialize ADC with the previous
configuration
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_TwoSamplingDelay =
ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInitStructure.ADC_DMAAccessMode =
ADC_DMAAccessMode_Disabled;
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_RegularChannelConfig(ADC1,ADC_Channel_11,1,ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1,ADC_Channel_12,2,ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1,ADC_Channel_14,3,ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1,ADC_Channel_15,4,ADC_SampleTime_3Cycles);
ADC_Cmd(ADC1, ENABLE); // Enable ADC1
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE); // Enable ADC1
ADC_SoftwareStartConv(ADC1);
/***********************************************************************
*******************************
* 5.0 Configure the DMA [ERROR: no transport of the values]
************************************************************************
******************************/
//==Configure DMA2 - Stream 4
DMA_DeInit(DMA2_Stream4); //Set DMA registers to default values
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
//Address of peripheral the DMA must map to
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &
ADCConvertedValue; //Variable to which ADC values will be stored
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 4; //Buffer size (4 because we
using two channels)
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_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream4, &DMA_InitStructure); //Initialise the DMA
DMA_Cmd(DMA2_Stream4, ENABLE); //Enable the DMA2 - Stream 0
}
Habe noch einen kleinen Fehler gefunden. Ich hatte vergessen den
foglenden Befehl einzutragen.
ADC_Cmd(ADC1, ENABLE); // Enable ADC1
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
ADC_DMACmd(ADC1, ENABLE); //Enable ADC1 DMA <--Fehlte
ADC_SoftwareStartConv(ADC1);
Jetzt läuft der DMA. Aber es wird nur ein Wert übertragen. Danach hält
der ADC an und es wird kein weiterer Wert konvertiert. Idee?