《嵌入式系统》知识总结10:使用位带操作操纵GPIO
位操作
汇编层面
外设控制常要针对字中某个位(Bit)操作
以字节编址的存储器地址空间中,需要3步骤(读出-修改-写回)
1.(从外设)读取包含该位的字节数据
2. 设置该位为0或1、同时屏蔽其他位(不改)
3. 将包含该位的字节数据写入(外设)
C语言层面
a |= (1<<2); // 位或实现置位
//将整型变量a的D2位置位、其他位不变a &= ~(1<<6); // 位与实现复位
//将整型变量a的D6位清零、其他位不变a ^= (1<<6); // 位异或实现求反
//将整型变量a的D6位取反、其他位不变
位带区
在STM32中,有两个地方实现了位带,一个是SRAM区的最低1MB空间,另一个是外设区最低1MB空间。这两个1MB的空间除了可以像正常的RAM一样操作外,他们还有自己的位带别名区,位带别名区把这1MB的空间的每一个位膨胀成一个32位的字,当访问位带别名区的这些字时,就可以达到访问位带区某个比特位的目的。
- W为位带区某个地址,k为改地址某个bit,A为位带别名区对应地址
- 对应关系为A=0x2200 0000+(W-0x2000 0000)×32+k×4,即位带区中地址W的第k位(记为W.k)对应着位带别名区中的地址A,对地址A(32位)的访问相当于访问W.k,即向A写入1,则W.k置1;向A写入0,则W.k清0。读出A相当于读出W.k。
- 位带别名区的每个字的内容只有第0位有效,其余的第[31:1]位保留。
SRAM位带区
SRAM的位带区为:0X2000_0000~0X200F_FFFF,大小为1MB,经过膨胀后的位带别名区为:
0X2200_0000~0X23FF_FFFF,大小为32MB
SRAM位带别名区地址
对于SRAM位带区的某个比特,记它所在字节的地址为 A,位序号为 n(0<=n<=7),则该比特在别名区的地址为:
AliasAddr=0x22000000+(A-0x20000000)*8*4 +n*4
或者写成:
AliasAddr=0x22000000+ (A-0x20000000)<<5 +n<<2
其中,0X22000000是SRAM位带别名区的起始地址,0x20000000是SRAM位带区的起始地址,(A-0x20000000)表示该比特前面有多少个字节,一个字节有8位,所以*8,一个位膨胀后是4个
字节,所以*4,n表示该比特在A地址的序号,因为一个位经过膨胀后是四个字节,所以*4。
不用位带方式
LDR r0, =0x20000300
LDR r1, [r0] ; 读取数据
ORR r1, r1, #0x4 ; D2位设置为1
STR r1, [r0] ; 写回结果
用位带方式
LDR r0, =0x22006008
MOV r1, #1 ; D2位设置为1
STR r1, [r0] ; 写入结果
位带(位绑定)操作的优点
- 简化操作
- 提高指令执行速度(32位cpu字对齐访问更高效)
- 保证执行过程的原子性
外设位带区
外设位带区的地址为:0X40000000~0X400FFFFF,大小为1MB,这1MB的大小包含APB1APB2和AHB上所有外设的寄存器,外设位带区经过膨胀后的位带别名区地址为:0X42000000~0X43FFFFFF,大小为32MB
外设位带别名区地址
对于片上外设位带区的某个比特,记它所在字节的地址为A,位序号为 n(0<=n<=7),则该比特在别名区的地址为:
AliasAddr=0x42000000+ (A-0x40000000)*8*4 +n*4
或者写成:
AliasAddr=0x42000000+ (A-0x40000000)<<5 +n<<2
其中,0X42000000是外设位带别名区的起始地址,0x40000000是外设位带区的起始地址,(A-0x40000000)表示该比特前面有多少个字节,一个字节有8位,所以*8,一个位膨胀后是4个字节,所以*4,n表示该比特在A地址的序号,因为一个位经过膨胀后是四个字节,所以*4。
统一公式
为了方便操作,我们可以把这两个公式合并成一个公式,把"位带地址+位序号"转换成别名区地址统一成一个宏。
// 把"位带地址+位序号"转换成别名地址的宏
#define BITBAND(addr,bitnum) ((addr & 0xF0000000)+0x02000000+((addr &0x000FFFFF)<<5)+(bitnum<<2))
其中:
• addr & 0xF0000000是为了区别SRAM还是外设,实际效果就是最高4位取出4或者2,
• addr & 0x000FFFFF 屏蔽了高12位,相当于减去0X200 00000或者0X400 00000,
最后我们就可以通过指针的形式操作这些位带别名区地址,最终实现位
带区的比特位操作。
// 把一个地址转换成一个指针
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
// 把位带别名区地址转换成指针
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
GPIO位带操作
外设的位带区,覆盖了全部的片上外设的寄存器,我们可以通过宏为每个寄存器的位都
定义一个位带别名地址,从而实现位操作。
以下以GPIO中ODR和IDR这两个寄存器的位操作举例:
从手册中我们可以知道ODR和IDR这两个寄存器对应GPIO基址的偏移是20和16,我们先实现这两个寄存器的地址映射,其中GPIOx_BASE在库函数里面有定义。
GPIO 寄存器映射
位带操作举例
//位带操作,实现51类似的GPIO控制功能
//具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr
&0x000FFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
//IO口地址映射
#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C
#define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808
#define LED0 PAout(0)// PA0LED0=0;
GPIO位操作
// 单独操作 GPIO的某一个IO口,
//n(0,1,2...16),n表示具体是哪一个IO口#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
相关文章:

