《嵌入式系统》知识总结10:使用位带操作操纵GPIO

news2024/11/23 11:25:08

位操作

汇编层面

外设控制常要针对字中某个位(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)// PA0

LED0=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)  //输入

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信小程序 <view></view>容器嵌套,wxss样式修改内部内部样式不产生效果

网上关于”微信小程序讲的知识很少“&#xff0c;微信开发文档对于新手不是很友好&#xff0c;但是建议一定要学会看文档。 问题如下&#xff1a; 我写了好几个<view></view> 容器嵌套&#xff0c;我在对内部容器包括的内容做修改时&#xff0c;不产生效果&#…

apache RocketMQ远程代码执行(CVE-2023-33246)

RocketMQ是阿里巴巴在2012年开发的分布式消息中间件&#xff0c;专为万亿级超大规模的消息处理而设计&#xff0c;具有高吞吐量、低延迟、海量堆积、顺序收发等特点。它是阿里巴巴双十一购物狂欢节和众多大规模互联网业务场景的必备基础设施。 RocketMQ的NameServer、Broker、…

【计算机网络之HTTP篇】Cookie与Session的区别

目录 Cookie 原理 缺点 Session 原理 区别 Cookie cookie是浏览器在本地存储数据的一种机制。 原理 当浏览器向服务器第一次发送请求时&#xff0c;服务器会向浏览器返回一个Cookie&#xff0c;此时 cookie记录着浏览器访问服务器的用户登录状态。 后续浏览器再次访问服…

[深度学习入门案例1]基于Keras的手写数字图像识别

文章目录 一、工具与环境 二、深度学习环境的搭建 1.安装Anaconda 2.创建虚拟环境 第1步&#xff1a;打开Anaconda的命令窗口&#xff0c;即Anaconda Prompt 第2步&#xff1a;使用命令创建指定版本的python环境&#xff08;这里以py36命令环境名称举例&#xff09; 3.切换…

深度解析MethodHandle方法句柄之findspecial方法的原理

网上看过太多关于MethodHandle方法句柄的文章&#xff0c;但是基本上没有人能把其中的findspecial方法讲清楚&#xff0c;特别是findspecial的第四个参数specialCaller, 相信大家都不明白是干嘛用的&#xff0c;网上给出的水文是很多都是说&#xff1a; 执行到specialCaller的父…

kafka二

练一练 需求&#xff1a;写一个生产者&#xff0c;不断的去生产用户行为数据&#xff0c;写入到kafka的一个topic中 生产的数据格式&#xff1a; 造数据 {"guid":1,"eventId":"pageview","timestamp":1637868346789} isNew 1 {&quo…

面了一个32岁的程序员,只因这一点,一眼看穿是培训班出来的,简历都是假的.....

首先&#xff0c;我说一句&#xff1a;培训出来的&#xff0c;优秀学员大有人在&#xff0c;我不希望因为带着培训的标签而无法达到用人单位和候选人的双向匹配&#xff0c;是非常遗憾的事情。 最近&#xff0c;在网上看到这样一个留言&#xff0c;引发了程序员这个圈子不少的…

Kafka安装及架构

kafka的特点 高吞吐量、低延迟&#xff1a;kafka每秒可以处理几十万条消息&#xff0c;它的延迟最低只有几毫秒&#xff0c;每个topic可以分多个partition, 由多个consumer group 对partition进行consume操作。可扩展性&#xff1a;kafka集群支持热扩展持久性、可靠性&#xf…

机智云的离线语音识别模组,让家电变得更加智能和便捷

随着人们对智能化生活的需求不断增加&#xff0c;离线语音模组越来越受到欢迎。它可以为家庭、工作和娱乐提供更加智能和便捷的服务&#xff0c;例如通过语音指令控制家居设备、查询天气信息、播放音乐等。 “小智同学&#xff0c;打开灯光” “调到最亮” “正转一档” 人工智…

Golden Gate (GGX) ZK 预编译: 彻底改变游戏玩法,成本降低千倍

Golden Gate (GGX) 作为一种新型跨链基础设施协议&#xff0c;解决了困扰 Web3.0 Layer1 和 Layer2 的跨链通信和流动性转换难题。 其解决方案主要涉及两个核心: 1) 与协议无关的通信&#xff0c;可以实现主流标准消息的传递&#xff0c;包括 IBC、XCMP 和 LayerZero 等标准。 …

