Hallo Ich versuche immer grad auch das was im Manual drin steht zu verstehen. Wenn das Peripheral size vom ADC immer 16bit ist und das PSIZE daher 16 bit lang (bits -> 01) ist, was muss ich dann im Register DMA_CPARx laut Punkt 1 unten tun? Ich meine, klar, dass ich eine Adresse angeben muss, aber in welchem Bereich kann ich die Adresse angeben und was ist, wenn ich nichts angebe. Welche Adresse wird dann verwendet? (Nucleo stm32l476rg) 11.5.5 DMA channel x peripheral address register (DMA_CPARx) (x = 1..7, where x = channel number) Address offset: 0x10 + 0d20 × (channel The following sequence should be followed to configure a DMA channel x (where x is the channel number). 1. Set the peripheral register address in the DMA_CPARx register. The data will be moved from/ to this address to/ from the memory after the peripheral event. 2. Set the memory address in the DMA_CMARx register. The data will be written to or read from this memory after the peripheral event. 3. Configure the total number of data to be transferred in the DMA_CNDTRx register. After each peripheral event, this value will be decremented. 4. Configure the channel priority using the PL[1:0] bits in the DMA_CCRx register 5. Configure data transfer direction, circular mode, peripheral & memory incremented mode, peripheral & memory data size, and interrupt after half and/or full transfer in the DMA_CCRx register 6. Activate the channel by setting the ENABLE bit in the DMA_CCRx register.
:
Bearbeitet durch User
CPAR = Channel Peripheral Address Register Wie wärs mit der Adresse des ADC Data Register? Da gibts keinen Bereich, entweder du gibst dem Ding die Adresse des ADC oder eben nicht. Schreibst du nichts rein, dann steht da vermutlich 0x0 drin, was dann wohl der Resetvektor ist... Der DMA Controller ist ein nützlicher Helfer, aber kein sehr schlauer. Du wirst ihm immer sagen müssen: - von WO (Peripherie) - nach WO (Speicher) - "implizit in welche Richtung" (DIR bit) - wie VIEL (x Messungen) - das wie VIEL in welchen STÜCKEN (8 16 32) - WANN (Trigger)
Danke, verstanden ;) Ich nehme an das ist die Adresse des ADC Datenregisters, wo auch die konvertierten Daten immer liegen, die ich angeben muss oder? Dann ist die Adresse, die ich angeben muss folgende: 0x5004 0000 + 0x40 ? 0x5004 0000 - 0x5004 03FF 1 KB ADC Section 16.7.4: ADC register map 16.6.15 ADC regular Data Register (ADCx_DR) Address offset: 0x40
Ja, sollte aber via vom Hersteller bereit gestellten Header ansprechbar sein... Kein Mensch merkt sich Register-Adressen.
Vincent H. schrieb: > Ja, sollte aber via vom Hersteller bereit gestellten Header ansprechbar > sein... Kein Mensch merkt sich Register-Adressen. Stimmt, aber in welchem Header? Es gibt ja tausend header-files :( Als Anfänger bin ich ein wenig aufgeschmissen. Edit folgendermassen: #define ADC1 ((ADC_TypeDef *) ADC1_BASE) aber wo das ADC1_DR liegt, finde ich nicht..
:
Bearbeitet durch User
Das (ADC_TypeDef*) ist ein Zeiger auf einen Typen, der wiederum ein Synonym für eine Struct ist, in der sich ein Element ADC1_DR befindet. Diese Struktur - an die richtige Adresse gelegt - überlagert dann die Register mit ihren Membern, so dass alles zusammenpasst. Die Adresse von ADC1_DR ist dann ADC1_BASE + offsetof(ADC_TypeDef, ADC1_DR). Heißt dann konkret, dass "ADC1->ADC1_DR" auf das richtige Register verweist.
S. R. schrieb: > Das (ADC_TypeDef*) ist ein Zeiger auf einen Typen, der wiederum > ein Synonym für eine Struct ist, in der sich ein Element ADC1_DR > befindet. Diese Struktur - an die richtige Adresse gelegt - überlagert > dann die Register mit ihren Membern, so dass alles zusammenpasst. > > Die Adresse von ADC1_DR ist dann ADC1_BASE + offsetof(ADC_TypeDef, > ADC1_DR). > > Heißt dann konkret, dass "ADC1->ADC1_DR" auf das richtige Register > verweist. Heißt das dann dass ich nun das DMA_CPAR1 = ADC1->ADC1_DR; setzen muss?
D.I schrieb: > S. R. schrieb: >> Das (ADC_TypeDef*) ist ein Zeiger auf einen Typen, der wiederum >> ein Synonym für eine Struct ist, in der sich ein Element ADC1_DR >> befindet. Diese Struktur - an die richtige Adresse gelegt - überlagert >> dann die Register mit ihren Membern, so dass alles zusammenpasst. >> >> Die Adresse von ADC1_DR ist dann ADC1_BASE + offsetof(ADC_TypeDef, >> ADC1_DR). >> >> Heißt dann konkret, dass "ADC1->ADC1_DR" auf das richtige Register >> verweist. > > Heißt das dann dass ich nun das DMA_CPAR1 = ADC1->ADC1_DR; setzen muss? Ich muss gestern wohl besoffen gewesen sein. so natürlich: DMA1_Channel1->CPAR = ADC1->DR; Dann sollte doch die Adresse drin stehen, richtig? Was bei mir noch einen grössere Frage ist, ist welche Adresse ich beim Speicher (memory) wähle.
D. I. schrieb: > DMA1_Channel1->CPAR = ADC1->DR; > Dann sollte doch die Adresse drin stehen, richtig? Nö. Dann steht da nicht die Adresse von ADC1->DR drin. Lies mal ein C-Buch, Kapitel über Pointer.
Jim M. schrieb: > D. I. schrieb: >> DMA1_Channel1->CPAR = ADC1->DR; >> Dann sollte doch die Adresse drin stehen, richtig? > > Nö. Dann steht da nicht die Adresse von ADC1->DR drin. Lies mal ein > C-Buch, Kapitel über Pointer. Dann so :) : DMA1_Channel1->CPAR = (uint32_t)&(ADC1->DR);
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.