STM32F4 USART und DMA

Gast #2477958
Lesenswert?
• ▲
▼
Mit USART + DMA kann ich zwar nicht direkt dienen, aber ich hätte mal 
ein Beispiel für ADC + DMA ( daraus sollte man ja auch schon einiges 
lernen können ) mit einem 128-Messwerte-Ringpuffer.
1
/* globale Variable */
2
uint16_t adcBuffer[128];
3

4
/* Initialisierung */
5
  /* DMA Init */
6
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
7
  
8
  DMA_InitTypeDef DMA_InitStruct;
9
  DMA_StructInit(&DMA_InitStruct);
10
  DMA_InitStruct.DMA_Channel = DMA_Channel_0;
11
  DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR);
12
  DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&adcBuffer;
13
  DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;
14
  DMA_InitStruct.DMA_BufferSize = 128;
15
  DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
16
  DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
17
  DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
18
  DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
19
  DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
20
  DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;
21
  DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;
22
  DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
23
  DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
24
  DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
25
  DMA_Init(DMA2_Stream0, &DMA_InitStruct);
26
  DMA_Cmd(DMA2_Stream0, ENABLE);
27
  DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
28

29
  /* DMA Interrupt Init */
30
  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
31
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
32
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
33
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
34
  NVIC_Init(&NVIC_InitStructure);
35
  
36
  /* ADC Init */
37
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
38
  
39
  ADC_CommonInitTypeDef ADC_CommonInitStruct;
40
  ADC_CommonStructInit(&ADC_CommonInitStruct);
41
  ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent;
42
  ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div2;
43
  ADC_CommonInitStruct.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
44
  ADC_CommonInitStruct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
45
  ADC_CommonInit(&ADC_CommonInitStruct);
46
  
47
  ADC_InitTypeDef ADC_InitStruct;
48
  ADC_StructInit(&ADC_InitStruct);
49
  ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
50
  ADC_InitStruct.ADC_ScanConvMode = DISABLE;
51
  ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
52
  ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
53
  ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
54
  ADC_InitStruct.ADC_NbrOfConversion = 1;
55
  ADC_Init(ADC1, &ADC_InitStruct);
56
  
57
  ADC_TempSensorVrefintCmd(ENABLE);
58
  ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_480Cycles);
59
  ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
60
 
61
  ADC_DMACmd(ADC1, ENABLE);
62
  ADC_Cmd(ADC1, ENABLE);
63
  ADC_SoftwareStartConv(ADC1);
64

65
/* Interrupt Handler */
66
  void DMA2_Stream0_IRQHandler(void)
67
  {
68
    /* Hier kann man mit adcBuffer tun, was man will.
69
       Wird alle 128 ADC-Messungen aufgerufen,
70
       nachdem die Ergebnisse von der DMA in adcBuffer geschrieben
71
       wurden. */
72
 
73
    DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
74
  }

Du musst nur im DMA-Abschnitt im Reference Manual den richtigen 
DMA-Channel/Stream für deinen USART finden.
Ansonsten müsstest du nur die Adressen und die DataSizes anpassen, schon 
sollte das bei der USART-Schnittstelle funktionieren.
OP #2478175
Lesenswert?
• ▲
▼
Hallo also ich versuch über usart 3 und dma  stream 3 channel 4 
(richtig?) einen Text auszugeben:


#include "stm32f4xx.h"


void USART3_Init(void);
void DMAStream3_Channel4_Init();

unsigned char buffer[129] = "Hello World, this is a DMA test. If you can 
read this the DMA is still working!\n";

int main(void)
{
  USART3_Init();
  DMAStream3_Channel4_Init();
  USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);
  DMA_Cmd(DMA1_Stream3, ENABLE);
  while(1);
}

void USART3_Init(void)
{
  GPIO_InitTypeDef GPIOC_10_11_InitStructure;
  USART_InitTypeDef USART3_InitStructure;

  //GPIO C 10/11 Init
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

  GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_USART3);

  GPIOC_10_11_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIOC_10_11_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIOC_10_11_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
  GPIOC_10_11_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIOC_10_11_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOC, &GPIOC_10_11_InitStructure);

  //USART 3 Init
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

  USART3_InitStructure.USART_BaudRate = 9600;
  USART3_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART3_InitStructure.USART_StopBits = USART_StopBits_1;
  USART3_InitStructure.USART_Parity = USART_Parity_No;
  USART3_InitStructure.USART_HardwareFlowControl = 
USART_HardwareFlowControl_None;
  USART3_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  USART_Init(USART3, &USART3_InitStructure);
  USART_Cmd(USART3, ENABLE);
}
void DMAStream3_Channel4_Init(void)
{
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);

  DMA_InitTypeDef DMA_InitStruct;
  DMA_StructInit(&DMA_InitStruct);
  DMA_InitStruct.DMA_Channel = DMA_Channel_4;
  DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(USART3->DR);
  DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&buffer;
  DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral;
  DMA_InitStruct.DMA_BufferSize = 129;
  DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStruct.DMA_PeripheralDataSize = 
DMA_PeripheralDataSize_HalfWord;
  DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;
  DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;
  DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA2_Stream3, &DMA_InitStruct);
}

weiß vielleicht jemand was ich falsch mach?

Moritz
Gast #2478197
Lesenswert?
• ▲
▼
Moritz M. schrieb:
> über usart 3 und dma  stream 3 channel 4
> (richtig?)

DMA 1, Stream 3, Channel 4, korrekt. (Alternativ ginge auch DMA 1, 
Stream 4, Channel 7)

Allerdings hast du wohl eine Stelle übersehen:

Moritz M. schrieb:
> DMA_Init(DMA2_Stream3, &DMA_InitStruct);
In der Funktion DMAStream3_Channel4_Init.

Da du Zeichen verschicken willst ( unsigned char ), beträgt deine 
DataSize ( sowohl Memory als auch Peripheral ) nur ein Byte und kein 
Half Word ( 2 Byte ).
Ansonsten habe ich die DMA noch nie für USART TX benutzt, daher kann ich 
nicht mehr dazu sagen.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.