在STM32中用寄存器方式点亮流水灯

文章目录

  • 实验资料
  • 一、对寄存器的理解
    • 1.通俗认识寄存器
    • 2.深入了解寄存器
      • (1)端口配置低寄存器(配置0到7引脚的寄存器)
      • (2)端口配置高寄存器(配置8到15引脚)
    • 3.GPIO口的功能描述
  • 二、配置寄存器点亮流水灯
    • 1.配置寄存器
      • (1)时钟设置
      • (2)配置端口寄存器的输入输出模式
      • (3)配置端口输出数据寄存器
    • 2.完整代码
    • 3.proteus仿真
    • 4.STM32实际效果
  • 三、将PC13的自带灯也引入流水灯
    • 1.添加的代码
    • 2.完整代码
    • 3.proteus仿真
    • 4.STM32实际效果
  • 四、总结
  • 五、参考资料

实验资料

链接:https://pan.baidu.com/s/1tYno7wmj11_bh1-UgL8HTQ?pwd=o1hk
提取码:o1hk

一、对寄存器的理解

1.通俗认识寄存器

首先我们来看一张图。在这里插入图片描述
试想如果没有寄存器,要控制8个LED灯的亮灭那么我们需要8个开关一对一进行控制。扳到ON,控制灯的亮。扳到OFF,控制灯的灭。而单片机中控制的东西太多太多,用开关来控制的话,至少需要成百上千个开关,显然这是不明智的。
因此,我们引入“寄存器”,顾名思义,寄存器,应当是用来寄存东西的而在单片机中的寄存器,就是用来寄存二进制数的。在上面的实例中,我们仅需一个8位寄存器就可以实现对这8个LED的控制。我们拨动开关相当于往寄存器里写数据,我们观察的开关的状态,相当于读取寄存器的数值。因此,一个8位寄存器,可以理解成8个小开关组成。
我们查阅资料可知,寄存器通常是由晶体管组成,它的体积微乎其微,非常适合在CPU中寄存数据。

2.深入了解寄存器

我们已经知道单片机中有很多寄存器。就相当于有很多组“开关”。那么我们如何来管理这些“开关”呢?因此,我们可以利用寄存器的符号(名字)地址

下图是与I/O口相关的寄存器
在这里插入图片描述
**注意:STM32单片机中的寄存器是32位的。(有些寄存器没有用高16位寄存器,比如:端口输出数据寄存器)**但是,不管哪款单片机,道理都是相通的。
在这里插入图片描述

下表是STM32F10xxx的寄存地址分布情况
在这里插入图片描述
STM32C8T6芯片共有48个引脚
在这里插入图片描述
具体功能如下:
在这里插入图片描述
我们可以看出GPIOA/B都有从0到15,都是16个引脚。
在GPIO配置寄存器中,每个引脚的模式由4位进行配置,16个端口就需要64位。

(1)端口配置低寄存器(配置0到7引脚的寄存器)

在这里插入图片描述
①CNF:configure。配置对应端口的输入输出模式。
②MODE:配置对应端口的输出速度。

(2)端口配置高寄存器(配置8到15引脚)

在这里插入图片描述
思考:为什么GPIOx_CRH的起始地址会偏移了4个字节(32位),而GPIOx_CRL却没有?
这是因为GPIOx_CRH恰好接在GPIOx_CRL后面,GPIOx_CRL恰好占了32位。

3.GPIO口的功能描述

在这里插入图片描述

在STM32中,GPIO(通用输入输出)接口通常是与APB2(Advanced Peripheral Bus 2,即高级外设总线)关联,是APB2的外设。

二、配置寄存器点亮流水灯

1.配置寄存器

框起来的是要用的寄存器的地址。
在这里插入图片描述

(1)时钟设置

由上面我们知道,GPIO口是APB2总线的外设。故我们在手册中要去查找APB2的外设时钟使能寄存器进行设置。

在这里插入图片描述
观察到时钟配置是置1打开,置0关闭。
在这里插入图片描述
因为本次实验要同时用到三个端口,要配置三个时钟,那我就不客气了,我直接打开GPIOA、B、C三个口的时钟。

RCC->APB2ENR=0x0000001C; //配置三个端口的时钟

(2)配置端口寄存器的输入输出模式

以配置GPIOA2引脚为例
在这里插入图片描述

