【STM32开发之寄存器版】(二)-USART

news2024/11/28 10:37:24

一、前言

串口作为STM32的重要外设,对程序调试具有不可替代的作用。通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特率选择。其主要具备以下特性:

  • 支持全双工的异步通信
  • 支持LIN(局部互联网)
  • 支持智能卡协议和IrDA(红外数据组织)SIR ENDEC规范
  • 支持调制解调器(CTS/RTS)操作
  • 支持多处理器通信
  • 支持使用多缓冲器配置的DMA方式,实现高速数据通信。

STM32F103ZET6具备多达5路串口,本文将使用USART1(PA9/PA10)实现串口回环测试DEMO。

二、串口通信原理与时序

2.1 USART和UART的区别

STM32F103ZET6具备5个串口,其中串口1,2,3均为USART(通用同步异步收发传输器),串口4,5为UART(通用异步收发传输器)。他们的区别如下:

  • 同步与异步UART仅支持异步通信,数据在没有时钟信号的情况下进行传输,发送和接收双方必须在波特率等设置上保持一致;USART支持同步和异步两种通信模式。在同步模式下,它使用额外的时钟信号来同步数据的发送和接收。
  • 信号引脚USART1、USART2和USART3接口具有硬件的CTS和RTS信号管理、兼容ISO7816的智能卡模式和类SPI通信模式,除了UART5之外所有其他接口都可以使用DMA操作。
  • 数据传输可靠性UART数据传输仅依赖于预设的波特率,没有时钟信号,因此数据传输的可靠性可能受到干扰;USART在同步模式下,数据传输更加可靠,因为有时钟信号来确保数据的正确接收和发送。USART1接口通信速率可达4.5兆位/秒,其他接口的通信速率可达2.25兆位/秒。

2.2 串口通信的硬件组成

USART1由6根线组成,如下所示:

USART1线束功能
USART1_TX发送数据引脚
USART1_RX接受数据引脚
USART1_CK用于输出同步信号传输的时钟
USART1_CTS用于流量控制的清除发送引脚,若是高电平,在当前数据传输结束时阻断下一次的数据发送。
USART1_RTS用于流量控制的发送请求引脚,若是低电平,表明USART准备好接收数据。
GND接地

其中,同步模式下的CK引脚以及用于流量控制的CTS/RTS引脚不常用,而TX/RX/GND引脚是串口通信中不可或缺的,因此本文只关注这三个引脚。

2.3 串口通信的通讯方式

从传输数据的方向性和同时性上划分,串口通信主要被分为全双工、半双工和单工模式:

  • 全双工模式:允许数据在两个通信设备之间同时双向传输。
  • 半双工模式:数据可以在两个通信设备之间双向传输,但不能同时进行。
  • 单工模式:数据只能单向传输,不能同时发送和接收。

STM32F103ZET6的USART1通讯方式是全双工的。

2.4 串口通信的时序要求和数据格式

串口通信的时序要求如下所示:

每一个字符帧都满足以下数据格式:

字符帧的位含义
起始位每个数据帧的开始部分,通常是一个低电平信号。
数据位实际传输的数据部分,可以是8位、7位或9位,具体取决于配置。每个位依次从最低有效位(LSB)到最高有效位(MSB)传输(小端传输)。
校验位在数据位后添加一个校验位,可以帮助检测数据在传输过程中是否发生了错误。校验方式有奇偶校验
停止位数据帧的结束部分,通常是一个高电平信号。一般来讲,停止位有1,1.5,2个单位时间三种长度。
空闲位处于逻辑1状态, 表示当前线路上没有数据传送。

2.5 串口通信的奇校验和偶校验

在标准ASCII码中,其最高位(b7)用作奇偶校验位。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1;偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。

2.6 串口通信的波特率

波特率(Baud Rate)是串行通信中衡量数据传输速度的一个重要参数,定义为每秒钟传输的符号(信号变化)次数,通常以bps(bits per second,位/秒)为单位。

三、时钟树配置

从《STM32中文参考手册》可知,USART1是归属APB2总线下的外设,其时钟来源为APB2的外设时钟PCLK2。APB2时钟来源于AHB时钟,AHB时钟来源于经锁相环PLL倍频后的外部8MHz高速时钟HSE。具体时钟树配置流程如下所示。

时钟树配置代码在正点原子官方例程SYSTEM/sys.c下实现:

