【STM32】位带操作

embedded/2024/9/20 1:29:29/ 标签: stm32, 嵌入式硬件, 单片机

一、位带操作

1.意义

回想以前写51代码

​ P0 = 0x10; //将P0端口设置为0x10 P1_0=1; //将P1端口0号引脚设置为高电平 a = P2_2; //获取P2端口2号引脚的电平

根据上述的方法,我们可以发现快速定位修改某个引脚的电平还有获取引脚的状态

2.原因

GPIO_SetBits、GPIO_ResetBits、GPIO_WriteBit操作IO口的性能没有达到极致,因为这些函数都需要进行现场保护和现场恢复的动作,比较耗时间,没有进行一步到位,使用位带操作则没有上述的烦恼,简单快速!

示例1:

 GPIO_SetBits(GPIOF,GPIO_Pin_9); 修改为 PFout(9)=1;              

示例2:

GPIO_ResetBits(GPIOF,GPIO_Pin_9); 修改为 PFout(9)=0;          

因为使用对引脚设置电平或读取电平,库函数效率是不高的,很难应付高性能的场合,如下代码,修改某引脚电平要执行起码3行代码,还不包括隐含的调用函数与函数返回的过程。

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{   /* Check the parameters */                        		assert_param(IS_GPIO_ALL_PERIPH(GPIOx));   	           	   assert_param(IS_GPIO_PIN(GPIO_Pin));    GPIOx->BSRRL = GPIO_Pin; 
}   

寄存器地址分析

在这里插入图片描述

二、《Cortex M3与M4权威指南》章节6.7 P206

1.背景

位带操作常用于I/O高度密集访问的芯片。

在这里插入图片描述

Bit-band operation support allows a single load/store operation to access (read/write) to a single data bit. In the Cortex-M3 and Cortex-M4 processors, this is supported in two pre-defined memory regions(静态映射) called bit-band regions. One of them is

在这里插入图片描述

There are two regions of memory for bit-band operations:

• 0x20000000~0x200FFFFF (SRAM, 1MB)

0x40000000~0x400FFFFF (Peripherals, 1MB)

2.映射表

在这里插入图片描述

在这里插入图片描述

3.公式

关于IO引脚对应的访问地址,可以参考以下公式寄存器的位带别名地址 = 0x42000000 + (寄存器的地址-0x40000000)32 + 引脚编号x

三、寄存器地址与别名地址转换技巧

1.确定某端口访问起始地址,如端口F访问起始地址为GPIOF_BASE

#define GPIOF               ((GPIO_TypeDef *) GPIOF_BASE)
typedef struct
{__IO uint32_t MODER;    /*!< GPIO port mode register,               Address offset: 0x00      */__IO uint32_t OTYPER;   /*!< GPIO port output type register,        Address offset: 0x04      */__IO uint32_t OSPEEDR;  /*!< GPIO port output speed register,       Address offset: 0x08      */__IO uint32_t PUPDR;    /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */__IO uint32_t IDR;      /*!< GPIO port input data register,         Address offset: 0x10      */__IO uint32_t ODR;      /*!< GPIO port output data register,        Address offset: 0x14      */__IO uint16_t BSRRL;    /*!< GPIO port bit set/reset low register,  Address offset: 0x18      */__IO uint16_t BSRRH;    /*!< GPIO port bit set/reset high register, Address offset: 0x1A      */__IO uint32_t LCKR;     /*!< GPIO port configuration lock register, Address offset: 0x1C      */__IO uint32_t AFR[2];   /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
} GPIO_TypeDef;

2.根据要访问的寄存器地址计算偏移值,如计算

GPIOF的ODR寄存器地址 = GPIOF_BASE+0x14;

3.根据以下公式进行换算

​ 寄存器的位带别名地址 = 0x42000000 + (寄存器的地址-0x40000000)32 + 引脚编号4

详细示意图参考如下:

在这里插入图片描述

4.PF9引脚的位带别名地址

示例1:

   uint32_t *PF9_BitBand = (uint32_t *)(0x42000000 + (GPIOF_BASE + 0x14 - 0x40000000)*32 + 9*4);               

示例2:

uint32_t *PF9_BitBand   = (uint32_t *)(0x42000000 + ((uint32_t)&GPIOF->ODR - 0x40000000)*32 + 9*4);

四、代码调整

将端口的访问封装为Pxout、Pxin,例如端口F引脚电平设置PFout,端口A引脚电平读取PAin。

#define PFout(x) *(volatile uint32_t *)(0x42000000 + (GPIOF_BASE + 0x14 - 0x40000000)32 + x4)

#define PAin(x) *(volatile uint32_t *)(0x42000000 + (GPIOA_BASE + 0x10 - 0x40000000)32 + x4)

五、编译优化

5.1 优化等级