GPIOA->CRL=0x00000300;//配置GPIOA2的输入输出模式

(3)配置端口输出数据寄存器

在这里插入图片描述
ODR:OutputDataRegister

GPIOA->ODR=0x00000000; //低电平点亮

2.完整代码

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

int main()
{
	//配置三个口的时钟
	RCC->APB2ENR=0x0000001C; 				//给GPOIA、B、C口配置时钟
	
	//配置GPIOA2口的输出模式及输出电平
	GPIOA->CRL=0x00000300;					//使用GPIOA2引脚
	//GPIOA->ODR=0x00000000; 			    //GPIOA2引脚低电平点亮
	GPIOA->ODR=0x00000004; 				//GPIOA2引脚高电平熄灭
	
	//配置GPIOB12口的输出模式及输出电平
	GPIOB->CRH=0x00030000;		 			//使用GPIOB12引脚
	//GPIOB->ODR=0x00000000; 	 			//GPIOB12引脚低电平点亮
	GPIOB->ODR=0x00001000; 		 		//GPIOB12引脚高电平熄灭
	
	//配置GPIOC15口的输出模式及输出电平
	GPIOC->CRH=0x30000000;					//使用GPIOC15引脚
	//GPIOC->ODR=0x00000000; 				//GPIOC15引脚低电平点亮
	GPIOC->ODR=0x00008000;    			//GPIOc15引脚高电平熄灭
	
	while(1)
	{
		GPIOA->ODR=0x00000000; 			    //GPIOA2引脚低电平点亮
		Delay_s(1);
		GPIOA->ODR=0x00000004; 				//GPIOA2引脚高电平熄灭
		
		GPIOB->ODR=0x00000000; 	 			//GPIOB12引脚低电平点亮
		Delay_s(1);
		GPIOB->ODR=0x00001000; 		 		//GPIOB12引脚高电平熄灭
		
		GPIOC->ODR=0x00000000; 				//GPIOC15引脚低电平点亮
		Delay_s(1);
		GPIOC->ODR=0x00008000;    			//GPIOc15引脚高电平熄灭
	}
}


3.proteus仿真

在这里插入图片描述

4.STM32实际效果

2024年5月5日001

与预期结果一致。

三、将PC13的自带灯也引入流水灯

太简单了,仍然去手册里查找GPIOC13相应寄存器的值进行配置,加上几行代码不就OK了!

1.添加的代码

注意:这两者的端口输出模式须同时配置,不然前面配置的会被覆盖,导致只配置成功后面配置的。

	//配置GPIOC13口和GPIOC15口的输出模式及输出电平
	GPIOC->CRH=0x30300000;					//使用GPIOC13和15引脚
	//GPIOC->ODR=0x00000000; 				//GPIOC13和15引脚低电平点亮
	GPIOC->ODR=0x0000A000; 					//GPIOC13和15仍然保持高电平
		GPIOC->ODR=0x00008000; 				//GPIOC13引脚低电平点亮,GPIOC15仍然保持高电平
		Delay_s(1);
		GPIOC->ODR=0x0000A000;    			//GPIOC13和GPIOC15引脚高电平熄灭

2.完整代码

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

int main()
{
	//配置三个口的时钟
	RCC->APB2ENR=0x0000001C; 				//给GPOIA、B、C口配置时钟
	
	//配置GPIOA2口的输出模式及输出电平
	GPIOA->CRL=0x00000300;					//使用GPIOA2引脚
	//GPIOA->ODR=0x00000000; 			    //GPIOA2引脚低电平点亮
	GPIOA->ODR=0x00000004; 				//GPIOA2引脚高电平熄灭
	
	//配置GPIOB12口的输出模式及输出电平
	GPIOB->CRH=0x00030000;		 			//使用GPIOB12引脚
	//GPIOB->ODR=0x00000000; 	 			//GPIOB12引脚低电平点亮
	GPIOB->ODR=0x00001000; 		 		//GPIOB12引脚高电平熄灭
	
	//配置GPIOC13口和GPIOC15口的输出模式及输出电平
	GPIOC->CRH=0x30300000;					//使用GPIOC13和15引脚
	//GPIOC->ODR=0x00000000; 				//GPIOC13和15引脚低电平点亮
	GPIOC->ODR=0x0000A000; 					//GPIOC13和15仍然保持高电平
	
	
	
	
	while(1)
	{
		GPIOA->ODR=0x00000000; 			    //GPIOA2引脚低电平点亮
		Delay_s(1);
		GPIOA->ODR=0x00000004; 				//GPIOA2引脚高电平熄灭
		
		GPIOB->ODR=0x00000000; 	 			//GPIOB12引脚低电平点亮
		Delay_s(1);
		GPIOB->ODR=0x00001000; 		 		//GPIOB12引脚高电平熄灭
				
		GPIOC->ODR=0x00008000; 				//GPIOC13引脚低电平点亮,GPIOC15仍然保持高电平
		Delay_s(1);
		GPIOC->ODR=0x0000A000;    			//GPIOC13和GPIOC15引脚高电平熄灭
		
		GPIOC->ODR=0x00002000; 				//GPIOC15引脚低电平点亮,GPIOC13仍然保持高电平
		Delay_s(1);
		GPIOC->ODR=0x0000A000;    			//GPIOC13和GPIOC15引脚高电平熄灭
		
	}
}

