STM32学习和实践笔记(9): 使用位带操作实现LED闪的实验

控制GPIO的那些寄存器,都在位带区。

根据上一篇讲的原理,要想每次只操作这些寄存的某一个bit而不影响别的bit,可以使用与这些bit相对应的位带别名区。

因此,在使用GPIO的位带操作之前,先要按上篇讲的原理,先在软件上做好位带区的每一个bit位与位带别名区的关连。

下面这些代码就实现这个目的:

一行行来看,首先看:

一行一行来看,先看第一行:

这个是使用宏定义,来定义和传递参数。(可以看到在用宏定义传递形参时,并没有事先另外去声明形能addr和bitnum的数据类型,直接就这样定义并使用了!见识了!)

当编译器看到BITBAND(0x40000,3),它就会把传进来实参,传到后面的公式进行计算,从来得到位带区某一个bit在位带别名区的地址。

读代码时,直接把它看作已计算好的位带别名区的地址就行了。

第二行:

这一行是根据位带区的基地址,取出对应的值。

这个*((volatile unsigned long  *)(addr)) 有两层,第一层是:

(volatile unsigned long  *)(addr),

这是强制声明一个32位(unsigned long)的数据类型,这个数据类型是一个指针变量,这个变量保存的是一个32位的地址

volatile是一个关键字,其作用是:

volatile 提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。

如 果没有 volatile 关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。所以遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。

第二是把第一层的内容是括号包起来,在外面又加了一个*,这表示取出这个地址里面的数据。简言之,就是取出那个地址里的byte。读代码时,直接把它看作是位带区对应地址里的值就可以了。

(为方便理解这两层,可以以*((int *) a)这样一个结构作作说明:

int a, 这是声明a是一个整数型变量。

int *a ,这表明a是指针变量,a里存放的是一个地址,而不是数据。这个时侯的a与int a完全不同的变量声明了,因为它是指针变量。

在int *a这里,不要把*作为取值理解,它仅仅是声明a是指针变量作用,不要把它当成运算符里的a

*((int *) a),就是操作a所向的地址内的值,最外面的这个*,才是运算符,表示取这个指针变量指向地址里的值)

第三行:

这一行的作用,就是操作位带别名区地址里的值

理解了前面的三行后,后面的就很好理解了!

比如,当我main.c中输入一个语句PAout(1)时,编译器会直接使用

来替代,并且把其中的n置换为1,

GPIOA_ODR_Addr置换为:

也就是对应端口的ODR寄存器的地址。

所以,当我输入PAout(1) =1时,根据上面所说的第三行的作用,那我通过对位带别名区对应地址的操作,而更改到了ODR寄存器里数据的某一bit位,从而实现了对某一个具体的pin的输入输出的直接操作!

现在,把整个的逻辑再理一遍:

假定我要让GPIO 的A端口的第1个引脚输出一个高电压,那么,我首先要找到GPIO A端口的控制输出的寄存器ODR:

其以看到我只要使ODR0变为高电平,那么GPIO 的A端口的第1个引脚就输出一个高电压。

而GPIOA_ODR在哪里呢?

根据前面的memory mapping也就是地址总图:

我知道A端口的所有寄存器的基地址是0x4001 0800,这就是GPIOA_BASE。

在这个基地址上,偏移0Ch,也就是12个地址,就是GPIOA_ODR的地址。

(其它的端口都是依此类推,都是在各自的基地址上偏移0Ch),

所以从这里我知道了ODR这个寄存器的地址,也由第几个引脚,知道在这个地址数据的第几个bit位。(这个地方与前面的描述有不一致,前面这个bit只有0-7这三8个值,但是这里可以从0-15,但根据公式,只要基地址不变,那么算过来的相应的地址也会是正确的,这个n在公式里,就起到每多一个位,就偏移4个地址的作用。)

再由前面的公式,就算出对应的位带别名区的地址,并对该地址的值进行操作。而对其的操作,就是对应ODR里的某一个bit位的操作(硬件设计决定的)

把这些宏定义加到程序里,用位带操作来控制LED,试验是成功的。

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

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

相关文章

通过前缀和来看golang的acm输入输出