优化:编译器想尽办法去压缩程序存储空间,提高运行速度。类比:新的电脑安装一个win10,默认的win10的存储空间占用是比较大、运算速度不是最快,会安装一些优化软件来优化win10,优化过后,会发现系统盘剩余空间增加了,win10的运行速度也增加了。

gcc 预处理 汇编 未链接的二进制文件 可执行程序

一般编译器,优化有多个等级:-O0、-O1、-O2、-O3。

-O0:缺省优化级别,一般情况下不压缩程序存储空间,不提高程序运行速度,保证程序的可靠执行。

-O1:轻度优化,轻度压缩程序存储空间,轻度优化程序运行速度。

-O2:推荐优化等级,在程序存储空间和程序运行速度取得平衡点。

-O3:最高级别的优化等级,有可能导致程序不能运行,也会使用以空间换时间的方法,导致程序体积增大。

示例1:-O0

在这里插入图片描述

示例1:-O2

在这里插入图片描述

按键例子1,任何时刻按下按键,灯无法响应:

​ #define PAin(n) *((uint32_t *)(0x42000000 + (((uint32_t)&GPIOA->IDR) - 0x40000000)*32 + (n)*4)) PFout(9) = PAin(0); 经过编译阶段,会得到恒定的结果。 PFout(9)=1;

按键例子2,任何时刻按下按键,灯能够立即响应点亮或熄灭:

              

六、volatile关键字

1.应用场景

volatile关键字分析,往往应用在三种场合

1)多线程编程共享全局变量的时候,该全局变量要加上volatile进行修饰,让编译器不要省略该变量的访问。

2)裸机编程的时候,某函数与中断服务函数共享全局变量的时候,该全局变量要加上volatile进行修饰,让编译器不要省略该变量的访问。

3)ARM定义寄存器的时候,寄存器是指向一个地址,要加上volatile进行修饰,让编译器不要优化而省略该变量的访问。

编译器不要优化该变量指的是防止编译器出现优化过度,导致代码运行失效。

加上volatile关键字生成的汇编代码会发生明显的变化,同样调用delay函数,灯的速度发生变化!

2.delay函数在-O2等级,是否添加volatile关键字,反汇编分析。

七、仿真调试

仿真调试实时跟踪代码的运行,程序出现问题并能跟踪到问题所在。能够观察变量的变化、逐步执行代码。

在这里插入图片描述


http://www.ppmy.cn/embedded/105161.html

相关文章

Ubuntu 22.04 镜像自定义制作

Centos封装镜像> Linux Centos ISO镜像自定义制作 Ubuntu20.04封装镜像> Ubuntu 20.04 镜像自定义制作 1、下载镜像 系统环境&#xff1a;ubuntu 22.04 镜像地址&#xff1a;https://mirrors.aliyun.com/ubuntu-releases rootubuntu:~# apt install -y p7zip xorriso ro…

Python进阶08-爬虫

零、文章目录 Python进阶08-爬虫 1、爬虫介绍 &#xff08;1&#xff09;爬虫是什么 **网络爬虫:**又被称为网页蜘蛛&#xff0c;网络机器人&#xff0c;是一种按照一定的规则&#xff0c;自动地抓取网络信息的程序或者脚本&#xff0c;另外一些不常使用的名字还有蚂蚁、自…

应用层(Web与HTTP)

目录 常见术语 1.HTTP概况 2.HTTP连接 非持久HTTP流程 响应时间模型 持久HTTP 3.HTTP报文 3.1HTTP请求报文 3.2HTTP响应报文 HTTP响应状态码 4.Cookies&#xff08;用户-服务器状态&#xff09; cookies&#xff1a;维护状态 Cookies的作用 5.Web缓冲&#xff08;…

视频智能分析打手机检测算法安防监控打手机检测算法应用场景、算法源码、算法模型介绍

随着智能手机的普及&#xff0c;手机已成为人们生活中不可或缺的一部分。然而&#xff0c;在某些场合&#xff0c;如驾驶、会议、学校课堂等&#xff0c;不当使用手机可能会导致安全隐患或干扰他人。因此&#xff0c;开发出一种能够准确识别并阻止不当使用手机的行为检测算法显…

TPM管理咨询公司一走,企业又恢复原样,为什么?

在探讨“TPM管理咨询公司离开后&#xff0c;企业为何常常恢复原样”这一深刻问题时&#xff0c;我们不得不深入剖析TPM理念的本质、实施过程中的挑战以及企业在持续变革中面临的普遍困境。TPM作为一种以最大化设备综合效率为目标的生产维护体系&#xff0c;其核心理念在于通过全…

C++ 消息分发类:详细示例应用

消息分发的概念 消息分发&#xff08;Message Dispatching&#xff09;是一种设计模式&#xff0c;广泛用于处理异步事件和消息。在 C 中&#xff0c;消息分发类通常用来接收和分发来自多个源的消息&#xff08;如网络连接、传感器数据、用户输入等&#xff09;&#xff0c;并根…