2023 华为 Datacom-HCIE 真题题库 10/12--含解析

单项选择题 1.[试题编号&#xff1a;190585] &#xff08;单选题&#xff09;华为SD-WAN解决方案中&#xff0c;当CPE位 于NAT设备后的私网时&#xff0c;特别是两个站点的CPE同时位于NAT设备后的私网时&#xff0c;CPE之 间需要使用NAT穿越技术。华为SD-WAN解决方案中使用以下…

驱动开发--根文件系统

1、单片机开发属于嵌入式开发吗&#xff1f; 广义&#xff1a;单片机开发属于嵌入式开发---&#xff08;嵌入式微处理器开发&#xff09; 一般不带mmu&#xff08;地址映射&#xff09; 狭义&#xff1a;单片机开发不属于嵌入式 ---&#xff08;Linux嵌入式开发&#xff09;一…

python数据分析学习笔记之matplotlib、numpy、pandas

为了学习机器学习&#xff0c;在此先学习以下数据分析的matplotlib&#xff0c;numpy&#xff0c;pandas&#xff0c;主要是为自己的学习做个记录&#xff0c;如有不会的可以随时查阅。希望大家可以一起学习共同进步&#xff0c;我们最终都可以说&#xff1a;功不唐捐&#xff…

刷完这套八股文,15K不能再少了...

前言 大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;得准备面试了&#xff0c;又不知道从何下手&#xff01;为了帮大家节约时间&#xff0c;特意准备了一份面试相关的资料&#xff0c;内容非常的全面&#xff0c;真的可以好好补一补&#xff0c;希望大家在都能拿…

hive中如何计算字符串中表达式

比如 select 1(2-3)(-4.1-3.1)-(4-3)-(-3.34.3)-1 col ,1(2-3)(-4.1-3.1)-(4-3)-(-3.34.3)-1 result \ 现在的需求式 给你一个字符串如上述col 你要算出result。 前提式 只有和-的运算&#xff0c;而且只有嵌套一次 -(4-3)没有 -(-4(3-(31)))嵌套多次。 第一步我们需要将运…

springboot项目的社区/博客系统

课前导读&#xff1a; 你学完一篇&#xff0c;你就多会一项技能&#xff0c;多多少少对你还是有点帮助的不是吗&#xff1f;~~~ 这是博主网页的url&#xff1a;优文共享社区 开发环境&#xff1a;JDK1.8&#xff0c;IDEA2021&#xff0c;MySQL5.7&#xff0c;Windows11 开发技术…

float变量与“零值”的比较

目录 1.问题的引出&#xff1a; 2.解决方案 <1>:自定义精度 <2>:系统提供的精度 3.总结 1.问题的引出&#xff1a; 浮点数在存储的时候&#xff0c;会存在精度的损失。 那么在浮点数进行比较的时候&#xff0c;可不可以使用 来进行比较&#xff0c;测试代码…

PHP——流程控制语句

if…else语句 几乎所有程序设计语言都有if语句&#xff0c;它按照条件选择执行不同的代码片段&#xff0c;PHP的if语句格式为 if&#xff08;条件&#xff09; {if 条件返回为TRUE执行的语句体; } else {if 条件返回FALSE执行的语句体&#xff1b; } 如果条件为真&#xff0c;就…

GitOps 最佳实践(下)| 基于 Amazon EKS 构建 CI/CD 流水线

了解了 GitOps 的概念以及 CI/CD 流水线的架构&#xff0c;完成了构建 GitOps 风格的 CI/CD 流水线的前两部分&#xff0c;恭喜开发者们&#xff01;我们一起在 GitOps 最佳实践的道路上已经实现了大半。接下来&#xff0c;我们一起看看构建 CI/CD 流水线最佳实践的后两个部分&…

I/O复用———常用系统调用select、poll、epoll

上周面了个实习&#xff0c;感觉自己菜的一匹&#xff0c;唉&#xff0c;理论还是没有联系实际啊&#xff0c;继续学吧。 I/O复用使得程序能同时监听多个文件描述符&#xff0c;这对提高程序的性能至关重要。通常&#xff0c;网络程序在下列情况下需要使用I/O复用技术&#xf…