STM32F4 USART DMA - Kein Restart

OP #3410495
Lesenswert?

Hallo zusammen,

ich versuche derzeit mit dem STM32F4 Discovery einen Block Daten per 
USART DMA zu übertragen.
Das funktioniert auch teilweise, dass einmalig die Daten übertragen 
werden. Danach stoppt der DMA Transfer wie gewünscht (Mode: normal, 
nicht circular), aber er lässt sich nicht erneut starten. Das Problem 
ist also, dass der DMA Transfer nur einmal startet, aber ein erneuter 
Start nicht wie gewollt ausgeführt wird.

Hier der Code:

Hier der Buffer der übertragen werden soll:
1
char txbuffer[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

Initialisierungsfunktion des USART3 auf GPIOB 10/11:
1
void USART3_INIT()
2
{
3
  /* Enable GPIO clock for UM6 USART*/
4
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
5

6
  /* Enable USART clock */
7
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
8

9
  // Init GPIOs
10
  GPIO_InitTypeDef   GPIO_InitStructure;
11

12
  // Configure USART
13
  GPIO_InitStructure.GPIO_Pin               = GPIO_Pin_10 | GPIO_Pin_11;
14
  GPIO_InitStructure.GPIO_Mode               = GPIO_Mode_AF;
15
  GPIO_InitStructure.GPIO_Speed               = GPIO_Speed_100MHz;
16
  GPIO_InitStructure.GPIO_OType               = GPIO_OType_PP;
17
  GPIO_InitStructure.GPIO_PuPd               = GPIO_PuPd_UP;
18
  GPIO_Init(GPIOB, &GPIO_InitStructure);
19

20
  /* UM6 USART GPIO configuration -----------------------------------------------*/
21
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);
22
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);
23

24
  // Configure UM6 USART
25
  USART_InitTypeDef   USART_InitStructure;
26
  USART_InitStructure.USART_BaudRate             = 115200;
27
  USART_InitStructure.USART_WordLength           = USART_WordLength_8b;
28
  USART_InitStructure.USART_StopBits             = USART_StopBits_1;
29
  USART_InitStructure.USART_Parity             = USART_Parity_No;
30
  USART_InitStructure.USART_HardwareFlowControl       = USART_HardwareFlowControl_None;
31
  USART_InitStructure.USART_Mode               = USART_Mode_Rx | USART_Mode_Tx;
32
  USART_Init(USART3, &USART_InitStructure);
33

34
  // Enable receive interrupt on USART3
35
  USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
36

37
  // Setup NVIC
38
  NVIC_InitTypeDef   NVIC_InitStructure;
39
  NVIC_InitStructure.NVIC_IRQChannel             = USART3_IRQn;
40
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority  = 0;
41
  NVIC_InitStructure.NVIC_IRQChannelSubPriority      = 0;
42
  NVIC_InitStructure.NVIC_IRQChannelCmd          = ENABLE;
43
  NVIC_Init(&NVIC_InitStructure);
44

45
  /* Enable USART */
46
  USART_Cmd(USART3, ENABLE);
47

48
  // Enable DMA TX for USART
49
  /* Enable the DMA clock */
50
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
51

52
  // Configure USART TX DMA
53
  DMA_InitTypeDef    dma_is;
54
  DMA_StructInit(&dma_is);                                  // Init dma structure (clear structure)
55
  dma_is.DMA_Channel                    = DMA_Channel_4;          // Select DMA channel (see reference manual, DMA1 request mapping)
56
  dma_is.DMA_Mode                      = DMA_Mode_Normal;          // Normal mode, not circular!
57
  dma_is.DMA_FIFOMode                    = DMA_FIFOMode_Disable;        // Disable FIFO mode
58
  //dma_is.DMA_FIFOThreshold                = DMA_FIFOThreshold_1QuarterFull;  // Irrelevant as direct mode is used (FIFO disabled)
59
  dma_is.DMA_DIR                      = DMA_DIR_MemoryToPeripheral;    // DMA direction definition (memory to peripheral)
60
  dma_is.DMA_Priority                    = DMA_Priority_Medium;        // Set priority
61
  dma_is.DMA_BufferSize                  = 10;                // Buffer size
62

63
  dma_is.DMA_Memory0BaseAddr                = (uint32_t)&txbuffer;        // Base address of buffer
