Hallo zusammen, ich kann ich Datanblatt und der CMSIS Lib nicht nachvollziehen, wie man einen GPIO-Pin eines beliebigen Ports mit einem ADC-Kanal verbindet. Gibt es eine feste Zuordnung, dass bestimmte Pins nur mit bestimmten Kanälen funktionieren? Hier mein Beispielcode: /* enable ADC1 clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE); /* GPIOA: ADC Channel 0, 1, 2, 3 as analog input * Ch 3 -> Battery Voltage * Ch 4 -> Current * Ch 5 -> Temperature */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure ADC1 */ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 0; ADC_Init(ADC1, &ADC_InitStructure); ADC_InjectedSequencerLengthConfig(ADC1, 3); ADC_InjectedChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_239Cycles5); ADC_InjectedChannelConfig(ADC1, ADC_Channel_12, 2, ADC_SampleTime_239Cycles5); ADC_InjectedChannelConfig(ADC1, ADC_Channel_13, 3, ADC_SampleTime_239Cycles5); /* ADC1 injected external trigger configuration */ ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None); Mir fehlt praktisch das Verständnis, welches Pin sich hinter den Kanalen "andockt". ADC_InjectedChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_239Cycles5); ADC_InjectedChannelConfig(ADC1, ADC_Channel_12, 2, ADC_SampleTime_239Cycles5); ADC_InjectedChannelConfig(ADC1, ADC_Channel_13, 3, ADC_SampleTime_239Cycles5); vielen Dank für eure Unterstützung! Ulf
Du hast die wichtigste Angabe vergessen: Welcher Cortex M3?
Ein STM32F1xx würde ich mal sagen. Aber wer das am Code nicht erkennt wird die Frage kaum beantworten können ;) Die Pinzuordnung steht im Datenblatt (nicht das "Reference Manual") unter "Pinouts and pin assignment". Beim STM32F100 ist das Kapitel 3. Such mal nach z. B. "ADC1_IN4". Interessant an dieser "Peripherial Lib" finde ich das jeder STM32 Fan sie einerseits lobt (leichter Einstieg usw.), sie andererseits aber kaum verwendet wird. So ist zumindest mein Eindruck.
Welcher Pin zu welchen Kanälen gehört findet man im Datasheet: ADC_Channel_11: PC1 ADC_Channel_12: PC2 ADC_Channel_13: PC3 Hinter PA3/4/5 stecken ADC_Channel_3/4/5 Datasheet Seite 27: http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00220364.pdf Du hast also die Falschen kanäle eingelesen/die Falschen pins Konfiguriert. btw. Ein grauenhaftes Datenblatt/User Manual...Sehr unübersichtlich und die Pin Configuration ist im User Manual gar nicht zu finden. Zumindest habe ich sie nicht gefunden.
Ulf schrieb: > ich kann ich Datanblatt und der CMSIS Lib nicht nachvollziehen, wie man > einen GPIO-Pin eines beliebigen Ports mit einem ADC-Kanal verbindet. Soweit mir erinnerlich tut man das überhaupt nicht, das hat ST für dich schon erledigt. Nur eben nicht "beliebig", sondern ein bestimmter ADC-Kanal sitzt auf einem bestimmten Portpin.
Antwort schrieb: > btw. Ein grauenhaftes Datenblatt/User Manual...Sehr unübersichtlich und > die Pin Configuration ist im User Manual gar nicht zu finden. Zumindest > habe ich sie nicht gefunden. Apropos übersichtlich: Seit sie die Webseite neu definiert haben finde ich nicht einmal mehr die Datasheets wieder. In der Reference können die Pinout allerdings auch nicht drinstehen, die sind immerhin modellspezifisch. Man muss schon einiges virtuelle Papier zusammenkratzen um die ganze Doku zu haben: Reference, Datasheet, Programming Manual und das vom Cortex.
A. K. schrieb: > Apropos übersichtlich: Seit sie die Webseite neu definiert haben finde > ich nicht einmal mehr die Datasheets wieder. In der Reference können die > Pinout allerdings auch nicht drinstehen, die sind immerhin > modellspezifisch. > > Man muss schon einiges virtuelle Papier zusammenkratzen um die ganze > Doku zu haben: Reference, Datasheet, Programming Manual und das vom > Cortex. Hm, also die Aufteilung gefällt mir überhaupt nicht. Da Lobe ich mir die User Manuals von NXP/Atmel. Da steht immer alles in einem Dokument und ist auch auf der Seite elicht zu finden. Aber das hat mit dem Problem des Thread-Autors nichts zu tuen. Daher würde ich diese Absschweifung gerne an dieser Stelle beenden und zum eigentlich Problem zurückkehren.
Leute! Super geil! Ich bin auch total am verzweifeln mit diesem - tschuldigung - DRECKS-MANUAL. Jeder Atmega hat ein bessere Doc. Bin bisher mit der Doku von Freescale (S12X...) ganz gut ausgekommen und kann mich mit der von ST nich anfreunden. Vielen lieben Dank und einen schönen Abend euch. Ulf
P.S.: der Oberwitz ist ja, dass dieses im Vergleich zum "Reference Manual" sehr sinnvolle Dokument nicht mal einen anständigen Namen hat, sodass man es chance hätte es wieder zu finden. Ich muss es jetzt unter "STM32F107xx.pdf" speichern... ---> Und die Hompepage von ST ist an Unübersichtlichkeit kaum zu übertreffen. Grauenhaft. bye
So, jetzt habe ich meine ganzen ADC Einstellungen hinter mir. Mein System zur Motorsteuerung hat ein Shunt, an dem ich zweimal pro PWM zyklus per Injection die Spannung messen möchte, und 5 weitere Kanäle, die einfach im autoscan-mode gewandelt werden sollten. Die Injections starte ich ja per Software durch den Befehl: ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE); Bekomme ich dann sofort nach Ende der ersten Conversion einen Interrupt, oder erst wenn beide Messungen durch sind? Ich habe gelesen, dass man den DMA-Controller nutzen muss... stimmt das? Muss ich da aktiv was machen oder ist dieser per default aktiv? mein ADC-Interrupt sieht im Moment so aus: ADC_ClearFlag(ADC1, ADC_FLAG_JEOC); Shunt_Messung1 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1); Shunt_Messung2 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_2); Bei der regular channels muss ich doch bestimmt noch ein paar Befehle ausführen um die Conversion zu starten, oder? Und wie mache ich den Zugriff auf die kontinuierlich gewandelten Messwerte? Würde diese gerne im Pollingmodus abholen. Anbei aktueller Code zur Initialisierung der ADC Kanäle nach dem Studium des "guten" Dokuments... /* Configure ADC */ /* enable ADC1 clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE); /* ADC Channel Mapping Port A Pin A1: Onboard Poti --> ADC Channel 1 Pin A3: U_Shunt --> ADC Channel 3 Pin A6: U_DC_BUS --> ADC Channel 6 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* ADC Channel Mapping Port B Pin B0: Current Phase A --> ADC Channel 8 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); /* ADC Channel Mapping Port C Pin C4: Temperature LOW SIDE --> ADC Channel 14 Pin C5: Current Phase B --> ADC Channel 15 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); /* Configure ADC1 */ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 5; ADC_Init(ADC1, &ADC_InitStructure); ADC_InjectedSequencerLengthConfig(ADC1, 2); ADC_InjectedChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_7Cycles5); ADC_InjectedChannelConfig(ADC1, ADC_Channel_3, 2, ADC_SampleTime_7Cycles5); /* ADC1 injected external trigger configuration */ ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None); /* Enable ADC1 JEOC interrupt */ ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration */ while (ADC_GetResetCalibrationStatus(ADC1) == SET) ; /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while (ADC_GetCalibrationStatus(ADC1) == SET) ; /* Start ADC1 Software Conversion */ ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* Enable the ADC Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); Danke für die Mithilfe und guten Abend!
Hallo ich muss diesen Beitrag nochmal aufgreiben weil mir eine sache nicht klar ist. Mit der Konfiguration:
1 | ADC_InjectedChannelConfig(ADC1, ADC_FB_VOLTAGE, 1, |
2 | ADC_SampleTime_7Cycles5); |
3 | ADC_InjectedChannelConfig(ADC1, ADC_BAT_VOLTAGE, 2, |
4 | ADC_SampleTime_7Cycles5); |
In diesem Abschnitt werden die InjectedChannel konfiguriert. Bekommt man mit dem Befehl,
1 | ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1); |
dann den Wert von "ADC_FB_VOLTAGE" oder von dem ADC_Channel_1 ? Also bezieht sich der Index der InjectedChannel auf das Ranking der CHannels oder muss man das noch irgendwo mappen?
Hallo, also meines Wissen nach funktioniert das so wie du es beschrieben hast also mit:
1 | ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1); |
bekommst du denn Wert von ADC_FB_VOLTAGE. Allerdings habe ich auch eine Frage zu: Ulf schrieb: > ADC_InjectedChannelConfig(ADC1, ADC_Channel_3, 1, > ADC_SampleTime_7Cycles5); > ADC_InjectedChannelConfig(ADC1, ADC_Channel_3, 2, > ADC_SampleTime_7Cycles5); Funktioniert das bei dir wenn du zwei InjectedChannel auf den gleichen ADC_Channel definiert? Bei mir funktioniert die Messung zwar, allerdings bekomme ich dann immer Ergebnisse die sehr nahe beieinander liegen obwohl sie völlig verschieden sein sollten. Und da nirgends definitiv steh ob das geht oder nicht bin ich mir unsicher. Vielen Dank für die Hilfe und viele Grüße Michael
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.