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:
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);
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.
Jeroen3
Verwirrter Käse