其他分享
首页 > 其他分享> > 细数STM32F103的那些坑——串口篇

细数STM32F103的那些坑——串口篇

作者:互联网

1、串口时钟

所以,在初始化串口1时,我们可以使用以下代码:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);

却不可以使用以下代码初始化串口2、串口3:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART2|RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART2|RCC_APB2Periph_GPIOB, ENABLE);

若要正确初始化串口相关时钟并且兼顾代码风格的统一性,推荐使用:

//串口1:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);	        //使能USART1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);		//使能GPIOA时钟

//串口2:
RCC_APB1PeriphClockCmd(RCC_APB2Periph_USART2, ENABLE);	        //使能USART2时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);		//使能GPIOA时钟

//串口3:
RCC_APB1PeriphClockCmd(RCC_APB2Periph_USART3, ENABLE);	        //使能USART3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);		//使能GPIOB时钟

2、串口中断

在进入串口中断后,需要对中断的类型进行判断,这里有两个容易混用的函数:

ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint32_t USART_IT)


  该函数不仅会判断标志位是否置1,同时还会判断是否使能了相应的中断。所以在串口中断函数中,如果要获取中断标志位,通常使用该函数。

FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint32_t USART_FLAG)


  该函数只判断标志位。在没有使能相应的中断时,通常使用该函数来判断标志位是否置1。

在串口中断中,使用的应该是函数USART_GetITStatus(),而USART_GetFlagStatus()通常用在串口轮询的场合。

参考:https://www.cnblogs.com/leo0621/p/8709944.html

串口中断函数常用代码如下:

void USART1_IRQHandler(void)
{
	uint8_t data;
	
	if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)		//接收寄存器非空中断
	{
		data = USART_ReceiveData(USART1);		//读取字符
        //添加你的代码
	}
	
	if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) 		//发送寄存器空中断
	{	
        //添加你的代码
        
        //如果所有数据都已发送完毕,则关闭发送中断
        USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
	}
}

更加丧心病狂一点的写法:(参考资料:https://blog.csdn.net/xiahailong90/article/details/94595005

void USART1_IRQHandler(void)
{
	uint8_t data;

	if (USART_GetFlagStatus(USART1, USART_FLAG_PE) != RESET)
	{
		USART_ReceiveData(USART1);
		USART_ClearFlag(USART1, USART_FLAG_PE);
	}

	if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)
	{
		USART_ReceiveData(USART1);
		USART_ClearFlag(USART1, USART_FLAG_ORE);
	}

	if (USART_GetFlagStatus(USART1, USART_FLAG_FE) != RESET)
	{
		USART_ReceiveData(USART1);
		USART_ClearFlag(USART1, USART_FLAG_FE);
	}

	if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)		//接收寄存器非空中断
	{
		USART_ClearFlag(USART1, USART_FLAG_RXNE);
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);

		data = USART_ReceiveData(USART1);		//读取字符
		//添加你的代码
	}

	if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) 		//发送寄存器空中断
	{
		USART_ClearFlag(USART1, USART_FLAG_TXE);
		USART_ClearITPendingBit(USART1, USART_IT_TXE);
		//添加你的代码

		//如果所有数据都已发送完毕,则关闭发送中断
		USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
	}
}
素手执锐血衊白衣 发布了17 篇原创文章 · 获赞 10 · 访问量 2万+ 私信 关注

标签:STM32F103,细数,ENABLE,USART,串口,APB2Periph,USART1,RCC
来源: https://blog.csdn.net/qq_17459305/article/details/104126735