void Stm32_Clock_Init(u8 PLL)
{
	unsigned char temp=0;   
	MYRCC_DeInit();		  //复位并配置向量表
 	RCC->CR|=0x00010000;  //外部高速时钟使能HSEON
	while(!(RCC->CR>>17));//等待外部时钟就绪
	RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1;
	PLL-=2;				  //抵消2个单位(因为是从2开始的,设置0就是2)
	RCC->CFGR|=PLL<<18;   //设置PLL值 2~16
	RCC->CFGR|=1<<16;	  //PLLSRC ON 
	FLASH->ACR|=0x32;	  //FLASH 2个延时周期
	RCC->CR|=0x01000000;  //PLLON
	while(!(RCC->CR>>25));//等待PLL锁定
	RCC->CFGR|=0x00000002;//PLL作为系统时钟	 
	while(temp!=0x02)     //等待PLL作为系统时钟设置成功
	{   
		temp=RCC->CFGR>>2;
		temp&=0x03;
	}    
}		    

调用该函数时,函数传参PLL倍频为9, 最终串口1获得的基础时钟频率PCLK2为72MHz。 

四、寄存器介绍

实现USART1的功能主要涉及以下寄存器:

寄存器功能
APB2ENR
APB2 外设时钟使能寄存器
GPIOx_CRH
端口配置高寄存器
APB2RSTR
APB2 外设复位寄存器
USART_BRR
波特比率寄存器
USART_CR1
控制寄存器 1
USART_SR
状态寄存器
USART_DR
数据寄存器

下面将对这些寄存器进行一一介绍。

4.1  APB2ENR外设时钟使能寄存器

《STM32中文参考手册》对APB2ENR寄存器的描述如下:

毋庸置疑,本文需要将USART1时钟使能,即将位14置1

除此以外,本文用到的串口1的TX和RX分别是PA9和PA10,因此需要使能IO端口A的时钟,即将位2置1

4.2 GPIOx_CRH端口配置高寄存器

《STM32中文参考手册》对GPIOx_CRH寄存器的描述如下:

 本文使用PA9和PA10作为串口1的功能端口,因此需要按照如下要求进行配置:

GPIO端口复用功能配置GPIO配置
PA9
USART1_TX
全双工模式推挽复用输出
PA10USART1_RX全双工模式浮空输入或上拉输入

因此,需要按照如下进行配置:

GPIO端口寄存器配置
PA9GPIOA_CRH[7:6] = 0b10
GPIOA_CRH[5:4] = 0b11
PA10GPIOA_CRH[11:10] = 0b10
GPIOA_CRH[9:8] = 0b00

4.3  APB2RSTR外设复位寄存器

《STM32中文参考手册》对APB2RSTR寄存器的描述如下:

本次DEMO仅需将USART1复位即可,故仅需将 APB2RSTR的第14位 置1 后再 置0 即可复位

4.4 USART_BRR波特比率寄存器

《STM32中文参考手册》对USART_BRR寄存器的描述如下:

STM32F103ZET6的USART1波特率计算方法如下:

若设置USART1的波特率为115200bps,按照如下方式求得USART_BRR寄存器的值:

  • 由第三节时钟树配置可知,USART1的时钟来源PCLK2为72MHz。
  • USARTDIV=fPCLK2/(16*bound)=72000000/(16*115200)=39.0625
  • 故DIV_Mantissa[11:0]=39=0X27
  • 故DIV_Fraction[3:0]=0.0625*16=1=0X1
  • USART_BRR寄存器的值为(DIV_Mantissa[11:0]<<4)|(DIV_Fraction[3:0])=0X0271

4.5 USART_SR状态寄存器

《STM32中文参考手册》对USART_SR寄存器的描述如下:

其中,仅重点关注TXE、TC和RXNE标志位。当发送寄存器为空时,TXE为1;当发送完成时,TC为1,;当读寄存器非空,即接收到数据时,RXNE为1。

4.6 USART_CR1控制寄存器 1

《STM32中文参考手册》对USART_CR1寄存器的描述如下:

 其中,仅需重点关注以下几位:

标志位功能用法
13:UE串口使能位置1
12:M字长选择位,当该位为 0 的时候设置串口为 8 个字长外加 n 个停止
位,停止位的个数(n)是根据 USART_CR2 的[13:12]位设置来决定的,默认为 0。
置0
10:PCE
校验使能位,设置为 0,则禁止校验,否则使能校验。  
置0
9:PS
校验位选择,设置为 0 则为偶校验,否则为奇校验
/
7:TXEIE
发送缓冲区空中断使能位,设置该位为 1,当 USART_SR 中的 TXE 位为1 时,将产生串口中断。
置1
6:TCIE
发送完成中断使能位,设置该位为 1,当 USART_SR 中的 TC 位为 1 时,将产生串口中断。
置1
5:RXNEIE
RXNEIE 为接收缓冲区非空中断使能,设置该位为 1,当USART_SR 中的 ORE 或者 RXNE 位为1时,将产生串口中断。
置1
3:TE
发送使能位
置1
2:RE
接收使能位
置1