3.proteus仿真

在这里插入图片描述

4.STM32实际效果

2024年5月2日002

与预期结果一致。

四、总结

做完实验之后,我发现通过使用寄存器的方式点亮流水灯是比较底层的方法,也是比较笨的方法。但是,它能让我们更深刻地理解,STM32单片机中寄存器大致有哪些,对应的位置又在哪。
通过本实验,一步一步自己配置要用的寄存器数据,其实挺有意思的。当在同时使用GPIOC15和PC15端口时,我一开始是一个一个端口去配置模式的,发现只有后面配置那个能亮,最后仔细检查发现这两者得同时配置,否则,后面配置的会覆盖前面配置的。
本人才疏学浅,仍然有一处不太明白,就是我Proteus仿真的时候,为啥灯亮灭得那么快?而在板子上实验的时候又是符合预期的。希望各位大佬不吝赐教。

五、参考资料

1.https://www.bilibili.com/video/BV1Lr4y137Yx/?spm_id_from=333.337.search-card.all.click&vd_source=f8a9b6d51762562d444c27daa5c18d81
2.https://www.bilibili.com/video/BV1th411z7sn/?p=5&spm_id_from=333.880.my_history.page.click

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Git Bash和Git GUI设置中文的方法

0 前言 Git是一个分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。一般默认语言为英文,本文介绍修改Git Bash和Git GUI语言为中文的方法。 1 Git Bash设置中文方法 (1)鼠标右键,单击“Git B…

时间复杂度的简单讲解

小伙伴们大家好,我们又见面了,这次我们直接进入正题 时间复杂度的概念 时间复杂度的定义:在计算机科学中, 算法的时间复杂度是一个函数 ,它定量描述了该算法的运行时间。一 个算法执行所耗费的时间,从理论…

公有云Linux模拟TCP三次挥手与四次握手(Wireshark抓包验证版)

目录 写在前面环境准备实验步骤1. 安装nc工具2. 使用nc打开一个连接2.1 公有云-安全组放行对应端口(可选) 3. 打开Wireshark抓包工具4. 新开终端,进行连接5. 查看抓包文件,验证TCP三次握手与四次挥手TCP三次握手数据传输TCP四次挥…

【C++杂货铺铺】AVL树

目录 🌈前言🌈 📁 概念 📁 节点的定义 📁 插入 📁 旋转 1 . 新节点插入较高左子树的左侧---左左:右单旋 2. 新节点插入较高右子树的右侧---右右:左单旋 3. 新节点插入较高左…

57 读取/写出/读取 文件的过程的调试

前言 问题来自于文章 请教文件读写问题 请教文件读写问题 - 内核源码-Chinaunix vim 编辑文件, 实际上删除了原有的文件建立了一个新的文件? Ls –ail . 查看 inode 编号不一样了 这里主要是 调试一下 这一系列流程 测试用例 就是一个程序, 读取 1.txt 两次, 两次之间间隔…

49. UE5 RPG 使用Execution Calculations处理对目标造成的最终伤害

Execution Calculations是Unreal Engine中Gameplay Effects系统的一部分,用于在Gameplay Effect执行期间进行自定义的计算和逻辑操作。它允许开发者根据特定的游戏需求,灵活地处理和修改游戏中的属性(Attributes)。 功能强大且灵…

国内智能搜索工具实战教程

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

