Forum: Mikrocontroller und Digitale Elektronik USART+DMA STM32F3


von Stm M. (stmfresser)


Lesenswert?

Hallo!

ich versuche USART über DMA auf STM32F303 Discovery Board hinzukriegen.

ich habe ein Beispiel genohmen. 
Beitrag "STM32F4 USART und DMA"

Beim Kompilieren habe ich keine Fehlermeldung. Leider sendet der µCont. 
keine Daten. Ich weiss nicht genau, wo ich Fehler gemacht habe.
hier ist die code.
1
 
2
/*  Systemtakt = 72000000  AHB Prescaler */
3
// init.c
4
/*===================================================*/
5
#include "init.h"
6
void RCC_Enable(void);
7
void init_all(void);
8
void USART2_Config(void);
9
void DMA2_Config(void);
10
/*===================================================*/
11
12
GPIO_InitTypeDef GPIO_InitStructure;
13
USART_InitTypeDef USART_Initialisation;
14
DMA_InitTypeDef   DMA_InitStructure;
15
16
extern unsigned char  buffer[129];
17
18
void RCC_Enable(void){
19
    /* Enable GPIO clock */
20
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
21
    /* Enable USART clock */
22
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
23
    /* Enable DMA2 clock -------------------------------------------------------*/
24
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
25
26
}
27
28
void init_all(void) {
29
    /*===================================================*/
30
    RCC_Enable();
31
    /* USART2 initialisieren PA2=TX PA3=RX*/
32
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_7);
33
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_7);
34
35
    /* Configure USART Tx as alternate function push-pull */
36
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
37
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
38
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
39
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
40
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
41
    GPIO_Init(GPIOA, &GPIO_InitStructure);
42
43
    USART2_Config();
44
    DMA2_Config();
45
    USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
46
        /* Enable DMA2 Channel3 */
47
    DMA_Cmd(DMA2_Channel3, ENABLE);
48
}
49
50
void USART2_Config(void){
51
    USART_Initialisation.USART_BaudRate = 9600;
52
    USART_Initialisation.USART_WordLength = USART_WordLength_8b;
53
    USART_Initialisation.USART_StopBits = USART_StopBits_1;
54
    USART_Initialisation.USART_Parity = USART_Parity_No;
55
    USART_Initialisation.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
56
    USART_Initialisation.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
57
    /* USART configuration */
58
    USART_Init(USART2, &USART_Initialisation);
59
    /* Enable USART */
60
    USART_Cmd(USART2, ENABLE);
61
}
62
void DMA2_Config(void){
63
    DMA_DeInit(DMA2_Channel3);
64
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(USART2->TDR);
65
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&buffer;
66
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
67
    DMA_InitStructure.DMA_BufferSize = 129;
68
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
69
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
70
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
71
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
72
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
73
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
74
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
75
    DMA_Init(DMA2_Channel3, &DMA_InitStructure);
76
}

Im init.c wird die ganze erstmal konfiguriert, im main.c wird init_all() 
aufgerufen.
1
 
2
#ifndef INIT_H
3
#define INIT_H
4
5
void init_all(void);
6
7
#endif /* INIT_H*/

main.c
1
#include "stm32f30x.h"
2
#include "stm32f3_discovery.h"
3
#include "init.h"
4
/* Private variables ---------------------------------------------------------*/
5
  RCC_ClocksTypeDef RCC_Clocks;
6
__IO uint32_t TimingDelay = 0;
7
8
/* Private function prototypes -----------------------------------------------*/
9
void TimingDelay_Decrement(void);
10
void Delay(__IO uint32_t nTime);
11
12
unsigned char buffer[129] = {"Hello World! \n"};
13
/* Private functions ---------------------------------------------------------*/
14
15
/**
16
  * @brief  This function handles SysTick Handler.
17
  * @param  None
18
  * @retval None
19
  */
20
void SysTick_Handler(void)
21
{
22
  TimingDelay_Decrement();
23
}
24
25
/**
26
  * @brief  Main program.
27
  * @param  None 
28
  * @retval None
29
  */
30
int main(void)
31
{  
32
  /* SysTick end of count event each 10ms */
33
  RCC_GetClocksFreq(&RCC_Clocks);
34
  SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);
35
  
36
  /* Initialize LEDs and User Button available on STM32F3-Discovery board */
37
  STM_EVAL_LEDInit(LED3);
38
  STM_EVAL_LEDInit(LED4);
39
  STM_EVAL_LEDInit(LED5);
40
  STM_EVAL_LEDInit(LED6);
41
  STM_EVAL_LEDInit(LED7);
42
  STM_EVAL_LEDInit(LED8);
43
  STM_EVAL_LEDInit(LED9);
44
  STM_EVAL_LEDInit(LED10);
45
  
46
  init_all();
47
  /* Infinite loop */
48
  while (1)