4.7 USART_DR数据寄存器

《STM32中文参考手册》对USART_DR寄存器的描述如下:

将数据放入TDR中即可发送,同理,可以从RDR中读出接收到的数据。 

五、硬件连接

  1. 将以上跳线帽接好,即将USART1接到板载CH340 USB转串口芯片上。
  2. 将USB线接到USB_SLAVE端口。

六、程序设计

6.1 USART1初始化

本函数位于SYSTEM/usart.c/uart_init(),该函数主要进行串口波特率设置(参考4.4)、使能A口和串口1外设时钟(参考4.1),设置端口复用(参考4.2),复位串口1(参考4.3)、使能接收中断(参考4.6)。具体代码如下所示:

void uart_init(u32 pclk2,u32 bound)
{  	 
	float temp;
	u16 mantissa;
	u16 fraction;	   
	temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
	mantissa=temp;				 //得到整数部分
	fraction=(temp-mantissa)*16; //得到小数部分	 
    mantissa<<=4;
	mantissa+=fraction; 
	RCC->APB2ENR|=1<<2;   //使能PORTA口时钟  
	RCC->APB2ENR|=1<<14;  //使能串口时钟 
	GPIOA->CRH&=0XFFFFF00F;//IO状态设置
	GPIOA->CRH|=0X000008B0;//IO状态设置 
	RCC->APB2RSTR|=1<<14;   //复位串口1
	RCC->APB2RSTR&=~(1<<14);//停止复位	   	   
	//波特率设置
 	USART1->BRR=mantissa; // 波特率设置	 
	USART1->CR1|=0X200C;  //1位停止,无校验位.
#if EN_USART1_RX		  //如果使能了接收
	//使能接收中断 
	USART1->CR1|=1<<5;    //接收缓冲区非空中断使能	    	
	MY_NVIC_Init(3,3,USART1_IRQn,2);//组2,最低优先级 
#endif
}

6.2 USART1接收中断函数

本函数位于SYSTEM/usart.c/USART1_IRQHandler(),主要通过定义一个标志USART_RX_STA,其bit15为接收完成标志位,bit14为接收到0X0d标志位,bit13-bit0为Buf计数。接收到的数据需要以0X0d 0X0a结尾。具体流程如下图所示:

具体实现如下所示:

#if EN_USART1_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误   	
u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART_RX_STA=0;       //接收状态标记	  
  
void USART1_IRQHandler(void)
{
	u8 res;	
	if(USART1->SR&(1<<5))	//接收到数据
	{	 
		res=USART1->DR; 
		if((USART_RX_STA&0x8000)==0)//接收未完成
		{
			if(USART_RX_STA&0x4000)//接收到了0x0d
			{
				if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
			}else //还没收到0X0D
			{	
				if(res==0x0d)USART_RX_STA|=0x4000;
				else
				{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=res;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
				}		 
			}
		}  		 									     
	}
}

6.3 printf函数重定向

本函数位于SYSTEM/usart.c/fputc(),主要是将fputc重定向到USART1上。

int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//等待上一次串口数据发送完成  
	USART1->DR = (u8) ch;      	//写DR,串口1将发送数据
	return ch;
}

6.4 轮询主函数

本函数位于USER/test.c,主要是通过USART_RX_STA获得接收到的信息长度,并将信息按照字节通过USART1->DR发送出去,利用USART_SR->TC判断是否发送完成。进而形成USART回环。具体代码如下所示:

#include "sys.h"
#include "usart.h"		
#include "delay.h"	
#include "led.h" 
#include "beep.h" 
#include "key.h"	 	 

