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

一、前言

串口作为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;  //外部高速时钟使能HSEONwhile(!(RCC->CR>>17));//等待外部时钟就绪RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1;PLL-=2;				  //抵消2个单位(因为是从2开始的,设置0就是2)RCC->CFGR|=PLL<<18;   //设置PLL值 2~16RCC->CFGR|=1<<16;	  //PLLSRC ON FLASH->ACR|=0x32;	  //FLASH 2个延时周期RCC->CR|=0x01000000;  //PLLONwhile(!(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);//得到USARTDIVmantissa=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;   //复位串口1RCC->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); 	//串口初始化为115200delay_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.rhkb.cn/news/438794.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSP-J模拟赛四补题报告

前言 T1: 100 p t s \color{green}100pts 100pts T2: 100 p t s \color{green}100pts 100pts T3: 20 p t s → 5 p t s \color{red}20pts\rightarrow5pts 20pts→5pts T4: 20 p t s \color{red}20pts 20pts T1,2秒了&#xff0c;T3&#xff0c;4死了 T1 三个(three) 题面…

数据集-目标检测系列- 货船 检测数据集 freighter>> DataBall

数据集-目标检测系列- 货船 检测数据集 freighter>> DataBall 数据集-目标检测系列- 货船 检测数据集 freighter>> DataBall 数据量&#xff1a;3k 想要进一步了解&#xff0c;请联系。 DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种…

SQL优化 - 排序

文章目录 排序和索引降序索引 FilesortORDER BY 顺序问题ORDER BY LIMIT 排序和索引 如果ORDER BY操作使用了索引&#xff0c;那么就可以避免排序操作&#xff0c;因为索引本身就是按索引 key 排好序的。那什么情况下&#xff0c;ORDER BY会走索引呢&#xff1f; 例如&#…

阿里云域名注册购买和备案

文章目录 1、阿里云首页搜索 域名注册2、点击 控制台3、域名控制台 1、阿里云首页搜索 域名注册 2、点击 控制台 3、域名控制台

【08】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-Scroll容器与Tabs组件

序言&#xff1a; 本文详细讲解了关于我们在页面上经常看到的可滚动页面和导航栏在鸿蒙开发中如何用Scroll和Tabs组件实现&#xff0c;介绍了Scroll和Tabs的基本用法与属性。 笔者也是跟着B站黑马的课程一步步学习&#xff0c;学习的过程中添加部分自己的想法整理为笔记分享出…

【漏洞复现】泛微OA E-Office do_excel.php 任意文件写入漏洞

》》》产品描述《《《 泛微0-0fice是一款标准化的协同 OA办公软件&#xff0c;泛微协同办公产品系列成员之一,实行通用化产品设计&#xff0c;充分贴合企业管理需求&#xff0c;本着简洁易用、高效智能的原则&#xff0c;为企业快速打造移动化、无纸化、数字化的办公平台。 》》…

深度学习:基于MindSpore实现CycleGAN壁画修复

关于CycleGAN的基础知识可参考&#xff1a; 深度学习&#xff1a;CycleGAN图像风格迁移转换-CSDN博客 以及MindSpore官方的教学视频&#xff1a; CycleGAN图像风格迁移转换_哔哩哔哩_bilibili 本案例将基于CycleGAN实现破损草图到线稿图的转换 数据集 本案例使用的数据集里…

【含文档】基于Springboot+Vue的护肤品推荐系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…

企望制造ERP系统存在RCE漏洞

漏洞描述 企望制造纸箱业erp系统由深知纸箱行业特点和业务流程的多位IT专家打造&#xff0c;具有国际先进的管理方式&#xff0c;将现代化的管理方式融入erp软件中&#xff0c;让企业分分钟就拥有科学的管理经验。erp的功能包括成本核算、报价定价、订单下达、生产下单、现场管…

五子棋双人对战项目(3)——匹配模块

目录 一、分析需求 二、约定前后端交互接口 匹配请求&#xff1a; 匹配响应&#xff1a; 三、实现游戏大厅页面&#xff08;前端代码&#xff09; game_hall.html&#xff1a; common.css&#xff1a; game_hall.css&#xff1a; 四、实现后端代码 WebSocketConfig …

vue3 环境配置vue-i8n国际化

一.依赖和插件的安装 主要是vue-i18n和 vscode的自动化插件i18n Ally https://vue-i18n.intlify.dev/ npm install vue-i18n10 pnpm add vue-i18n10 yarn add vue-i18n10 vscode在应用商城中搜索i18n Ally&#xff1a;如图 二.实操 安装完以后在对应项目中的跟package.jso…

计算机毕业设计 基于协同过滤算法的个性化音乐推荐系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

Charles+socksdroid手机抓包配置

证书配置 保存一个证书 使用abd将证书推送到手机 找手机的加密与凭据 点击从存储设备安装 选择刚刚导入手机的证书 证书按照成功 手机安装socksdroid 端口对应 ip对应 开启 点击allow 成功手机抓包 将用户证书移动到系统证书 系统证书路径&#xff1a;/etc/security/cacerts…

【springboot】整合LoadBalancer

目录 问题产生背景解决方案&#xff1a;实现LoadBalancer1. 添加依赖2. 配置文件3. 使用LoadBalancer4. 使用 RestTemplate 进行服务调用5. 测试 问题产生背景 以下是一个购物车项目&#xff0c;通过调用外部接口获取商品信息&#xff0c;并添加到购物车中&#xff0c;这段代码…

【Android 14源码分析】WMS-窗口显示-第二步:relayoutWindow -1

忽然有一天&#xff0c;我想要做一件事&#xff1a;去代码中去验证那些曾经被“灌输”的理论。                                                                                  – 服装…

【JAVA开源】基于Vue和SpringBoot的宠物咖啡馆平台

本文项目编号 T 064 &#xff0c;文末自助获取源码 \color{red}{T064&#xff0c;文末自助获取源码} T064&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

使用CSS实现酷炫加载

使用CSS实现酷炫加载 效果展示 整体页面布局 <div class"container"></div>使用JavaScript添加loading加载动画的元素 document.addEventListener("DOMContentLoaded", () > {let container document.querySelector(".container&q…

初识Linux · 自主Shell编写

目录 前言&#xff1a; 1 命令行解释器部分 2 获取用户命令行参数 3 命令行参数进行分割 4 执行命令 5 判断命令是否为内建命令 前言&#xff1a; 本文介绍是自主Shell编写&#xff0c;对于shell&#xff0c;即外壳解释程序&#xff0c;我们目前接触到的命令行解释器&am…

数据提取之JSON与JsonPATH

第一章 json 一、json简介 json简单说就是javascript中的对象和数组&#xff0c;所以这两种结构就是对象和数组两种结构&#xff0c;通过这两种结构可以表示各种复杂的结构 > 1. 对象&#xff1a;对象在js中表示为{ }括起来的内容&#xff0c;数据结构为 { key&#xff1…

区块链+Web3学习笔记(METAMASHK、密码学知识)

学习资料来源于B站&#xff1a; 17小时最全Web3教程&#xff1a;ERC20&#xff0c;NFT&#xff0c;Hardhat&#xff0c;CCIP跨链_哔哩哔哩_bilibili 该课程提供的Github代码地址&#xff0c;相关资料详见README.md&#xff1a; Web3_tutorial_Chinese/README.md at main sm…