Hallo, ich versuche mit einem STM32F103 einen 4 Kanaligen AD-Wandler in betrieb zu nehmen. Dazu soll der DMA genutz werden. Allerdings habe ich nun das Problem, das nur in ADC_values[0] ein sinnvoller Wert. Sieht hier irgendjemand wo das Problem liegen könnte? #define UEW_24V GPIO_Pin_0 #define UEW_24V_Channel ADC_Channel_0 #define UEW_7V5 GPIO_Pin_1 ///<PA1 ADC12_IN1 #define UEW_7V5_Channel ADC_Channel_1 #define UEW_5V GPIO_Pin_2 ///<PA2 ADC12_IN2 #define UEW_5V_Channel ADC_Channel_2 #define UEW_3V3 GPIO_Pin_3 ///<PA3 ADC12_IN3 #define UEW_3V3_Channel ADC_Channel_3 #define UEW_GPIO_PORT GPIOA ///< Verwendeter Port mit AD-Wandler /** * @brief Auswahl moeglicher AD-wandler Kanaele */ typedef enum { AN_UEW_24V, ///< AD-Wert 24V AN_UEW_7V5, ///< AD-Wert 7,5V AN_UEW_5V, ///< AD-Wert 5V AN_UEW_3V3, ///< AD-Wert 3,3V MAX_ANALOG ///< Anzahl Analoger Eingaenge } analog_t; volatile uint16_t ADC_values[MAX_ANALOG]; ///< Array mit Werten des AD-Wandlers /*********************************************************************** ************ Beginn der Initialisierung *************************************/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ANALOG, ENABLE); RCC_ADCCLKConfig(RCC_PCLK2_Div6); // GPIO Pins für ADC konfigurieren GPIO_InitStructure.GPIO_Pin = UEW_24V | UEW_3V3 | UEW_5V | AN_UEW_7V5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // Analog Mode GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(UEW_GPIO_PORT, &GPIO_InitStructure); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; // ENABLE = Multiple Channels ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = MAX_ANALOG; ADC_Init(ADC1, &ADC_InitStructure); // ADC1 regular channel12 configuration ADC_RegularChannelConfig(ADC1, UEW_24V_Channel, 1, ADC_SampleTime_41Cycles5); ADC_RegularChannelConfig(ADC1, UEW_7V5_Channel, 2, ADC_SampleTime_41Cycles5); ADC_RegularChannelConfig(ADC1, UEW_5V_Channel, 3, ADC_SampleTime_41Cycles5); ADC_RegularChannelConfig(ADC1, UEW_3V3_Channel, 4, ADC_SampleTime_41Cycles5); // Enable ADC1 reset calibration register ADC_ResetCalibration(ADC1); ADC_StartCalibration(ADC1); // Enable ADC1 ADC_Cmd(ADC1, ENABLE); // Enable ADC1 DMA ADC_DMACmd(ADC1, ENABLE); ADC_SoftwareStartConvCmd(ADC1, ENABLE); // DMA Configuration RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // reset DMA channel DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_values; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = MAX_ANALOG; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR; DMA_Init(DMA1_Channel1, &DMA_InitStructure); // Enable DMA1 Channel Transfer Complete interrupt DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); // Enable DMA1 Channel Transfer Complete interrupt DMA_Cmd(DMA1_Channel1, ENABLE); //Enable the DMA1 - Channel1 DMA_Cmd(DMA1_Channel1, ENABLE); //Enable the DMA1 - Channel1
Ohne dass ich mich im Detail mit den einzelnen Funktionen beschäftigt
hatte:
Ich würde mir mal mit den zeitlichen Abhängigkeiten der
DMAEnable, ADCEnable und ADC_SoftwareStartConv Kommandos ansehen.
>Allerdings habe ich nun das Problem, das nur in ADC_values[0] ein >sinnvoller
Wert
WANN stellst Du das fest? Im DMA1 Channel Transfer Complete interrupt?
Ich habe gerade erst mit dem STM32 angefangen und bin daher ncht sicher ob ich noch den NVIC für den DMA zu initialisieren muss. TripTrab schrieb: > WANN stellst Du das fest? Im DMA1 Channel Transfer Complete interrupt? ich habe einen kontinuierlichen Funktionsaufruf alle paar Millisekunden in dem ich den Inhalt des Arrays (ADC_values) prüfe
pegel schrieb: > MAX_ANALOG > > kommt mehrfach vor, aber was steht drin? MAX_ANALOG kommt aus dem folgenden enum. Steht also 4 drin.
1 | typedef enum { |
2 | AN_UEW_24V, ///< AD-Wert 24V |
3 | AN_UEW_7V5, ///< AD-Wert 7,5V |
4 | AN_UEW_5V, ///< AD-Wert 5V |
5 | AN_UEW_3V3, ///< AD-Wert 3,3V |
6 | MAX_ANALOG ///< Anzahl Analoger Eingaenge |
7 | } analog_t; |
Paul schrieb: > enum. Steht also 4 drin Alles klar. Ist das ein fertiges Board oder selbst gemacht? Nicht das PA2 und PA3 für USART benutzt wird.
Es gibt auch ein Beispiel für 3 ADC mit DMA unter: STM32F10x_StdPeriph_Lib_V3.5.0/Project/STM32F10x_StdPeriph_Examples/ADC/ 3ADCs_DMA
>Ich habe gerade erst mit dem STM32 angefangen und bin daher ncht sicher >ob ich noch den NVIC für den DMA zu initialisieren muss. Na selbstverständlich!
was ich nicht ganz verstehe, ist wie das erste element des Arrays richtig beschrieben werden kann. Das wird doch wenn ich das richtig sehe über
1 | DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_values; |
eingeleitet. Was muss ich dem DMA für weitere ANgaben machen ,das er das Array mit den Werten der anderen ADC s füllt?
Das Beispiel unterscheidet sich darin, das hier unterschiedliche ADCs verwendet werden. Ich will ja den ADC1 mit 4 Kanälen betreiben
>Das Beispiel unterscheidet sich darin, das hier unterschiedliche ADCs >verwendet werden. Ich will ja den ADC1 mit 4 Kanälen betreiben Vielleicht trifft das Deinen Geschmack besser: http://www.embedds.com/multichannel-adc-using-dma-on-stm32/
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.