嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置

这篇具有很好参考价值的文章主要介绍了嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

上一篇中,对串口做了个概述,主要是介绍了串口通信的特征,异步串行全双工通信,然后就是结合串口的框图梳理了一下STM32中USART的配置流程以及发送接收数据的流程,本文将接着上篇的内容,对串口的寄存器做个介绍,然后实现一个简单的收发实验。

USART的相关寄存器介绍

根据之前GPIO的经验,咱们可以打开中文编程手册去找到对应的章节,然后依次看一下寄存器的每个位的功能。具体的位置在手册的第20章。
嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置

状态寄存器:USARTX->SR

首先第一个寄存器,就是状态寄存器,其作用就是用于描述USART的工作状态,为编程者提供一个串口的实时状态,前面分析框图的时候,有提到过,发送时需要判断上一帧有没有发送完毕;接收时需要判断一帧数据有没有接收完毕,当时说的是有内部的标志,这其中的标志就在此寄存器中。
状态寄存器是只读。
嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
寄存器的访问方式,还是结构体指针指向成员的写法:

**USARTx->SR(x代表1236)
或者
UARTx->SR(x代表45)**

具体位代表的含义

  1. 位 7 TXE:发送数据寄存器为空 (Transmit data register empty)
    用于判断发送数据寄存器
    当发送数据寄存器为空 1
    当发送数据寄存器不为空 0
    从发送数据寄存器发送到移位寄存器 这一位置1

  2. 位 6 TC:发送完成 (Transmission complete)
    用于判断上一帧数据是否发送完成
    发送完成 1
    发送未完成 0
    移位寄存器将数据发送完了,会将这一位置1;用于判断上一帧有么有发送完毕,没有就等待。
    参照之前GPIO等待松手的写法,等待发送完成的代码应该是下面这个样子:

while( !(USART1->SR & 1<<6) );  /如果不为1 则一直等待
  1. 位 5 RXNE:读取数据寄存器不为空 (Read data register not empty)
    判断数据接收结束了(接受完毕了CPU就可以将数据读取到变量)。
    如果数据接收结束 1
    如果数据没有接收结束 0
  2. 位 4 IDLE:检测到空闲线路 (IDLE line detected)
    检测到空闲线路时,该位由硬件置 1。这位此文用不上,下一篇的串口中断中会应用到,想要了解可以自己去手册细看。
    剩下的位,包括第0位的奇偶校验,一般都不做配置,所以在这也不看了。

实际代码

到这里关于发送和接收的代码编写思路其实已经有了,用串口1为例,代码如下:

//注意注释

串口的发送字符数据函数
{
  等待上一帧数据发送完成
  发送数据
}
/*******************************************
*函数名    :Usart1_Send_Byte
*函数功能  :串口1发送一个字节函数
*函数参数  :u8 data 
*函数返回值:无
*函数描述  :
发送一个U8类型的字符
*********************************************/
void Usart1_Send_Byte(u8 data)
{
	//等待之前的发送完成
	while(!(USART1->SR & (1<<6)));
	//将要发送的数据给数据寄存器
	USART1->DR = data;
}


接收过程
{
   等待接收移位寄存器为满
   接收数据
}

/*******************************************
*函数名    :Usart1_Receive_Byte
*函数功能  :串口1接收一个字节函数
*函数参数  :void
*函数返回值:u8 str
*函数描述  :
发送一个U8类型的字符
*********************************************/
u8 Usart1_Receive_Byte(void)
{
	u8 str;
	//等待接收完成
	while(!(USART1->SR & (1<<5)));
	//将数据寄存器的数据读取到
	str = USART1->DR;
	return str;
}

这个寄存器最大作用就是解决了上一篇中发送完成和接收完成的两个标志位的问题,完善了框图中发送和接收过程的标志判断问题。
注意上面的代码中,无论是写数据还是读数据都用到了一个USART1->DR的
寄存器,那么它的作用又是什么呢,接下里就对它来做个分析。

数据寄存器 USARTX->DR

注意手册中红框的表述,前面的框图中,发送和接收是两个数据寄存器,但实际在单片机内部是一个,这两个寄存器的唯一区别方法就是,执行写操作就是发送数据寄存器(TDR),执行读操作的时候就是接受数据寄存器(RDR)。这也就解释了为什么上面的代码中,读和写都是使用的DR寄存器。
嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置