int main(void)
{								  
	u16 t; 
	u16 len;	
	u16 times=0;    
	Stm32_Clock_Init(9);	//系统时钟设置
	uart_init(72,115200); 	//串口初始化为115200
	delay_init(72);	   	 	//延时初始化 
	LED_Init();		  		//初始化与LED连接的硬件接口 
 	while(1)
	{
		if(USART_RX_STA&0x8000)
		{					   
			len=USART_RX_STA&0x3FFF;//得到此次接收到的数据长度
			printf("\r\n您发送的消息为:\r\n\r\n");
			for(t=0;t<len;t++)
			{
				USART1->DR=USART_RX_BUF[t];
				while((USART1->SR&0X40)==0);//等待发送结束
			}
			printf("\r\n\r\n");//插入换行
			USART_RX_STA=0;
		}else
		{
			times++;
			if(times%5000==0)
			{
				printf("\r\n串口USART1寄存器实验\r\n");
			}
			if(times%200==0)printf("请输入数据,以回车键结束\r\n");  
			if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
			delay_ms(10);   
		}
	}		 
}

完整版代码见正点原子官方:【正点原子】精英STM32F103开发板\【正点原子】精英STM32F103开发板资料 资料盘(A盘)\4,程序源码\1,标准例程-寄存器版本\1,标准例程-寄存器版本\实验4 串口实验

七、上机测试

使用XCOM查看串口发送的数据,并测试串口回环:

至此测试成功! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2189536.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nacos入门指南:服务发现与配置管理的全面解析

Nacos 是一个用于动态服务发现、配置管理和服务管理的平台。它由阿里巴巴开源&#xff0c;旨在帮助开发者更轻松地构建云原生应用。Nacos 支持多种环境下的服务管理和配置管理&#xff0c;包括但不限于 Kubernetes、Docker、虚拟机等。 一、Nacos的主要功能 1. **服务发现与健康…

GS-SLAM论文阅读笔记-CaRtGS

前言 这篇文章看起来有点像Photo-slam的续作&#xff0c;行文格式和图片类型很接近&#xff0c;而且貌似是出自同一所学校的&#xff0c;所以推测可能是Photo-slam的优化与改进方法&#xff0c;接下来具体看看改进了哪些地方。 文章目录 前言1.背景介绍GS-SLAM方法总结 2.关键…

认知杂谈97《兼听则明,偏听则暗》

内容摘要&#xff1a; 在信息爆炸的时代&#xff0c;我们被各种信息包围&#xff0c;这些信息往往经过精心设计以吸引注意力和影响观点。为了避免被操控&#xff0c;我们需要从多个渠道获取信息&#xff0c;并培养批判性思维来分析信息的真实性和偏见。 提高信息素养&#xff0…

读数据湖仓07描述性数据

1. 描述性数据 1.1. 基础数据中包含不同类型的数据&#xff0c;而不同类型数据的描述性数据也存在显著的差异 1.2. 尽管这些描述性数据存在根本性的差异&#xff0c;但通过描述性数据&#xff0c;我们可以全面了解基础数据中的数据 1.3. 通过分析基础设施中提供的描述性数据…

基于CAN总线的STM32G4 Bootloader设计说明

1 设计目的 根据芜湖铂科新能源自身企业发展需要&#xff0c;开发一款基于ST公司STM32G4系列MCU&#xff08;具体开发用型号STM32G473和STM32G431微处理器&#xff09;的CAN总线bootloader&#xff0c;方便应用程序的刷写。CAN设备采用周立功CAN卡&#xff08;USBCAN-II、CAN-…

Docker安装人大金仓(kingbase)关系型数据库教程

人大金仓数据库(KingbaseES)是由中国人民大学金仓公司研发的一款自主知识产权的关系型数据库管理系统。 官网地址:https://www.kingbase.com.cn/ 本章教程,主要介绍如何用Docker安装启动人大金仓(kingbase)关系型数据库。 一、下载镜像 下载地址:https://www.kingbase.c…

【黑马软件测试三】web功能测试、抓包

阶段三&#xff0c;内容看情况略过 Web功能测试链接测试表单测试搜索测试删除测试cookies/session测试数据库测试抓包工具的使用一个APP的完整测试流程熟悉APP业务流程功能测试APP专项测试兼容性安装、卸载和升级交叉测试(干扰测试)push消息测试用户体验测试 Web功能测试 通过…

Python画笔案例-075 绘制趣味正方形

