尝试重现问题
由于客户使用的是主从架构,实验采用两块 STM3220G-EVAL 评估板来重现现象。 一块用来不间断发送串口数据, 另一块采
用串口 DMA 进行接收, 直接通过杜邦线连接串口 PIN 脚并共地,不使用评估板上的 RS232 收发器。 接收端使用
STM32F2xx_StdPeriph_Examples\ USART\USART_TwoBoards 的示例代码。 代码片段如下:
int main(void)
{
...
USART_Config();
...
while (1)
{
/* Clear Buffers */
Fill_Buffer(RxBuffer, TXBUFFERSIZE);
Fill_Buffer(CmdBuffer, 2);
DMA_DeInit(USARTx_RX_DMA_STREAM);
DMA_InitStructure.DMA_Channel = USARTx_RX_DMA_CHANNEL;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
/************* USART will receive the the transaction data ****************/
/* Transaction data (length defined by CmdBuffer[1] variable) */
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)RxBuffer;
DMA_InitStructure.DMA_BufferSize =10;// (uint16_t)CmdBuffer[1];
DMA_InitStructure.DMA_Mode =DMA_Mode_Normal;//DMA_Mode_Circular;
DMA_Init(USARTx_RX_DMA_STREAM, &DMA_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable DMA Stream Transfer Complete interrupt */
DMA_ITConfig(USARTx_RX_DMA_STREAM, DMA_IT_TE|DMA_IT_DME|DMA_IT_FE, ENABLE);
/* Enable the DMA Stream */
DMA_Cmd(USARTx_RX_DMA_STREAM, ENABLE);
/* Enable the USART Rx DMA requests */
USART_DMACmd(USARTx, USART_DMAReq_Rx , ENABLE);
// USART_Cmd(USARTx, ENABLE);
// while(SET ==USART_GetFlagStatus(USARTx,USART_FLAG_ORE))
// {
// Tmp =USART_ReceiveData(USARTx);
// }
while ((DMA_GetFlagStatus(USARTx_RX_DMA_STREAM, USARTx_RX_DMA_FLAG_TCIF) ==
RESET)
{
}
/* Clear all DMA Streams flags */
DMA_ClearFlag(USARTx_RX_DMA_STREAM, USARTx_RX_DMA_FLAG_HTIF |
USARTx_RX_DMA_FLAG_TCIF);
/* Disable the DMA Stream */
DMA_Cmd(USARTx_RX_DMA_STREAM, DISABLE);
/* Disable the USART Rx DMA requests */
USART_DMACmd(USARTx, USART_DMAReq_Rx, DISABLE);
//handle the RxBuffer data...
//...
}
}
USART_Config()函数如下:
static void USART_Config(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Peripheral Clock Enable -------------------------------------------------*/
/* Enable GPIO clock */
RCC_AHB1PeriphClockCmd(USARTx_TX_GPIO_CLK | USARTx_RX_GPIO_CLK, ENABLE);
/* Enable USART clock */
USARTx_CLK_INIT(USARTx_CLK, ENABLE);
/* Enable the DMA clock */
RCC_AHB1PeriphClockCmd(USARTx_DMAx_CLK, ENABLE);
/* USARTx GPIO configuration -----------------------------------------------*/
/* Connect USART pins to AF7 */
GPIO_PinAFConfig(USARTx_TX_GPIO_PORT, USARTx_TX_SOURCE, USARTx_TX_AF);
GPIO_PinAFConfig(USARTx_RX_GPIO_PORT, USARTx_RX_SOURCE, USARTx_RX_AF);
/* Configure USART Tx and Rx as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Pin = USARTx_TX_PIN;
GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = USARTx_RX_PIN;
GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStructure);
/* USARTx configuration ----------------------------------------------------*/
/* Enable the USART OverSampling by 8 */
USART_OverSampling8Cmd(USARTx, ENABLE);
USART_InitStructure.USART_BaudRate = 1408000;//3750000;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
/* When using Parity the word length must be configured to 9 bits */
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USARTx, &USART_InitStructure);
/* Configure DMA controller to manage USART TX and RX DMA request ----------*/
DMA_InitStructure.DMA_PeripheralBaseAddr = USARTx_DR_ADDRESS;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
/* Here only the unchanged parameters of the DMA initialization structure are
configured. During the program operation, the DMA will be configured with
different parameters according to the operation phase */
/* Enable USART */
USART_Cmd(USARTx, ENABLE);
}
按如上代码, 有如下现象:
1 代码不做修改,若先启动接收端 MCU 再启动发送端 MCU, 接收端 MCU 的串口能正常接收。
2 代码不做修改,若先启动发送端 MCU 再启动接收端 MCU, 接收端 MCU 的串口 100%接收异常。
3 修改发送端代码,改为发送端 MCU 串口每 1 秒间隔发送一次,则无论启动顺序如何, 接收端 MCU 的串口都能正常。
|