Forum: Mikrocontroller und Digitale Elektronik STM32F4 USART DMA - Kein Restart


von Michael K. (mmike)


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

von Stm M. (stmfresser)


Lesenswert?

Hallo!

ich glaube es DMA Mode soll circular sein.
1
  dma_is.DMA_Mode                      = DMA_Mode_Normal;          //

VG

von RP6conrad (Gast)


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
  }

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.