STM32F103ZET6 USART mit DMA verhält sich beim Debug anders als beim Reset-Lauf

Ich verwende die MCU STM32F103ZET6 und habe ein seltsames Problem, bei dem, wenn ich meine MCU programmiere und debugge oder programmiere und zurücksetze, der USART3, der zur Kommunikation mit einem Slave-Gerät verwendet wird, nicht funktioniert. Beim Debuggen gehen keine USART-Daten vom DMA in den Speicher, und ich habe festgestellt, dass das Slave-Gerät ständig Daten sendet. Ich habe kontrolliert:

  1. Die Takte sind mit geeigneten Geschwindigkeiten konfiguriert.
  2. Der USART funktioniert immer noch mit USART3_getchar(0)
  3. Neuinitialisierung meines USART3.
  4. BOOT0-Pin ist im Debug niedrig.
  5. Der DMA-Kanal wird von nichts anderem verwendet.

Ich habe das Referenzhandbuch und das Gerätedatenblatt überprüft, habe jedoch Schwierigkeiten, die Einstellungen im Code zu debuggen/überprüfen, um den Unterschied zwischen dem Debug-/Reset-Lauf zu erkennen.

// Local Variables
GPIO_InitTypeDef    GPIO_InitStructure;
NVIC_InitTypeDef    NVIC_InitStructure;
USART_InitTypeDef   USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStructure;

// Code
// Configure UART
RCC_APB2PeriphClockCmd(RCC_APB1Periph_USART3 | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);     // USART3 Periph clock enable

// Configure Pins
GPIO_InitStructure.GPIO_Pin                     =  UART3_RX_PIN;
GPIO_InitStructure.GPIO_Speed                   =  GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode                    =  GPIO_Mode_IPD;
GPIO_Init(UART3_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin                     =  UART3_TX_PIN;
GPIO_InitStructure.GPIO_Speed                   =  GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode                    =  GPIO_Mode_AF_PP;
GPIO_Init(UART3_PORT, &GPIO_InitStructure);

#if(UART3_TX_FLOW_CTS_EN    == 1)                                                       
// Enable USART3 CTS pin
GPIO_InitStructure.GPIO_Pin                     =  UART3_CTS_PIN;
GPIO_InitStructure.GPIO_Speed                   =  GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode                    =  GPIO_Mode_IN_FLOATING;
GPIO_Init(UART3_PORT, &GPIO_InitStructure);
#endif

#if(UART3_RX_FLOW_RTS_EN    == 1)                                                       
// Enable USART3 RTS pin
GPIO_InitStructure.GPIO_Pin                     =  UART3_RTS_PIN;
GPIO_InitStructure.GPIO_Speed                   =  GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode                    =  GPIO_Mode_Out_PP;
GPIO_Init(UART3_PORT, &GPIO_InitStructure);

mCSP_USART3_RTS_PIN_GO;                                                             
// initialise the RTS pin as go
#endif

st_uart3_tx_glb.timeout_timer_u16               =  UART3_TX_TIMEOUT;
while(  (uart3_tx_flg                           == 0)   &&
#if(UART3_TX_FLOW_CTS_EN    == 1)

        (mCSP_USART3_CTS_READ                   == 0)   &&
#endif
        (st_uart3_tx_glb.timeout_timer_u16      >  0)   );

//Set USART3 Clock
USART_ClockStructInit(&USART_ClockInitStructure);
USART_ClockInit(USART3, &USART_ClockInitStructure);

USART_InitStructure.USART_BaudRate                  =  baud_rate_u32;
USART_InitStructure.USART_WordLength                =  USART_WordLength_8b;
USART_InitStructure.USART_StopBits                  =  USART_StopBits_1;
USART_InitStructure.USART_Parity                    =  USART_Parity_No;
#if(UART3_TX_FLOW_CTS_EN    == 1)
USART_InitStructure.USART_HardwareFlowControl       =  
USART_HardwareFlowControl_CTS;  // Enable USART3 CTS pin
#else
USART_InitStructure.USART_HardwareFlowControl       =  
USART_HardwareFlowControl_None;
#endif
USART_InitStructure.USART_Mode                      =  USART_Mode_Rx | 
USART_Mode_Tx;
USART_Init(USART3, &USART_InitStructure);

// Enable interrupts
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);