C++新特性-线程

主要内容 thread、condition、mutexatomicfunction、bind使用新特性实现线程池(支持可变参数列表)异常协程其他 1 C11多线程thread 重点: join和detach的使用场景thread构造函数参数绑定c函数绑定类函数线程封装基础类互斥锁mutexconditi…

网络基础-Telnet协议

Telnet(Telecommunication Network)是一种基于文本的远程终端协议,允许用户通过网络连接到远程计算机,并在远程计算机上执行命令;它使用TCP作为传输层协议,并依赖于网络连接在客户端和服务器之间进行通信&a…

FPGA SDRAM读写控制器

感谢邓堪文大佬 ! SDRAM 同步动态随机存取内存(synchronousdynamic randon-access menory,简称SDRAM)是有一个同步接口的动态随机存取内存(DRAM)。通常DRAM是有一个异步接口的,这样它可以随时响…

计算机毕业设计 | vue+springboot调查问卷管理系统(附源码)

1,研究目的 在进入21世纪以后,互联网得到了蓬勃的发展,电子问卷调查也开始逐渐流行起来。传统纸质问卷和电子问卷相比较后,传统问卷还存在很多弊端: 问卷分发起来比较困难,并且分发试卷耗费大量的金钱和时…

基于STC12C5A60S2系列1T 8051单片机实现一主单片机给多个从单片机发送数据的串口通信功能

基于STC12C5A60S2系列1T 8051单片机实现一主单片机给多个从单片机发送数据的串口通信功能 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机串口通信介绍STC12C5A60S2系列1T 8051单片机串口通信的结构基于STC12C5A60S2系列1T 8051单片机串口通信的特殊功能寄…

基于深度学习神经网络的AI图像PSD去雾系统源码

第一步:PSD介绍 以往的研究主要集中在具有合成模糊图像的训练模型上,当模型用于真实世界的模糊图像时,会导致性能下降。 为了解决上述问题,提高去雾的泛化性能,作者提出了一种Principled Synthetic-to-real Dehazing (…

STC8增强型单片机开发【LED呼吸灯(PWM)⭐⭐】

目录 一、引言 二、硬件准备 三、PWM技术概述 四、电路设计 五、代码编写 EAXSFR: 六、编译与下载 七、测试与调试 八、总结 一、引言 在嵌入式系统开发中,LED呼吸灯是一种常见的示例项目,它不仅能够展示PWM(脉冲宽度调制…

2024 cleanmymac有没有必要买呢,全反面分析

在使用mac时,小编遇到了运行内存不足、硬盘空间不足的情况。遇到这种情况,我们可以借助经典的电脑深度清理软件——CleanMyMac X,清理不常用的软件和系统垃圾,非常好用!不过,有许多网友发现CleanMyMac X有免…

SQLite利用事务实现批量插入(提升效率)

在尝试过SQLite批量插入一百万条记录,执行时长高达20多分钟后,就在想一个问题,这样的性能是不可能被广泛应用的,更不可能出现在真实的生产环境中,那么对此应该如何优化一下呢? 首先分析一下批量插入的逻辑 …

社区送水小程序软件开发

uni-app框架:使用Vue.js开发跨平台应用的前端框架,编写一套代码,可编译到Android、小程序等平台。 框架支持:springboot/Ssm/thinkphp/django/flask/express均支持 前端开发:vue.js 可选语言:pythonjavanode.jsphp均支持 运行软件…

端午节线上活动方案怎么写?

一年一端午,一岁一安康。 如果您想组织端午活动,却不知道如何安排,可以看看何策网,有很多案例参考,仿造模板修改即可。 下面分享一个线上端午节活动策划方案,希望能帮到你! 端午节作为祭祖祈…

Remix 集成 MUI

Remix 如何接入 MUI 组件库,MUI 官网提供了一个 Remix 接入 MUI 的例子,用的是老的 Remix版本,如何接入新的 Vite 版本呢? 由于 MUI 支持 SSR,只需要改造对应的 Client 和 Server 即可实现。安装 MUI 组件组件库&…

Java类与对象(一)

类的定义与使用 在Java中使用关键字class定义一个类,格式如下: class 类名{// 成员变量/字段/属性//成员方法/行为 }Java中类和c语言中的结构体有点类似, 在Java中类名一般采用大驼峰(每个首字母大写)的形式&#xf…