77-UART_DMA-Library (STM32F4)

mit dieser Library wird eine UART im DMA-Mode betrieben (RX und TX)

im H-File muss eingestellt werden welche UART benutzt werden soll und an welchen Pins der CPU sie angeschlossen ist. Und es muss auch die passende Einstellung vom DMA gewählt werden. (im RefManual stehen alle DMA-Streams)

Die Größe vom Puffer für RX und TX wird auch im H-File eingestellt und betrifft das senden und empfangen :

1
2
Sende-Puffer    = UART_DMA.tx_buffer[UART_DMA_TX_BUF_SIZE]
Empfangs-Puffer = UART_DMA.rx_buffer[UART_DMA_RX_BUF_SIZE]

1. Beim senden wird IMMER der komplette TX-Puffer gesendet
(also so viele Bytes wie im H-File als TX-Buffer-Size eingestellt sind)

2. Vor dem senden muss der TX-Puffer mit Daten gefüllt werden
(nach der Initialisierung stehen alle Bytes auf 0×00)

3. Die Empfangs-Funktion liefert erst ein “RX_DMA_READY” wenn so viele Bytes empfangen wurden, wie im H-File als RX-Buffer-Size eingestellt worden ist.

4. Wenn Daten empfangen wurden, stehen sie danach im RX-Puffer

Das senden und empfangen wird per DMA verwaltet. Die Sendefunktion wartet vor dem senden falls notwendig bis der letzte Transfer abgeschlossen ist. Die Empfangsfunktion muss gepollt werden.

im Beispiel wurde die UART so definert :

1
2
UART3 [TX=PC10], [RX=PC11] mit 115200 Baud
DMA1, Channel4, Stream1+3

Voraussetzungen :

1
2
Benutzte Module der CooCox-IDE : GPIO, USART, DMA, MISC
Benutzte Librarys : keine

Enumerationen :

1
2
3
4
5
typedef enum {
  RX_DMA_EMPTY = 0,  // nichts empfangen
  RX_DMA_READY,      // es steht was im Empfangspuffer
  RX_DMA_OVF         // RX-Puffer ueberlauf
}UART_RX_DMA_STATUS_t;

Funktionen :

1
2
3
void UB_Uart_DMA_Init(void);                          // zum init der UART
void UB_Uart_DMA_SendBuffer(void);                    // zum senden per UART
UART_RX_DMA_STATUS_t UB_UART_DMA_ReceiveBuffer(void); // zum empfangen per UART

Beispiel :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//--------------------------------------------------------------
// File     : main.c
// Datum    : 05.03.2014
// Version  : 1.0
// Autor    : UB
// EMail    : mc-4u(@)t-online.de
// Web      : www.mikrocontroller-4u.de
// CPU      : STM32F4
// IDE      : CooCox CoIDE 1.7.4
// GCC      : 4.7 2012q4
// Module   : CMSIS_BOOT, M4_CMSIS_CORE
// Funktion : Demo der UART-DMA Library
// Hinweis  : Diese zwei Files muessen auf 8MHz stehen
//              "cmsis_boot/stm32f4xx.h"
//              "cmsis_boot/system_stm32f4xx.c"
//--------------------------------------------------------------
 
#include "main.h"
#include "stm32_ub_uart_dma.h"
 
int main(void)
{
  uint32_t n;
 
  SystemInit(); // Quarz Einstellungen aktivieren
 
  // init der UART (per DMA)
  UB_Uart_DMA_Init();
 
  // Puffer zum senden füllen
  for(n=0;n<UART_DMA_TX_BUF_SIZE;n++) {
    UART_DMA.tx_buffer[n]=n;
  }
 
  // Daten senden
  UB_Uart_DMA_SendBuffer();
 
  while(1)
  {
    // check ob Daten empfangen wurden
    // Hinweis : die Anzahl muss 50 Bytes sein !!
    if(UB_UART_DMA_ReceiveBuffer()==RX_DMA_READY) {
 
      // empfangene Daten kopieren
      for(n=0;n<UART_DMA_TX_BUF_SIZE;n++) {
        UART_DMA.tx_buffer[n]=UART_DMA.rx_buffer[n];
      }
 
      // Daten als Echo zuruecksenden
      UB_Uart_DMA_SendBuffer();
    }
  }
}

Hier die Library zum Download :

ub_stm32f4_uart_dma_v100

Hier der komplette CooCox-Projektordner zum Download :

Demo_77_UART_DMA


3 Antworten auf 77-UART_DMA-Library (STM32F4)

  1. Endy sagt:

    Hallo Uwe,

    erstmal vielen Dank für deine ganzen Librarys! Ich schreibe momentan meine Bachelorarbeit über ein Thema, wo der STM32F4 zum Einsatz kommt, da ist dies wirklich ein super Einstieg!

    Ich habe mir mal die Library etwas unter die Lupe genommen und frage mich, warum der DMA-Stream bei dem TX-Kanal nach jedem mal senden immer wieder neu initialisiert wird. Muss das so sein und kostet das nicht wertvolle CPU-Zeit, die man doch grade durch die DMA sparen möchte?

    Danke!

    • admin_ub sagt:

      bin mir nicht mehr sicher. vlt um die startadresse wieder zurückzusetzen. aber egal warum…die 20 Zeilen code benötigen weniger Zeit als das senden von einem Bit per UART. aber du kannst ja gerne probieren ob es auch ohne deinit funktioniert.

  2. Endy sagt:

    Ich habe es ausprobiert. Bei mir reicht es, wenn man wieder senden will, einfach den Befehl:
    DMA_Cmd(UART_DMA_TX_STREAM,ENABLE);
    zu setzen. Die Adresse wird auch wieder automatisch auf Anfang gesetzt.

    Liebe Grüße


Wie hat Dir dieser Artikel gefallen?

1 Stern2 Sterne3 Sterne4 Sterne5 Sterne (1 Bewertungen, Durchschnitt: 5,00 von 5)
Loading...

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.