波特率寄存器 USARTX->BRR

然后就是波特率寄存器,根据昨天的框图,在波特率的配置过程中,只用将计算的DIV结构写入一个寄存器即可。如下图:该寄存器的4-15位就是写入DIV的整数部分,0-3位就是写入DIV的小数部分。
嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
至于怎么写,参照前面的经验,直接使用赋值语句即可。还是借用昨天的
使用串口1,最后一句就是写入过程。
波特率:115200 时钟大小:84000000 过采样:16

float USARTDIV;
unsigned int  DIV_M;
unsigned int  DIV_F;
USARTDIV=84000000/16/115200// 45.57291666666667
DIV_M =(u32) USARTDIV//读取整数部分
DIV_F = (USARTDIV- DIV_M)*16+0.5 f  //考虑四舍五入


USART1->BRR = DIV_M<<4 | DIV_F;//写入BRR寄存器


控制寄存器 (USART_CR)

前面三个寄存器已经解决了前面框图分析提到的发送接收以及波特率的配置,剩下的USART_CR1、USART_CR2、USART_CR3就是用来配置串口控制器的,可以预见的是,这三个寄存器绝对是与串口的剩下三要素紧密相光的。

控制寄存器1(USART_CR1)

嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
如上图,控制寄存器1的高十六位是做保留的,只有低十六位用来做配置,这里还是先挑出今天需要使用的位,想要全面了解的可以自己去看数据手册哈。

  1. 位 15 OVER8:过采样模式 (Oversampling mode),过采样,很熟悉吧,上面一个寄存器中计算公式的8倍过采样还是16倍过采样就是通过这个寄存器来进行配置的,寄存器写1时是8倍过采样,写0时是16倍过采样。

  2. 位 13 UE:USART 使能 (USART enable)
    片上外设使能----模块级使能
    打开时钟 ----内核级使能
    “注!!!:具备配置写保护,进行USART配置的时候要先关闭使能,其他的配置完才能打开使能,要放在串口配置的最后一个”

  3. 位 12 M:字长 (Word length)
    配置数据位,此位就是用来配置四要素中的数据位的,一般配置为8位数据位,也就是对其写0。
    嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置

  4. 位 10 PCE:奇偶校验控制使能 (Parity control enable)
    一般没有使用,所以直接配置为0,禁止奇偶校验。

  5. 位 3 TE:发送器使能 (Transmitter enable)
    使能发送器配置为1即可。嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置

  6. 位 2 RE:接收器使能 (Receiver enable)使能接收。
    嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
    在控制寄存器1中我们需要操作的就是这些位,这里需要注意写法,控制寄存器1(USART_CR1),在代码中的写法是

USART1->CR[0]

控制寄存器2(USART_CR2)

可以发现,上面的控制寄存器1配置完后,四要素还有一个没有配置完毕,那就是停止位的配置,所以关于控制寄存器2,目前唯一用的上的就是第12
和13位。嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
一般配置为1个停止位,也就是写入00。
可以发现,到此,关于框图中的分析出来的,使能、四要素,发送,接收都齐活了,可是还有好几个寄存器没有露脸啊,这个后面遇到相关功能了再回来看,今天的功能确实只需要使用到上面的这些寄存器就够了。
关于控制寄存器的具体代码如下:


/*-----------------------------------------------------------------------*/	
		//Usart1初始化(四要素)
		RCC->APB2ENR |= (1<<4);//打开AHB2上的Usart_1时钟使能。
/*		//CR1
//			USART1->CR1 &= ~(1<<15);        //16倍过采样
//			USART1->CR1 &= ~(1<<12);        //8位字长
//			USART1->CR1 &= ~(1<<10);        //无奇偶校验
//			USART1->CR1 |= (1<<3);          //发送使能
//			USART1->CR1 |= (1<<2);          //接收使能*/
		USART1->CR1  &=~ (0XB<<12);//清零(16倍过采样,8位字长)
		USART1->CR1  |= (3<<2);   //配置CR1寄存器,无奇偶校验、发送使能接收使能 
		//CR2
		USART1->CR2 &= ~(3<<12);        //1个停止位
/*-----------------------------------------------------------------------*/	

		//串口使能(最后开启使能,不然会锁住寄存器导致配置失败)
		USART1->CR1 |= (1<<13);