《嵌入式系统》知识总结10:使用位带操作操纵GPIO
位操作 汇编层面 外设控制常要针对字中某个位(Bit)操作 以字节编址的存储器地址空间中,需要3步骤(读出-修改-写回) 1.(从外设)读取包含该位的字节数据 2. 设置该位为0或1、同时屏蔽其他位&am…...

leetcode 2.两数相加(链表操作)
题目描述跳转到leetcode 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外࿰…...
Jenkins是什么?以及Jenkins有哪些具体的应用呢?
Jenkins是一个流行的开源持续集成和持续交付(CI/CD)工具,它可以自动化构建、测试和部署软件项目。以下是Jenkins的一些具体应用场景: 1. 自动化构建和集成:Jenkins可以与代码版本控制系统(如Git、SVN&#…...
2023年数学建模:参数估计与假设检验:自助法(Bootstrap)详解
2023年9月数学建模国赛期间提供ABCDE题思路加Matlab代码,专栏链接(赛前一个月恢复源码199,欢迎大家订阅):http://t.csdn.cn/Um9Zd 目录 1. 引言 2. 自助法简介 3. 自助法在参数估计中的应用 3.1 原理...
华为OD机试真题 Java 实现【字符串通配符】【2022Q4 200分】
一、题目描述 问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。 要求: 实现如下2个通配符: :匹配0个或以上的字符(注:能被和?匹配的字符仅由英文字母和数字0到9组成,下同)?:匹配1个…...
Android 11.0 user模式下解除系统进入recovery功能的限制
1.前言 在11.0的系统rom定制化开发中,系统中recovery模式功能也是很重要的一部分,而在原生系统中,对于debug模式的产品,可以通过电源键和音量+键进入recovery模式, 但是在user模式下的产品,对于通过这种方式,进入recovery模式就受限制了,防止用户无操作为了产品安全等,…...

TDEngine3.0 环境安装、配置及使用经验总结
TDEngine3.0 环境安装、配置及使用经验总结 一、TDengine 介绍二、TDengine的下载三、TDengine Server安装及配置3.1 安装3.2 taos的参数配置3.3 启动3.4 taosAdapter 四、TDengine Client 安装4.1 linux客户端安装4.2 windows客户端安装 五、TDEngine3.x的使用总结 一、TDengi…...

Redis7实战加面试题-高阶篇(Redlock算法和底层源码分析)
当前代码为8.0版接上一步 当前文档源码,接上一篇博客 Redis7实战加面试题-高阶篇(手写Redis分布式锁) 逐步深入,引入Redlock 自研一把分布式锁,面试中回答的主要考点 1.按照UC里面java.util.concurrent.locks.Lock接口规范编写…...
保持Git历史提交整洁,解决冲突
比较常见的场景,在代码提交场景,自己的代码和master冲突了,直接拉取master 解决冲突,很方便快捷,但是这样就会将其他开发同学的commit 拉到我们的分支,团队的代码合入时,需要代码同学帮忙code r…...
CompletableFuture使用详解,多线程相关
CompletableFuture笔记 一. 创建异步任务二.异步回调处理三.多任务组合处理四.总结 原文: https://blog.csdn.net/zsx_xiaoxin/article/details/123898171 CompletableFuture是jdk8的新特性。CompletableFuture实现了CompletionStage接口和Future接口,前者是对后者…...

(3)NUC980 kenerl编译
解压 用到的配置文件位置: /NUC980-linux-4.4.y-master/arch/arm/configs/nuc980_defconfig 执行: 编译linux内核源码。了解其 配置文件在 arch/arm/configs/nuc980_defconfig (1) make nuc980_defconfig 载入配置文件 (2) make menuconfig --->Devi…...
华为OD机试真题 Java 实现【分奖金】【2022Q4 100分】
一、题目描述 公司老板做了一笔大生意,想要给每位员工分配一些奖金,想通过游戏的方式来决定每个人分多少钱。按照员工的工号顺序,每个人随机抽取一个数字。按照工号的顺序往后排列,遇到第一个数字比自己数字大的,那么,前面的员工就可以获得“距离 * 数字差值”的奖金。如…...

迅为国产化RK3588开发板在安防前后端应用解决方案
K3588是瑞芯微推出的一款高性能处理器,针对安防领域的应用具备强大的计算能力和图像处理能力。下面是关于RK3588的安防前后端应用解决方案的介绍: 前端摄像头端: 高清视频采集:利用RK3588处理器的高性能图像处理能力,…...

Windows 安装 GCC
文章目录 GCC 是什么?GCC 和 gcc 什么关系?Windows 安装 GCC选型下载安装配置环境变量验证 参考文献 GCC 是什么? GCC(GNU Compiler Collection)是一个开源的编译器套件,由 GNU 项目开发和维护。 GNU 编译…...

下载安装LabVIEW
下载安装LabVIEW 介绍下载安装流程下载安装 后续 介绍 LabVIEW 是 工程 师 用来 开发 自动 化 研究、 验证 和 生产 测试 系统 的 图形 化 编 程 环境。Labview作为图形化编程语言,图形控件拖拽式编程,显得更加直观形象,也很容易上手学习。 …...

从C语言到C++_14(vector的常用函数+相关选择题和OJ题)
目录 1. vector的常用函数 1.1 vector 的介绍 1.2 vector 的初始化 1.3 vector 的操作和遍历 1.4 vector 的容量和增删查改 2. vector 相关笔试题 3. vector 相关OJ题 136. 只出现一次的数字 - 力扣(LeetCode) 解析代码: 118. 杨辉…...
Java NIO-非阻塞I/O(二)
文章目录 1. SocketChannel2. ServerSocketChannel2. Channels类3. 异步通道(Java 7)4. Socket选项5. 就绪选择6. Selector类7. SelectionKey类 1. SocketChannel 通道将缓冲区的数据块移入或移出到个汇总给你I/O,如文件、Socket、数据报等。…...

PaaS平台iuap——数智底座支撑企业的全球化业务拓展
数智化转型是全球化企业非常关注的话题,数智化转型过程中suo 面临的问题与挑战也绝非一套简单的产品能够解决的,必须配合组织、人员、目标制度采用达成目标。iuap平台是整个企业数智化转型的底座,形象来说是我们的土壤,在这个土壤…...
RK3318 android12 HEVC-1080P 4K VP9等格式视频播放不了
同样视频在同样硬件在android10的固件刷机测试播放正常 在android12播放失败,在媒体中心点开视频直接闪退了 在android10 能播放4K视频, 我对比了ddr频率 cat /d/clk/clk_summary | grep ddr android10 clk_ddrmon 0 0 0 24000000 0 0 50000 pclk_ddr 3 3 0 61440000 0 0 5…...
gpt技术简介以及具体应用领域
GPT(Generative Pre-trained Transformer)是一种基于Transformer架构的生成式预训练模型。它是由OpenAI开发的一系列语言模型,其中最著名的是GPT-3。GPT模型通过在大规模文本数据上进行自监督预训练,学习了大量语言知识和语言模式…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...

dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...