ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2020-01-31 19:40:50  阅读:1260  来源: 互联网

标签:STM32F103 细数 ENABLE USART 串口 APB2Periph USART1 RCC


1、串口时钟

  • GPIO外设时钟都挂载在APB1总线上
  • 串口1的时钟挂在APB2上,而串口2、串口3则是挂在APB1上

所以,在初始化串口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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有