可以发现,到这里关于昨天框图的流程已经走完了,那么是不是将上面的这些代码放进工程就可以了呢,事实上是不行的,还漏了一个点,前面介绍GPIO的时候说过,任何需要CPU与外界进行数据交换的时间,都需要使用到GPIO,很明显,上面的步骤中,还没有对GPIO进行操作。根据GPIO那篇的介绍,现在这种情况属于GPIO的复用模式,那么该怎么配置呢,分析如下:

GPIO的复用模式

查询对应GPIO管脚

既然GPIO是唯一通道,那么串口的通道具体对应那几个GPIO口呢,根据前面的通信特征可以知道应该会用到两个GPIO口,一个是TX一个是RX那么具体的对应要怎么查询呢,在数数据手册的第三章最后一个表格中有具体的映射,这里还是以USART1来说,首先在上方找到USART1,然后向下找到USART1_TX和USART1_RX然后再向左寻找即可看见对应管脚

嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
,细心的同学肯定会发现一个问题,在后面的续表中还有一组GPIO口对应值USART1的TX和RX,这时候到底要配置哪一组呢,解决方法就是看原理图的物理连接用的是什么。通过原理图可以发现使用的是PA9和PA10这一组,所以说,在配置过程中就要使用PA9和PA10管脚。
嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置

配置为复用模式

前面的按键输入和控制LED做了通用输入模式和通用输出模式的配置,这是第一次使用到复用模式的配置,那么关于复用模式具体怎么配置呢,之前在介绍GPIO的寄存的时候,有两个寄存器当时给略过了,现在就需要用到他们了,GPIO的复用功能寄存器,其中GPIO复用功能低寄存器对应控制的是0-7八个管脚的复用功能,GPIO复用功能高寄存器对应控制的是8-15这八个管脚的复用功能,这里使用的是PA9和PA10属于复用功能高位寄存器,这里和上面的串口控制寄存器一样需要注意寄存器具体的写法:

GPIO复用功能低位寄存器: GPIOx->AFR[0]
GPIO复用功能高位寄存器: GPIOx->AFR[1]

嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
然后在上面的引脚映射表中可以看见有个AF7,这个AF7就可以让PA9PA10对应到USART1的TX和RX。注意到编程手册的描述,对应AF7需要写入的是0111,也就是说,需要对AFR9和AFR10中写入0111即可。
嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
具体的配置代码:

	RCC->AHB1ENR  |= (1<<0);		//打开AHB1上GPIOA端口
		GPIOA ->MODER &= ~(0xf<<18);//清0  GPIOA_MODER寄存器
		GPIOA ->MODER |= (0xA<<18); //GPIOA_MODER寄存器配置为复用模式
		GPIOA->AFR[1] &= ~((15<<4) | (15<<8));   //清零
		GPIOA ->AFR[1]|= (0X77<<4); //A9,A10配置为AF7(USART1的TX、RX)

编程实现串口收发一个字节

根据上面的介绍,我们将函数进行封装,串口配置部分就使用初始化函数,接收和发送就是用功能函数,同样的,这是一个新模块,还是需要新建两个文件用来存放源文件和头文件。
具体的代码:

#include "Usart1.h"
/*******************************************
*函数名    :Usart1_Init
*函数功能  :串口1初始化函数
*函数参数  :u32 bps波特率 
*函数返回值:无
*函数描述  :
PA9--------USART1_TX
PA10-------USART1_RX
*********************************************/
void Usart1_Init(u32 bps)
{
		float USARTDIV;
		unsigned int  DIV_M;
		unsigned int  DIV_F;
		//GPIOA9、GPIOA10的初始化
		RCC->AHB1ENR  |= (1<<0);		//打开AHB1上GPIOA端口
		GPIOA ->MODER &= ~(0xf<<18);//清0  GPIOA_MODER寄存器
		GPIOA ->MODER |= (0xA<<18); //GPIOA_MODER寄存器配置为复用模式
		GPIOA->AFR[1] &= ~((15<<4) | (15<<8));   //清零
		GPIOA ->AFR[1]|= (0X77<<4); //A9,A10配置为AF7(USART1的TX、RX)
	
/*-----------------------------------------------------------------------*/	
		//Usart1初始化(四要素)
		RCC->APB2ENR |= (1<<4);//打开AHB2上的Usart_1时钟使能。
		//以下是两种配置方式,注释部分是一位一位的配置,未注释的是一起配置的部分。
/*		//CR1
//			USART1->CR1 &= ~(1<<15);        //16倍过采样
//			USART1->CR1 &= ~(1<<12);        //8位字长
//			USART1->CR1 &= ~(1<<10);        //无奇偶校验
//			USART1->CR1 |= (1<<3);          //发送使能
//			USART1->CR1 |= (1<<2);          //接收使能*/
		USART1->CR1  &=~ (0XB<<12);//清零(16倍过采样,8位字长)
		USART1->CR1  |= (3<<2);   //配置CR1寄存器,无奇偶校验、发送使能接收使能 
		//CR2
		USART1->CR2 &= ~(3<<12);        //1个停止位
/*-----------------------------------------------------------------------*/	
//BRR波特率计算
		USARTDIV = 84000000/16/bps;  // 
		DIV_M =(u32)USARTDIV;
		DIV_F = (USARTDIV - DIV_M)*16+0.5f;   //考虑四舍五入
		USART1->BRR = DIV_M<<4 | DIV_F;
/*-----------------------------------------------------------------------*/	
		//串口使能(最后开启使能,不然会锁住寄存器导致配置失败)
		USART1->CR1 |= (1<<13);
}
//!!!还需要将上面的发送一个字节和接收一个字节函数添加进来!!!!!
#ifndef _USART1_H__
#define _USART1_H_
#include "stm32f4xx.h"

void Usart1_Init(u32 bps);
void Usart1_Send_Byte(u8 data);
u8 Usart1_Receive_Byte(void);
#endif

然后在主函数调用初始化,编译
嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置

串口打印乱码

编译下载后发现,并没有按照我们的代码写的发送出‘A’到串口调试助手上,而是问号,仔细检查发现配置也没有问题,而且再林外一块板子上可以使用,那这是为什么呢。嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
后来,经过检查,是因为官方的时钟配置文件的分配是以25MHZ的晶振为基础来写的,而我的板子是8M晶振,造成了时序混乱,所以打印乱码了,修改为8后就可以了。
嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
修改后,可以正常打印字符A了。
嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置

接收一个字符

需求1:使用PC机控制板子的LED灯
接收字符 ’O’ 打开全部灯
接收字符‘F’关闭全部灯
答:直接调用前面的接收函数,然后判断接受到的值,执行操作即可。
嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置

运行效果

嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置

M4系列目录

1.嵌入式学习笔记——概述
2.嵌入式学习笔记——基于Cortex-M的单片机介绍
3.嵌入式学习笔记——STM32单片机开发前的准备
4.嵌入式学习笔记——STM32硬件基础知识
5.嵌入式学习笔记——认识STM32的 GPIO口
6.嵌入式学习笔记——使用寄存器编程操作GPIO
7.嵌入式学习笔记——寄存器实现控制LED小灯
8.嵌入式学习笔记——使用寄存器编程实现按键输入功能
9.嵌入式学习笔记——STM32的USART通信概述
10.嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
11.嵌入式学习笔记——STM32的USART收发字符串及串口中断
12.嵌入式学习笔记——STM32的中断控制体系
13.嵌入式学习笔记——STM32寄存器编程实现外部中断
14.嵌入式学习笔记——STM32的时钟树
15.嵌入式学习笔记——SysTick(系统滴答)
16.嵌入式学习笔记——M4的基本定时器
17.嵌入式学习笔记——通用定时器
18.嵌入式学习笔记——PWM与输入捕获(上)
19.嵌入式学习笔记——PWM与输入捕获(下)
20.嵌入式学习笔记——ADC模数转换器
21.嵌入式学习笔记——DMA
22.嵌入式学习笔记——SPI通信
23.嵌入式学习笔记——SPI通信的应用
24嵌入式学习笔记——IIC通信文章来源地址https://www.toymoban.com/news/detail-445704.html

