Forum: Mikrocontroller und Digitale Elektronik stm32F103 DMA Uart3 und Uart4 zu tunneln


von Andreas M. (chillymu)


Lesenswert?

Hi Leute

ich habe mal eine Frage.

Ist es im STM32F103 möglich, über DMA Zeichen von UART3 zu bekommen und 
sie direkt, ohne Interrupt, an UART4 zu senden und umgekehrt? Dabei ist 
die Zeichen länge nicht genau definiert.

RX_UART3 --> DMA --> TX_UART4
TX_UART3 <-- DMA <-- RX_UART4

Ich habe gelesen das der DMA Peripheral-to-Peripheral kann.

Ist das vielleicht das was ich suche und hat schon jemand damit 
Erfahrung?


Gruß Andreas

von Bimbo. (Gast)


Lesenswert?

Also bei meinem STM32F4 ist das ohne Probleme möglich.
Der Rest steht im Datenblatt deines Controllers.

von Bernd (Gast)


Lesenswert?

Gemacht habe ich es noch nicht. In der Referenz des STM32F103 (June 2014 
DocID13902 Rev 151/1128 RM0008 Reference manual) steht als Feature:

Peripheral-to-memory and memory-to-peripheral, and 
peripheral-to-peripheral transfers

Sollte also funktionieren.

von Andreas M. (chillymu)


Lesenswert?

Genau Bernd, das habe ich auch gelesen.

Die Frage dabei ist wie genau funktioniert das bzw. was muss ich da wie 
programmieren?
Ich habe mit DMA noch nicht so viel Erfahrung.

von pegel (Gast)


Lesenswert?

Nö.
der F103 hat nur USART1 .. USART3.

von Spongebob (Gast)


Lesenswert?

Andreas M. schrieb:
> Genau Bernd, das habe ich auch gelesen.
>
> Die Frage dabei ist wie genau funktioniert das bzw. was muss ich da wie
> programmieren?
> Ich habe mit DMA noch nicht so viel Erfahrung.

Du hast Riesenglück:
Das steht im Reference Manual! Einfach durchlesen, Register setzen und 
schon läuft es.
Und das Beste: Dabei bekommst Du automatisch die Erfahrung!

von Spongebob (Gast)


Lesenswert?

pegel schrieb:
> Nö.
> der F103 hat nur USART1 .. USART3.

Er hat nach UART gefragt.
Also korrekte Antwort:
Er hat je nach Modell USART1..3 und UART4..5.

von Gerd E. (robberknight)


Lesenswert?

Andreas M. schrieb:
> Dabei ist
> die Zeichen länge nicht genau definiert.

das macht es schwierig.

Denn beim DMA musst Du immer genau angeben wieviele Bytes transferiert 
werden sollen.

Wenn dauerhaft einfach alles kopiert werden soll, wäre zu fragen warum 
Du nicht einfach die entsprechenden Pins direkt miteinander verbindest 
und den Controller ganz außen vor lässt.

von Alex D. (daum)


Lesenswert?

Gerd E. schrieb:
> Denn beim DMA musst Du immer genau angeben wieviele Bytes transferiert
> werden sollen.

Man kann den DMA auch auf Continuous mode stellen, wenn kein die 
Register bzw Speicherstellen immer die gleichen bleiben, ist dann auch 
die eingestellte Länge egal, der fängt danach einfach wieder von vorne 
an.

von Andreas M. (chillymu)


Lesenswert?

Also langsam.
1. Ja, mein STM32F103RE hat 5 UART-Schnittstellen.
2. Das mit dem direkten Verbinden geht nicht mehr da die Leiterplatte 
schon fertig ist.

SpongeBob: ich werde das mal anschauen mit dem Reference Manual.

von tgdfgdf (Gast)


Lesenswert?

dann setz den auf bytetransfer
dann wird jedes byte einzeln durchgeschubst
lass den NVIC aus dann kommt auch kein interrupt

von Andreas M. (chillymu)


Angehängte Dateien:

