STM32F103的USART调试日志

本次串口调试过程中遇到两个问题:

1、发送数据出现死循环:

     具体表现为: 程序卡死在 while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);  无数据输出。TXD线上只是低电平,发送端口指示灯常亮。

注:串口1的引脚定义是PA.09,PA.10

    解决问题:

串口初始化时:USART1 和USART6 要使用   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USARTx, ENABLE);而

USART2, USART3, UART4 , UART5要使用 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE) ;问题得以解决。

typedef  struct _UART_CFG
{
	USART_TypeDef* UartNo;
	PIN_CFG Tx;
	PIN_CFG RX;
	uint32_t BaudRate;
	
}UART_CFG;


void Comm_Port_Init(void)
{
	UART_CFG uart_comm;

	uart_comm.UartNo = UART_COM;
	uart_comm.Tx.Pin= GPIO_Pin_9;
	uart_comm.Tx.Port = GPIOA;
	uart_comm.RX.Pin =  GPIO_Pin_10;
	uart_comm.RX.Port = GPIOA;
	uart_comm.BaudRate = BAUD_COM;
	Uart_Init(uart_comm);
}

void Uart_Init(UART_CFG uart)
{
	uint8_t Uart_IRQChannel_No;
	uint32_t RCC_APB1Periph;
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	USART_ClockInitTypeDef USART_ClockInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	if(uart.UartNo == USART1)
	{
		Uart_IRQChannel_No = USART1_IRQn;
		RCC_APB1Periph = RCC_APB2Periph_USART1;
        RCC_APB2PeriphClockCmd(RCC_APB1Periph, ENABLE);
	}
	else if(uart.UartNo == USART2)
	{
		Uart_IRQChannel_No = USART2_IRQn;
		RCC_APB1Periph = RCC_APB1Periph_USART2;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph, ENABLE);
	}
	else if(uart.UartNo == USART3)
	{
		Uart_IRQChannel_No = USART3_IRQn;
		RCC_APB1Periph = RCC_APB1Periph_USART3;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph, ENABLE);
	}
	else if(uart.UartNo == UART4)
	{
		Uart_IRQChannel_No = UART4_IRQn;
		RCC_APB1Periph = RCC_APB1Periph_UART4;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph, ENABLE);
	}
	else
	{
		Uart_IRQChannel_No = UART5_IRQn;
		RCC_APB1Periph = RCC_APB1Periph_UART5;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph, ENABLE);
	}
	
	GPIO_InitStructure.GPIO_Pin = uart.Tx.Pin;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(uart.Tx.Port, &GPIO_InitStructure);
   
	GPIO_InitStructure.GPIO_Pin = uart.RX.Pin;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(uart.RX.Port, &GPIO_InitStructure);

	USART_InitStructure.USART_BaudRate = uart.BaudRate;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	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(uart.UartNo, &USART_InitStructure);//初始化外设 USARTx 寄存器

	USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
	USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
	USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
	USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
	USART_ClockInit(uart.UartNo, &USART_ClockInitStructure);

	USART_Cmd(uart.UartNo, ENABLE);
	USART_ITConfig(uart.UartNo,USART_IT_RXNE,ENABLE);//ENABLE-DISABLE//使能或者失能指定的 USART 中断

	NVIC_InitStructure.NVIC_IRQChannel = Uart_IRQChannel_No;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);   
}

2、接收数据中断出现死循环:

具体表现:收到数据程序会不断进入中断,USART_GetITStatus 检查又没有中断发生。本函数一退出就重新再进入,就这样死循环了。源代码如下:

void USART2_IRQHandler(void)
{
    BYTE  Data = 0;
    OSIntEnter();
    if(USART_GetITStatus(USART1,USART_IT_RXNE)  !=   RESET)          
         //检查指定的usart是否发生了中断
    {
        Data  =   USART_ReceiveData(USART2);
        // do something at this;    处理数据
        USART_ClearFlag(USART2,USART_FLAG_TC ); //清除中断标志
    }
    else
    {
        USART_ClearFlag(UART_COM, USART_IT_ORE);
    }
    OSIntExit();
}

解决办法:

进入中断后必须第一时间清零RXNE,如没及时清零,下一帧数据过来时就会产生Overrun error!

更改为如下代码就OK了。

void USART2_IRQHandler(void)
{
    BYTE  Data = 0;
    OSIntEnter();
    if(USART_GetITStatus(USART1,USART_IT_RXNE)  !=   RESET) 
      //检查指定的usart是否发生了中断
    {
        Data  =   USART_ReceiveData(USART2);
        USART_ClearFlag(USART2,USART_FLAG_TC ); //清除中断标志

        // do something at this;    处理数据
    }
    else
    {
        USART_ClearFlag(UART_COM, USART_IT_ORE);
    }
    OSIntExit();
}

猜你喜欢

转载自blog.csdn.net/ggggyj/article/details/83306317