1、绘制趣味正方形 通过 python 的turtle 库绘制 趣味正方形,如下图: 2、实现代码 绘制趣味正方形,以下为实现代码: """趣味正方形.py画个正方形后,单击它会移动,并且碰到边缘就反弹。这个版本采用画布的move命令让当前线条项目移动实现的。也可以用纯动画…

华夏ERP账号密码泄露漏洞

漏洞描述 华夏ERP账号密码泄露漏洞 漏洞复现 FOFA "jshERP-boot" POC IP/jshERP-boot/user/getAllList;.ico

解决 IntelliJ IDEA 中 JSP 页面无法识别 getParameter() 方法的问题

目录 背景: 过程: getParameter优点&#xff1a; 背景: 在IDEA中&#xff0c;我正在编写一个.jsp文件&#xff0c;想要测试一下数据是否能够从HTTP请求中成功获取到userId参数的数据&#xff0c;下面代码是我用来测试的&#xff0c;但是出现了错误。 <% String userId …

【EXCEL数据处理】000016案例 vlookup函数。

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【EXCEL数据处理】000016案例 vlookup函数。使用的软件&#xff1a;off…

SpringBoot整合QQ邮箱

SpringBoot可以通过导入依赖的方式集成多种技术&#xff0c;这当然少不了我们常用的邮箱&#xff0c;现在本章演示SpringBoot整合QQ邮箱发送邮件.... 下面按步骤进行&#xff1a; 1.获取QQ邮箱授权码 1.1 登录QQ邮箱 1.2 开启SMTP服务 找到下图中的SMTP服务区域&#xff0c;…

C/C++/EasyX——入门图形编程(4)

【说明】紧接上文(&#xff61;&#xff65;ω&#xff65;&#xff61;)&#xff0c;好了&#xff0c;接下来&#xff0c;就让我们开始学习图像处理和获取鼠标消息的函数吧。&#xff08;各位友友们不要着急&#xff0c;想在短时间内就想做小游戏或者写出各种好看的画面是不简…

【韩顺平Java笔记】第7章:面向对象编程(基础部分)【214-226】

文章目录 214. 递归解决什么问题215. 递归执行机制1216. 递归执行机制2217 递归执行机制3217.1 阶乘218. 递归执行机制4219. 斐波那契数列220. 猴子吃桃221. 222. 223. 224. 老鼠出迷宫1,2,3,4224.1 什么是回溯 225. 汉诺塔226. 八皇后 214. 递归解决什么问题 简单的说: 递归就…

Koa2+mongodb项目实战1(项目搭建)

Koa中文文档 Koa 是一个基于 Node.js 的 Web 应用框架&#xff0c;由 Express 原班人马打造。 Koa 并没有捆绑任何中间件&#xff0c;而是提供了一套优雅的方法&#xff0c;帮助开发者快速地编写服务端应用程序。 项目初始化 创建一个文件夹&#xff1a;ko2-mongodb 打开文件…

Nginx的基础讲解之重写conf文件

一、Nginx 1、什么是nginx&#xff1f; Nginx&#xff08;engine x&#xff09;是一个高性能的HTTP和反向代理web服务器&#xff0c;同时也提供了IMAP/POP3/SMTP服务。 2、用于什么场景 Nginx适用于各种规模的网站和应用程序&#xff0c;特别是需要高并发处理和负载均衡的场…

Python | Leetcode Python题解之第452题用最少数量的箭引爆气球

题目&#xff1a; 题解&#xff1a; class Solution:def findMinArrowShots(self, points: List[List[int]]) -> int:if not points:return 0points.sort(keylambda balloon: balloon[1])pos points[0][1]ans 1for balloon in points:if balloon[0] > pos:pos balloo…

【EO-1(Earth Observing-1)卫星】

EO-1&#xff08;Earth Observing-1&#xff09;卫星是美国国家航空航天局&#xff08;NASA&#xff09;新千年计划&#xff08;New Millennium Program&#xff0c;NMP&#xff09;地球探测部分中的第一颗对地观测卫星。以下是对EO-1卫星的详细介绍&#xff1a; 一、发射与服…

国外电商系统开发-运维系统单个添加被管理服务器

提前设置好您的远程主机的信息&#xff0c;这样才能自动执行任务。否则&#xff0c;自动执行根本无从谈起。登录方式有SSH密码登录、SSH-Key登录两种方式。 最后点击保存。 上面的刷新图标表示在请求该服务器的状态。如果该服务器状态正常&#xff0c;则会显示如下图标&#xf…

业务封装与映射 -- 编码方式(QPSK、DQPSK、QAM)

信号在光通信系统中传输&#xff0c;需要在信号的发送端对原始电信号进行调制&#xff0c;接收端进行解调&#xff0c;恢复成原始的二进制电信号。光通信系统有三种基本的调制方式&#xff1a;ASK&#xff08;调幅&#xff09;/FSK&#xff08;调频&#xff09;/PSK&#xff08…