到了这里,关于嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式学习笔记——STM32的时钟树

    在之前的所有代码编程的过程中,似乎每次都绕不开一个叫做时钟使能的东西,当时我们是在数据手册上直接看其挂接在那条时钟线上的,那么STM32内部的时钟到底是怎么一个构型呢,本文来对此做一个介绍。 老规矩,一个新的名词出现,首先需要搞清楚它是个啥,下图中对

    2024年02月02日
    浏览(53)
  • 嵌入式学习笔记——STM32硬件基础知识

    上一篇中我们重点是讲了一下怎么搭建开发环境以及怎么下载烧录的过程,这都是解决的电脑端的开发环境问题,还没有到实际的开发板上,我们的单片机是都是焊接在开发板上的,PCB上有着它所需的工作电路。并不是直接给供电电压就可以让其工作的,本文主要是简介一下

    2024年01月22日
    浏览(67)
  • 【嵌入式知识08】STM32的USART串口通信,给上位机连续发送Hello Windows!

    本文主要介绍串口协议和RS-232、485标准,以及RS232、485电平与TTL电平的区别,了解\\\"USB/TTL转232\\\"模块的工作原理;并完成一个STM32的USART串口通讯程序。   串口通信(Serial Communication)的概念非常简单,串口按位(bit)发送和接收字节的通信方式。尽管比按字节(byte)的并行通信

    2024年02月13日
    浏览(46)
  • 蓝桥杯嵌入式CT117E-M4学习笔记02-STM32G431RBT6芯片学习

    首先学习了解一下蓝桥杯嵌入式CT117E-M4开发板的主控芯片STM32G431RBT6,本文仅为个人学习成果总结,如有错误,恳请指正。 上图为STM32CubeMX选型界面,如图可以看出STM32G431RBT6具有以下特点和硬件集成。 采用Cortex-M4 32位RISC核心架构,工作频率最高可达170Mhz。 128kBytes的FLASH,32

    2023年04月09日
    浏览(59)
  • STM32串口通信详解(嵌入式学习)

    时钟信号在电子领域中是指用于同步和定时电路操作的周期性信号。它在数字系统和通信系统中起着至关重要的作用,用于协调各个组件之间的数据传输和操作。 时钟信号有以下几个重要的方面: 频率:时钟信号的频率是指单位时间内信号周期的数量。它通常以赫兹(Hz)为

    2024年02月09日
    浏览(66)
  • STM32的时钟系统(嵌入式学习)

    时钟是指用于计量和同步时间的装置或系统。时钟是嵌入式系统的脉搏,处理器内核在时钟驱动下完成指令执行,状态变换等动作,外设部件在时钟的驱动下完成各种工作,例如:串口数据的发送、AD转换、定时器计数等。因此时钟对于计算机系统是至关重要的,通常时钟系

    2024年02月16日
    浏览(47)
  • STM32的中断系统详解(嵌入式学习)

    中断是处理器中的一种机制,用于响应和处理突发事件或紧急事件。当发生中断时,当前正在执行的程序会被暂时中止,处理器会跳转到中断处理程序(也称为中断服务例程),对中断事件进行处理。处理完中断后,处理器再返回到被中断的程序继续执行。 中断可以分为内部

    2024年02月12日
    浏览(69)
  • 嵌入式学习stm32基础知识(期末复习)

    1. 计算机的体系架构 冯诺依曼架构 ​ 在完整的计算机系统中,包含五个部分,储存器,运算器,控制器输入设备和输出设备。 改进的冯诺依曼架构 改进型架构的各模块的高速数据交换中心利用储存器这个大容量,极大的提高了效率。 哈佛架构 ​ 哈佛结构数据空间和地址

    2024年02月07日
    浏览(64)
  • STM32&ARM体系结构(嵌入式学习)

    STM32是意法半导体(STMicroelectronics)公司推出的一系列32位ARM Cortex-M微控制器(MCU)产品系列。它们基于ARM架构,并且具有广泛的应用领域,包括工业自动化、消费电子、医疗设备、通信、汽车电子等。 STM32系列提供了多个产品系列,以满足不同应用需求和性能要求。其中常见

    2024年02月08日
    浏览(61)
  • STM32的定时器详解(嵌入式学习)

    想要了解STM32的时钟系统 点击这里跳转——》STM32的时钟系统(嵌入式学习) 建议先看看时钟树如何配置 点击这里跳转——》STM32的时钟树配置(嵌入式学习) 跳转——》STM32的时钟基础详解(嵌入式学习) 跳跳转——》STM32的时钟源详解(嵌入式学习) SysTick又称滴答定时

    2024年02月13日
    浏览(66)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包