49
  {   
50
    /* LEDs Off */
51
    STM_EVAL_LEDOff(LED3);
52
    STM_EVAL_LEDOff(LED6);
53
    STM_EVAL_LEDOff(LED7);
54
    STM_EVAL_LEDOff(LED4);
55
    STM_EVAL_LEDOff(LED10);
56
    STM_EVAL_LEDOff(LED8);
57
    STM_EVAL_LEDOff(LED9);
58
    STM_EVAL_LEDOff(LED5);
59
    
60
    GPIO_ResetBits(GPIOE, GPIO_Pin_14); 
61
    GPIO_ResetBits(GPIOE, GPIO_Pin_15); 
62
    
63
    Delay(100); /*500ms - half second*/
64
    
65
    /* LEDs Off */
66
    STM_EVAL_LEDOn(LED3);
67
    STM_EVAL_LEDOn(LED6);
68
    STM_EVAL_LEDOn(LED7);
69
    STM_EVAL_LEDOn(LED4);
70
    STM_EVAL_LEDOn(LED10);
71
    STM_EVAL_LEDOn(LED8);
72
    STM_EVAL_LEDOn(LED9);
73
    STM_EVAL_LEDOn(LED5);
74
75
    //GPIO_SetBits(GPIOE, GPIO_Pin_14); 
76
    //GPIO_SetBits(GPIOE, GPIO_Pin_15); 
77
    
78
    Delay(100); /*500ms - half second*/
79
  }
80
}
81
/**
82
  * @brief  Inserts a delay time.
83
  * @param  nTime: specifies the delay time length, in 10 ms.
84
  * @retval None
85
  */
86
void Delay(__IO uint32_t nTime)
87
{
88
  TimingDelay = nTime;
89
90
  while(TimingDelay != 0);
91
}
92
93
/**
94
  * @brief  Decrements the TimingDelay variable.
95
  * @param  None
96
  * @retval None
97
  */
98
void TimingDelay_Decrement(void)
99
{
100
  if (TimingDelay != 0x00)
101
  { 
102
    TimingDelay--;
103
  }
104
}
105
106
#ifdef  USE_FULL_ASSERT
107
108
/**
109
  * @brief  Reports the name of the source file and the source line number
110
  *         where the assert_param error has occurred.
111
  * @param  file: pointer to the source file name
112
  * @param  line: assert_param error line source number
113
  * @retval None
114
  */
115
void assert_failed(uint8_t* file, uint32_t line)
116
{ 
117
  /* User can add his own implementation to report the file name and line number,
118
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
119
120
  /* Infinite loop */
121
  while (1)
122
  {
123
  }
124
}
125
#endif

ich feue mich sehr über Antworten.

PS. ich schreibe deutsch als Fremdsprache. Bitte entschuldigen Sie über 
schlecht formulierte Sätze

von Stm M. (stmfresser)


Lesenswert?

ich glaube ich sollte DMA1 Channel 7 nehmen.

ich hoffe jetzt sollte es funktionieren.

von Felix G. (felixg)


Lesenswert?

Also bei mir heißt das Datenregister DR und nicht TDR.

Anstatt:
1
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(USART2->TDR);

verwende mal:
1
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(USART2->DR);

Sonst ist es eig. genauso, wie ich es auch habe.

von Stm M. (stmfresser)


Lesenswert?

Hallo!

im STM32F3 usart.c ist DR Register als TDR definiert. :D

von Felix G. (felixg)


Lesenswert?

Achso alles klar ;-)

Gehts denn mit dem anderen DMA-Channel?

von Stm M. (stmfresser)


Lesenswert?

hab nur kompiliert und teste es mal in einer stunde. ich habe ein gutes 
gefühl.:D

von Stm M. (stmfresser)


Lesenswert?

wenn die code falsch ist, dann ist sie verdammt gut falsch.

von Felix G. (felixg)


Lesenswert?

Müsste hier nicht anstatt
1
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
2
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;

sowas stehen
1
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
2
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

Steht im anderen Beitrag auch so. Du versendest mit dem USART ja nur ein 
Byte jedesmal und kein WORD (4 Bytes).

von Stm M. (stmfresser)


Lesenswert?

nice, du hast recht, es funktioniert :)
danke!

sonst habe ich char mühl empfangen.

Ich frag mich wie konfiguriere ich DMA für RX

: Bearbeitet durch User
von Felix G. (felixg)


Lesenswert?

Sehr gut.

Für Rx musst du den passenden Channel auswählen und dann folgende Zeilen 
ändern:
1
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
2
3
USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);

zu
1
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
2
3
USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);

Das müsste es dann gewesen sein.

von Stm M. (stmfresser)


Lesenswert?

Hallo!

Leider lese ich es etwas spät. Nach vielen Versuchen geht RX 
einwandfrei.
"PeripheralSRC" Genau das war mein Problem.

Danke!

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.