如何使用 Canvas 和 Paint 进行绘制,以及如何处理自定义属性和解析 XML 属性

在 Android 中&#xff0c;自定义 View 的绘制通常涉及使用 Canvas 和 Paint 两个关键类。Canvas 提供了一个用于绘制图形的界面&#xff0c;而 Paint 则用来定义绘制的风格和颜色。以下是如何使用 Canvas 和 Paint 进行绘制的步骤&#xff0c;以及如何处理自定义属性和解析 XM…

Flink 1.14.* Flink窗口创建和窗口计算源码

解析Flink如何创建的窗口&#xff0c;和以聚合函数为例&#xff0c;窗口如何计算聚合函数 一、构建不同窗口的build类1、全局窗口2、创建按键分流后的窗口 二、在使用窗口处理数据流时&#xff0c;不同窗口创建的都是窗口算子WindowOperator1、聚合函数实现2、创建全局窗口(入参…

APP长文本内容编辑器功能实现方案

背景 CSDN APP 中原有编辑器页面为纯H5适配&#xff0c;整体用户交互体验差&#xff0c;如何优化APP端编辑器用户体验是我们团队需要思考的问题。下面我们以iOS为例展开讨论。 一、方案调研 我们分析了几款国内内容发布的APP&#xff0c;如知乎、今日头条、简书&#xff0c;…

深度学习100问46:什么是Dropout

嘿&#xff0c;你知道吗&#xff1f;在深度学习的奇妙世界里&#xff0c;有个超厉害的家伙叫 Dropout。 想象一下&#xff0c;你正在建造一个超级复杂的神经网络&#xff0c;就像搭建一座巨大的城堡。但有时候这座城堡可能会变得太娇气&#xff0c;只认得它见过的特定东西&am…

【CF补题数学裴蜀定理】 div969 C Dora and C++

Dora and C 分析&#xff1a; 对于两个数x,y 我们想要通过如下操作使得他们的差变得尽可能小 我们要如何操作&#xff1f; 这个操作也就是相当于 d e l ∣ y − x ∣ − k 1 ∗ x − k 2 ∗ y del|y-x|-k_1*x-k_2*y del∣y−x∣−k1​∗x−k2​∗y&#xff0c;让这个差值最小…

【TomCat】安装部署

首先得进行Java的安装和部署java1.8对应tomcat9 TomCat下载Apache Tomcat - Apache Tomcat 10 Software Downloads

yolo-world开放词汇检测onnxruntime和tensorrt推理

onnxruntime推理 导出onnx模型&#xff1a; from ultralytics import YOLOWorld,YOLO model YOLOWorld(yolov8s-worldv2.pt) model.set_classes(["glasses","shoes"]) model.save("yolo_world.pt") model YOLO(yolo_world.pt) model.export(…

记录 PyQt6 / PySide 6 自定义边框窗口的 Bug 及可能可行的解决方案:窗口抖动和添加 DWM 环绕阴影的大致原理

前言&#xff1a; 本篇文章将要讨论我在前不久发表的关于 PyQt6 / PySide6 自定义边框窗口代码及内容中的问题&#xff1a; &#xff08;终&#xff09;PyQt6 / PySide 6 Pywin32 自定义标题栏窗口 完全还原 Windows 原生窗口边框特效_pyside6 win32 无边框窗口-CSDN博客ht…

AOP和注解的配合使用(封装通用日志处理类)

自定义注解 Inherited Documented Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) public interface MyLog {String value() default ""; } 定义切面 Aspect Component Slf4j public class LogAop {// 定义识别自定义注解的切点Pointcut("a…

Spring优缺点和SpringBoot基础和搭建

前言 Spring框架是一个流行的Java企业级开发框架&#xff0c;旨在简化应用程序开发。它的核心特性包括依赖注入和面向切面编程&#xff0c;提供了灵活性和强大的社区支持。然而&#xff0c;Spring也存在学习曲线陡峭和配置复杂等缺点。 Spring Boot是基于Spring的项目&#x…

Linxu系统之Mysql数据库练习【完整版】

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/cat…

pdf转cad软件,5款快速上手转换软件分享

在当今快节奏的工作环境中&#xff0c;图纸文件的格式转换成为设计师、工程师等职业群体日常工作中不可或缺的一环。尤其是将PDF文件转换为CAD格式&#xff0c;不仅能够提升工作效率&#xff0c;还能确保设计数据的准确性和可编辑性。下面给大家分享5款能够快速上手转换软件&am…

计算机毕业设计选题推荐-在线培训平台-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

相似哈希技术在溯源分析中的应用

随着软件开发的日益复杂化和全球化&#xff0c;代码复用和变体生成变得愈发普遍&#xff0c;导致在不同项目之间追踪代码的来源和演变变得更加困难。在这种背景下&#xff0c;相似哈希技术&#xff08;Simhash, Minhash等&#xff09;成为溯源分析中的一项关键工具&#xff0c;…