// Enable modules
USART_Cmd(USART3, ENABLE);
USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);

// Enable the UART3 Interupt
//  NVIC_InitStructure.NVIC_IRQChannel                      =  USART3_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=USART3_IRQ_PREM_PRI;
//  NVIC_InitStructure.NVIC_IRQChannelSubPriority   = USART3_IRQ_SUB_PRI;
//  NVIC_InitStructure.NVIC_IRQChannelCmd                   =  ENABLE;
//  NVIC_Init(&NVIC_InitStructure);

// Configure DMA
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);                                  // DMA1 Periph clock enable

st_uart3_tx_glb.cnt_u8                              =  st_uart3_tx_glb.wr_index_u8;

DMA_DeInit(DMA1_Channel2);
DMA_StructInit(&DMA_UART3_InitStructure);
DMA_UART3_InitStructure.DMA_PeripheralBaseAddr      =  (uint32_t)&USART3->DR;
DMA_UART3_InitStructure.DMA_MemoryBaseAddr          =  (uint32_t)uart3_rx_buffer_a_u8_glb;
DMA_UART3_InitStructure.DMA_DIR                     =  DMA_DIR_PeripheralSRC;
DMA_UART3_InitStructure.DMA_BufferSize              =  st_uart3_tx_glb.cnt_u8;
DMA_UART3_InitStructure.DMA_PeripheralInc           =  DMA_PeripheralInc_Disable;
DMA_UART3_InitStructure.DMA_MemoryInc               =  DMA_MemoryInc_Enable;
DMA_UART3_InitStructure.DMA_PeripheralDataSize      =  DMA_PeripheralDataSize_Byte;
DMA_UART3_InitStructure.DMA_MemoryDataSize          =  DMA_MemoryDataSize_Byte;
DMA_UART3_InitStructure.DMA_Mode                    =  DMA_Mode_Circular;
DMA_UART3_InitStructure.DMA_Priority                =  DMA_Priority_VeryHigh;
DMA_UART3_InitStructure.DMA_M2M                     =  DMA_M2M_Disable;
DMA_Init(DMA1_Channel2, &DMA_UART3_InitStructure);

// Enable the DMA complete Interupt
NVIC_InitStructure.NVIC_IRQChannel                      =  DMA1_Channel2_IRQn;
NVIC_Init(&NVIC_InitStructure);

DMA_Cmd(DMA1_Channel2, ENABLE);
DMA und USART können während des Debuggens nicht angehalten werden, Sie könnten asynchron werden, wenn Sie auf diese Weise Interrupts verpassen. Siehe DBGMCU_CR.
Ich kann die Bitdefinition in stm32f10x.h sehen, bin mir aber nicht sicher, ob ich bestimmte DBGMCU_CR-Bits definieren muss, damit USART und DMA beim Debuggen funktionieren? Ich glaube nicht, dass ich das vorher machen musste. Ich halte die CPU nicht an, ich warte einfach darauf, dass ein bisschen in den Speicher kommt, und halte danach an.

Antworten (2)

Lokale Strukturen sollten initialisiert werden, da sonst einige Felder unvorhersehbare Werte erhalten können:

GPIO_InitTypeDef    GPIO_InitStructure={};
NVIC_InitTypeDef    NVIC_InitStructure={};
USART_InitTypeDef   USART_InitStructure={};
USART_ClockInitTypeDef USART_ClockInitStructure={};

mCSP_USART3_RTS_PIN_GO;Was bewirkt diese Aussage? Ist es ein Makro oder was?

Diese Flags sollten deklariert werden volatile, da Sie sonst bei unterschiedlichen Optimierungseinstellungen unterschiedliches Verhalten erhalten können:

while(  (uart3_tx_flg                           == 0)   &&
#if(UART3_TX_FLOW_CTS_EN    == 1)
    (mCSP_USART3_CTS_READ                   == 0)   &&
#endif
    (st_uart3_tx_glb.timeout_timer_u16      >  0)   );

Es war so, dass USART3 auf APB1 und nicht auf APB2-Uhr war und daher nicht aktiviert wurde, aber im Bootloader wurde die APB1-USART3-Uhr aktiviert.