Forum: Mikrocontroller und Digitale Elektronik Peripheral size 16bit


von D. I. (Firma: Fa) (buell)


Lesenswert?

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
von Vincent H. (vinci)


Lesenswert?

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)

von D. I. (Firma: Fa) (buell)


Lesenswert?

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

von Vincent H. (vinci)


Lesenswert?

Ja, sollte aber via vom Hersteller bereit gestellten Header ansprechbar 
sein... Kein Mensch merkt sich Register-Adressen.

von D. I. (Firma: Fa) (buell)


Lesenswert?

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
von S. R. (svenska)


Lesenswert?

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.

von D.I (Gast)


Lesenswert?

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?

von D. I. (Firma: Fa) (buell)


Lesenswert?

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.

von Jim M. (turboj)


Lesenswert?

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.

von D. I. (Firma: Fa) (buell)


Lesenswert?

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
Noch kein Account? Hier anmelden.