Lesenswert?

Hi Leute,

ich habe mir das reference Manual jetzt mal angeschaut aber so richtig 
werde ich nicht daraus schlau.

Ich arbeite mit der Standardbibliothek und habe den UART eingebunden, 
die GPIOs gesetzt und den NVIC ausgeschaltet.
Wie mache ich das jetzt mit dem DMA? Ich finde den bytetransfer auch 
nirgends.

1
unsigned char sys_uart_init_dma_uart1()
2
{
3
  GPIO_InitTypeDef GPIO_InitStructure;
4
  DMA_InitTypeDef DMA_InitStructure;
5
  USART_InitTypeDef USART_InitStructure;
6
  NVIC_InitTypeDef NVIC_InitStructure;
7
  
8
  // Baudrate einstellen
9
  USART_InitStructure.USART_BaudRate = 115200;
10
  // Anzahl an DatenBits einstellen
11
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
12
  // Parität einstellen
13
  USART_InitStructure.USART_Parity = USART_Parity_No;
14
  // StopBits einstellen
15
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
16
  // Flusssteuerng einstellen
17
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
18
  // Richtung der Schnittstelle einstellen
19
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
20
21
  USART_Init(USART1, &USART_InitStructure);
22
  USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
23
  USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
24
  USART_Cmd(USART1, ENABLE);
25
26
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
27
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);  // Periph clock enable
28
  
29
  // PINs konfigurieren
30
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
31
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;        //Txx
32
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
33
  GPIO_Init(GPIOA, &GPIO_InitStructure);
34
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;        //Rxx
35
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
36
  GPIO_Init(GPIOA, &GPIO_InitStructure);
37
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;        //CTS
38
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
39
  GPIO_Init(GPIOA, &GPIO_InitStructure);
40
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;        //RTS
41
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
42
  GPIO_Init(GPIOA, &GPIO_InitStructure);
43
44
  // Interuppt ausschlaten
45
  NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
46
  NVIC_Init(&NVIC_InitStructure);
47
  
48
  // DMA konfigurieren
49
  DMA_InitStructure.DMA_BufferSize = 0;
50
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
51
  DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
52
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DMA_UART_Buffer;
53
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
54
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
55
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
56
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART3;
57
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
58
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
59
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
60
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
61
62
  DMA_Cmd(DMA1_Channel1, ENABLE);
63
64
65
  return 0;
66
}

von Beo Bachta (Gast)


Lesenswert?

Grob drübergeflogen vermute ich dass du noch folgendes
berückschtigen musst:

- du brauchst zwei DMA Kanäle, je einen für Rx und Tx
- die Quell- bzw Ziel-Adresse des DMA-Memory muss dein
jeweiliges Rx- und TX-Register sein.
- der Funktionsaufruf DMA_Cmd (..) startet bereits DMA so
wie du DMA vorhergehend konfiguriert hast.

von Andreas M. (chillymu)


Lesenswert?

Ich habe jetzt mal was hinzugefügt. Aber woher weiß jetzt der DMA das 
der alles was am UART1 ankommt an UART 2 geschickt werden soll und 
umgedreht?
1
// DMA UART1_RX konfigurieren
2
  DMA_InitStructure.DMA_BufferSize = 0;
3
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
4
  DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
5
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DMA_UART_RX_Buffer;
6
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
7
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
8
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
9
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
10
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
11
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
12
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
13
  DMA_Init(DMA1_Channel5, &DMA_InitStructure);
14
15
  // DMA UART1_TX konfigurieren
16
  DMA_InitStructure.DMA_BufferSize = 0;
17
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
18
  DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
19
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DMA_UART_TX_Buffer;
20
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
21
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
22
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
23
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
24
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
25
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
26
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
27
  DMA_Init(DMA1_Channel4, &DMA_InitStructure);
28
  
29
  
30
  DMA_Cmd(DMA1_Channel4, ENABLE);
31
  DMA_Cmd(DMA1_Channel5, ENABLE);

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.