前缀和 问题引入 package mainimport ("fmt" )func main() {var n, q, l, r intfmt.Scan(&n, &q)a : make([]int, n)ap : make([]int64, n 1)ap[0] 0for i : 0; i < n; i {fmt.Scan(&a[i])ap[i 1] ap[i] int64(a[i])}for j : 0; j < q; j {f…

远程桌面无法连接怎么办?

远程桌面无法连接是指在尝试使用远程桌面功能时出现连接失败的情况。这种问题可能会给工作和生活带来极大的不便&#xff0c;因此我们需要寻找解决办法。在讨论解决方案之前&#xff0c;我们先来了解一下【天联】组网的优势。 【天联】组网的优势有很多。它能够解决复杂网络环境…

[大模型]Qwen1.5-7B-Chat-GPTQ-Int4 部署环境

Qwen1.5-7B-Chat-GPTQ-Int4 部署环境 说明 Qwen1.5-72b 版本有BF16、INT8、INT4三个版本&#xff0c;三个版本性能接近。由于BF16版本需要144GB的显存&#xff0c;让普通用户忘却止步&#xff0c;而INT4版本只需要48GB即可推理&#xff0c;给普通用户本地化部署创造了机会。&…

MySQL数据库的详解(1)

DDL&#xff08;数据库操作&#xff09; 查询 查询所有数据库&#xff1a;show databases;当前数据库&#xff1a;select database(); 创建 创建数据库&#xff1a;create database [ if not exists] 数据库名 ; 使用 使用数据库&#xff1a;use 数据库名 ; 删除 删除数…

Deblurring 3D Gaussian Splatting去模糊3D高斯溅射

Abstract 摘要 Recent studies in Radiance Fields have paved the robust way for novel view synthesis with their photorealistic rendering quality. Nevertheless, they usually employ neural networks and volumetric rendering, which are costly to train and impede…

如何将普通maven项目转为maven-web项目

文件-项目结构&#xff08;File-->Project Structure &#xff09; 模块-->learn&#xff08;moudle-->learn&#xff09; 选中需要添加web的moudle&#xff0c;点击加号&#xff0c;我得是learn&#xff0c;单击选中后进行下如图操作&#xff1a; 编辑路径 结果如下…

微信小程序自定义关闭按钮在弹窗下面的效果

效果图: 我之前用vant 的popup的弹窗写&#xff0c;会出现close图标移动到弹窗内容外部不可见。 自定义代码&#xff1a; popup.JS/*** 生命周期函数--监听页面初次渲染完成*/onReady() {//自定义弹窗 动态获取屏幕高度var that this;wx.getSystemInfo({success: (result) &…

4.2.k8s的pod-标签管理、镜像拉取策略、容器重启策略、资源限制、优雅终止

一、标签管理 1.标签在k8s中极其重要&#xff0c;大多数资源的相互关联就需要使用标签&#xff1b;也就是说&#xff0c;资源的相互关联大多数时候&#xff0c;是使用标签进行关联的&#xff1b; 2.其他作用&#xff0c;在k8s集群中&#xff0c;node节点的一些操作比如污点及污…

前端docker jenkins nginx CI/CD持续集成持续部署-实战

最近用go react ts开发了一个todolist后端基本开发完了,前端采用CI/CD方式去部署。 步骤总结 先安装docker 和 docker-compose。安装jenkins镜像,跑容器的时候要配好数据卷。配置gitee或github(我这里使用gitee)在服务器上一定要创建好dokcer的数据卷,以便持久保存jenkin…

Google 推出 Gemini 1.5 Pro能处理音频;iOS 18或带来Safari 浏览助手;Llama 3 开源模型下个月推出

Google 推出 Gemini 1.5 Pro 公共预览版&#xff0c;能处理音频 Google 宣布将通过其 AI 应用平台 Vertex AI 向公众提供 Gemini 1.5 Pro&#xff0c;并且还赋予其「听力」&#xff0c;帮助用户处理音频内容。 用户可以上传会议录音、电视节目等音频内容&#xff0c;无需书面记…

好用的Python开发工具合集

​ Python是一种功能强大且易于学习的编程语言&#xff0c;被广泛应用于数据科学、机器学习、Web开发等领域。随着Python在各个领域的应用越来越广泛&#xff0c;越来越多的Python开发工具也涌现出来。但是&#xff0c;对于新手来说&#xff0c;选择一款合适的Python开发工具可…

R语言绘制一次和二次相关性热图

在数据探索的过程中&#xff0c;我们往往会对数据与数据的相关性进行分析&#xff0c;例如我们常用的corrplot包&#xff0c;或者psych包中的corr.test函数&#xff0c;对两两变量间的相关性进行分析。我们常常会看到这样的相关性热图&#xff1a; 但有时变量间的关系并非线性…

如何排查k8s集群中Pod内mysqld进程占用内存消耗过高?

文章目录 1. **查看容器资源使用情况**&#xff1a;2. **进入容器内部**&#xff1a;3. **检查进程内存使用**&#xff1a;4. **MySQL服务器状态检查**&#xff1a;5. **MySQL日志分析**&#xff1a;6. **使用专门的MySQL监控工具**&#xff1a;7. **配置文件检查**&#xff1a…

多模态 ——LLaVA 集成先进图像理解与自然语言交互GPT-4的大模型

概述 提出了一种大型模型 LLaVA&#xff0c;它使用 GPT-4 生成多模态语言图像指令跟随数据&#xff0c;并利用该数据将视觉和语言理解融为一体。初步实验表明&#xff0c;LLaVA 展示了出色的多模态聊天能力&#xff0c;在合成多模态指令上的表现优于 GPT-4。 在科学质量保证中…

Ubuntu 安装Java、Git、maven、Jenkins等持续集成环境

Ubuntu 持续集成 安装OpenJdk 查看所有可安装的 JDK 版本 apt list OpenJDK\*使用 apt 安装 JDK&#xff08;以 11为例&#xff09;,最好是用11&#xff0c;java8对应的jenkins会有兼容问题。 sudo apt install openjdk-11-jdk openjdk-11-jre安装成功后&#xff0c;可以使用以…

【JavaEE初阶系列】——网络编程 UDP客户端/服务器 程序实现

目录 &#x1f6a9;UDP和TCP之间的区别 &#x1f388;TCP是有连接的 UDP是无连接的 &#x1f388;TCP是可靠传输 UDP是不可靠传输 &#x1f388;TCP是面向字节流 UDP是面向数据报 &#x1f388;TCP和UDP是全双工 &#x1f469;&#x1f3fb;‍&#x1f4bb;UDP的socket ap…

kubekey 离线安装harbor、k8s、kubesphere

目录 参考文献 了解kubekey 英文和中文 前提条件 部署准备 下载kubukey 离线包配置和制作 配置离线包 制作离线包 离线安装集群 复制KubeKey 和制品 artifact到离线机器 创建初始换、安装配置文件 安装镜像仓库harbor 初始化harbor 项目 修改配置文件 安装k8s集…

ios包上架系列 一、打包机Flutter项目环境配置

打包的时候一定要断开网络&#xff0c;上线包名只能在打包机配置 1、Xcode 需要从其它电脑空投 版本号&#xff1a;14.3.1 升级到Xcode14.3后发现,从这个版本开始,苹果从Xcode中移除了ARC相关的库,会导致fluter项目下的原生工程使用Xcode编译原生代码没 有问题, 但是flutter项…

Python(1):认识Python并且了解一些简单函数

文章目录 一、Python的优势及其使用场景二、Python环境的安装三、Python中的变量及其命名四、Python中的注释五、一些简单常见的函数和认识ASCII表六、Python导入模块的方式 一、Python的优势及其使用场景 优点&#xff1a; 开发效率高&#xff1a;Python具有非常强大的第三方…

MySQL 全文检索

不是所有的数据表都支持全文检索 MySQL支持多种底层数据库引擎&#xff0c;但是并非所有的引擎支持全文检索 &#xff0c;目前最常用引擎是是MyISAM和InnoDB&#xff1b;前者支持全文检索&#xff0c;后者不支持。 booolean模式操作符 操作符含义必须有-必须不包含>包含对应…