《嵌入式系统》知识总结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模型通过在大规模文本数据上进行自监督预训练,学习了大量语言知识和语言模式…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式
简介 在我的 QT/C 开发工作中,合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式:工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...
从物理机到云原生:全面解析计算虚拟化技术的演进与应用
前言:我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM(Java Virtual Machine)让"一次编写,到处运行"成为可能。这个软件层面的虚拟化让我着迷,但直到后来接触VMware和Doc…...
32单片机——基本定时器
STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…...
接口 RESTful 中的超媒体:REST 架构的灵魂驱动
在 RESTful 架构中,** 超媒体(Hypermedia)** 是一个核心概念,它体现了 REST 的 “表述性状态转移(Representational State Transfer)” 的本质,也是区分 “真 RESTful API” 与 “伪 RESTful AP…...