64
  dma_is.DMA_MemoryInc                  = DMA_MemoryInc_Enable;        // Increment memory address enabled
65
  dma_is.DMA_MemoryBurst                  = DMA_MemoryBurst_Single;      // Set burst mode to single
66
  dma_is.DMA_MemoryDataSize                = DMA_MemoryDataSize_Byte;      // Set memory data size to BYTE
67

68
  dma_is.DMA_PeripheralBaseAddr              = (uint32_t)&(USART3->DR);      // Select peripheral base address (USART data register)
69
  dma_is.DMA_PeripheralInc                = DMA_PeripheralInc_Disable;    // Increment peripheral address disabled
70
  dma_is.DMA_PeripheralBurst                = DMA_PeripheralBurst_Single;    // Set peripheral burst mode to single
71
  dma_is.DMA_PeripheralDataSize              = DMA_PeripheralDataSize_Byte;    // Set peripheral data size to BYTE
72

73
  DMA_Init(DMA1_Stream3, &dma_is);                              // Init DMA
74

75
  USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);                        // Enable USART DMA TX Requsts
76

77
  // Enable TX DMA transfer complete interrupt
78
  //DMA_ITConfig(USARTy_TX_DMA_STREAM, DMA_IT_TC, ENABLE);
79
}

und letztlich noch die Main:
1
int main(void)
2
{
3
  // Locals
4

5
  // ----------------------------------------------------------------------------------------------------------
6
  // Board initialization
7
  // ----------------------------------------------------------------------------------------------------------
8
  // Init LEDs
9
  LED_INIT();
10

11
  // Init serial port
12
  USART_INIT();
13

14
  // ----------------------------------------------------------------------------------------------------------
15
  // ----------------------------------------------------------------------------------------------------------
16
  // PRODUCTIVE LOOP
17
  // ----------------------------------------------------------------------------------------------------------
18
  // ----------------------------------------------------------------------------------------------------------
19
  int i = 0;
20
  int led = 0;
21

22
    while(1)
23
    {
24
      Delay(500000);
25
      LED1_ON;
26
      Delay(500000);
27
      LED1_OFF;
28

29
      if (i++ > 5)
30
      {
31
        StartDMA();
32
        i = 0;
33
      }
34
    }
35
}
36

37

38
/***************************************************************************************************************/
39
void Delay(__IO uint32_t nCount)
40
{
41
  while(nCount--)
42
  {
43
  }
44
}


Über einen hilfreichen Tipp würde ich mich sehr freuen!

mit besten Grüßen,
Michael
Gast #3695440
Lesenswert?

Code von  StartDMA() ?
Mit meinen DiscoveryF100 functioniert es so :
1
char bufferTx[254] = "USART DMA Polling: USARTy -> USARTz using DMA";
2
 char bufferRx[127] = "USART DMA Polling: USARTz -> USARTy using DMA";
3
 void DMA_Configuration(void)
4
 {
5
  DMA_InitTypeDef DMA_InitStructure;
6
  /* USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */
7
  DMA_DeInit( DMA1_Channel4);  
8
  DMA_InitStructure.DMA_PeripheralBaseAddr =  0x40013804 ;//USART1_DR_Base
9
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)bufferTx;
10
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
11
  DMA_InitStructure.DMA_BufferSize = 10;
12
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
13
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
14
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
15
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
16
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
17
  DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
18
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
19
  DMA_Init( DMA1_Channel4, &DMA_InitStructure);
20
  }
21
 /* Enable USARTy DMA TX request */
22
 USART_DMACmd(USART1,USART_DMAReq_Tx, ENABLE);
23
 /* Enable USARTy TX DMA1 Channel */
24
 DMA_Cmd(DMA1_Channel4, ENABLE);
25
 USART_Cmd(USART1, ENABLE);
26
 void Start_DMA(int string_length){
27
  //Wait until USARTy TX DMA1 Channel Transfer Complete 
28
       if (DMA_GetFlagStatus(DMA1_FLAG_TC4) == SET){
29
         DMA1_Channel4->CCR &= ~DMA_CCR_EN;      // disable DMA
30
         DMA1_Channel4->CMAR  =  (uint32_t)bufferTx;//(unsigned)
31
         DMA1_Channel4->CNDTR = string_length;//strlen(hallo);
32
         DMA1_Channel4->CCR |= DMA_CCR_EN; 
33
       }
34
  }

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren