004 - STM32固件库GPIO(三)位带操作

news2024/11/28 14:40:51

目前掌握的对GPIO引脚的输入输出操作只能使用BSRRL/H、I/ODR寄存器,记得以前学51的时候,对于引脚的输入输出可以采用关键字sbit实现位定义,例如

sbit LED1 = P1^3;

在STM32中没有类似于sbit一样的关键字,但是提供了位带操作来实现类似于51的为才做。
在这里插入图片描述
图中可以看到,STM32在两个地方实现了位带。一个是SRAM区,另外一个是Peripherals(外设)区,以外设区为例,可以看到外设区位带实际占1MB空间,前面学习的寄存器操作都是在这个空间内操作的,对应的将外设的空间膨胀32倍,膨胀后的空间就是外设的位带别名区。
外设的寄存器位带区空间为0x400000000 ~ 0x400F0000,这1MB的空间包含了APB1/2和AHB1上所有外设的寄存器,AHB2/3总线上的寄存器没有包含在内。经过膨胀后,外设位带别名区的地址范围为0x42000000 ~ 0x43FFFFFF。
SRAM的不在这里说明,具体可以参照上图结合外设位带别名区的办法进行分析。
位带别名区地址的计算
片上外设的位带区某个寄存器的地址为A,位序号为n(0 ≤ n ≤ 7),那么这个寄存器的位带别名区地址应该为:

AliasAddr = 0x42000000+(A-0x40000000) * 8 * 4 + n * 4

例如F429开发板上的PH10的ODR寄存器 A = GPIOH_BASE+0x14,n = 10,那么其位带别名区的地址是:

Alias_Ph10_ODR= 0x42000000 + ( GPIOH_BASE + 0x14 -0x40000000) * 8 * 4 + 10 * 4

另外,这里给出SRAM的位带别名区的计算公式:

AliasAddr = 0x22000000+(A-0x20000000) * 8 * 4 + n * 4

整合一下,外设和SRAM可以用一个统一公式来计算位带别名区的地址:

/*addr为外设寄存器地址,bitnum为位号(0 ≤ n ≤ 7)*/
AliasAddr = (addr & 0xF0000000) + 0x02000000 + ((addr & 0x000FFFFF) << 5) + (bitnum << 2)

公式分析:
①、addr & 0xF0000000是为了区别当前计算的是外设区还是SRAM区,比如地址为0x40006789,那么与0xF0000000与运算后,得结果为0x40000000,再加上0x02000000就等于0x42000000,那么就得出来这个寄存器为外设区寄存器,如果是0x22000000,那么就是SRAM区寄存器等同于原始公式中的0x42000000或者0x22000000
②、addr & 0x000FFFFF则是屏蔽高三位,取出低五位的地址,0x40006789计算后,取出值为0x06789,等同于原始公式中的A-0x40000000或者A-0x20000000
③、<< 5<< 2则是通过位运算分别提到了* 8 * 4* 4
用以上公式转出的位带别名区地址还不能立即使用,此时转换出来的地址是个立即数,并不能当作地址去使用,需要进行转换,这里用两个宏进行最终的操作:

//计算位带别名区地址,并转换为地址指针
#define BITBAND(addr,bitnum)    (*(__IO unsigned long *)((addr & 0xF0000000) + 0x2000000+((addr & 0xFFFFF) << 5) + (bitnum << 2))) 

//最终操作的寄存器
#define BIT_ACTION(addr,bitnum)   BITBAND(addr,bitnum)

位带操作的内容基本就这些,不太明白的话可以在看一下完整的程序。
bitband.h

#ifndef __BSP_BIT_BAND_H__
#define __BSP_BIT_BAND_H__

#include "stm32f4xx.h"
#include "stm32f4xx_rcc.h"

//计算位带别名区地址
#define BITBAND(addr,bitnum)    (*(__IO unsigned long *)((addr & 0xF0000000) + 0x2000000+((addr & 0xFFFFF) << 5) + (bitnum << 2))) 

#define BIT_ACTION(addr,bitnum)   BITBAND(addr,bitnum)

/*A-H端口ODR地址*/
#define GPIOA_ODR_ADDR  (GPIOA_BASE+0x14)
#define GPIOB_ODR_ADDR  (GPIOB_BASE+0x14)
#define GPIOC_ODR_ADDR  (GPIOC_BASE+0x14)
#define GPIOD_ODR_ADDR  (GPIOD_BASE+0x14)
#define GPIOE_ODR_ADDR  (GPIOE_BASE+0x14)
#define GPIOF_ODR_ADDR  (GPIOR_BASE+0x14)
#define GPIOG_ODR_ADDR  (GPIOG_BASE+0x14)
#define GPIOH_ODR_ADDR  (GPIOH_BASE+0x14)

/*A-H端口IDR地址*/
#define GPIOA_IDR_ADDR  (GPIOA_BASE+0x10)
#define GPIOB_IDR_ADDR  (GPIOB_BASE+0x10)
#define GPIOC_IDR_ADDR  (GPIOC_BASE+0x10)
#define GPIOD_IDR_ADDR  (GPIOD_BASE+0x10)
#define GPIOE_IDR_ADDR  (GPIOE_BASE+0x10)
#define GPIOF_IDR_ADDR  (GPIOR_BASE+0x10)
#define GPIOG_IDR_ADDR  (GPIOG_BASE+0x10)
#define GPIOH_IDR_ADDR  (GPIOH_BASE+0x10)

/*A-H端口输出宏*/
#define PAout(n)    BIT_ACTION(GPIOA_ODR_ADDR,n)
#define PBout(n)    BIT_ACTION(GPIOB_ODR_ADDR,n)
#define PCout(n)    BIT_ACTION(GPIOC_ODR_ADDR,n)
#define PDout(n)    BIT_ACTION(GPIOD_ODR_ADDR,n)
#define PEout(n)    BIT_ACTION(GPIOE_ODR_ADDR,n)
#define PFout(n)    BIT_ACTION(GPIOF_ODR_ADDR,n)
#define PGout(n)    BIT_ACTION(GPIOG_ODR_ADDR,n)
#define PHout(n)    BIT_ACTION(GPIOH_ODR_ADDR,n)

/*A-H端口输入宏*/
#define PAin(n)    BIT_ACTION(GPIOA_IDR_ADDR,n)
#define PBin(n)    BIT_ACTION(GPIOB_IDR_ADDR,n)
#define PCin(n)    BIT_ACTION(GPIOC_IDR_ADDR,n)
#define PDin(n)    BIT_ACTION(GPIOD_IDR_ADDR,n)
#define PEin(n)    BIT_ACTION(GPIOE_IDR_ADDR,n)
#define PFin(n)    BIT_ACTION(GPIOF_IDR_ADDR,n)
#define PGin(n)    BIT_ACTION(GPIOG_IDR_ADDR,n)
#define PHin(n)    BIT_ACTION(GPIOH_IDR_ADDR,n)

#endif  /* __BSP_BIT_BAND_H__ */

bsp_key.c中增加按键检测扫描函数Key1_Scan()和Key2_Scan()

uint8_t Key1_Scan(void)
{

        if(PAin(0) == KEY_ON)	        //判断按键是否按下
        {
            while(PAin(0) == KEY_ON);	//消抖,等待按键释放
            return KEY_ON;
        }
        else
            return KEY_OFF;
}

uint8_t Key2_Scan(void)
{
        if(PCin(13) == KEY_ON)       	//判断按键是否按下
        {
            while(PCin(13) == KEY_ON);   //消抖,等待按键释放
            return KEY_ON;
        }
        else
            return KEY_OFF;
}

main.c

#include "stm32f4xx.h"
#include ".\LED\bsp_led.h"
#include ".\KEY\bsp_key.h"
#include ".\BIT_BAND\bsp_bit_band.h"


int main(void)
{
    LED_Config();    
    Key_Config();   
    while(1)
    {
        if(Key1_Scan() == KEY_ON)		//K1按键检测
        {
            PHout(10) = 0;				//红灯亮
        }
        if(Key2_Scan() == KEY_ON)		//K2按键检测
        {
            PHout(10) = 1;				//红灯灭
        }       
    }
}

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

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

相关文章

ARM的状态传送器指令、软中断指令与协处理指令(软中断具体实现)

1.状态寄存器传送指令: 作用&#xff1a;访问&#xff08;读写&#xff09;CPSR寄存器 CPSR寄存器结构图&#xff1a; 前八位的作用&#xff1a; Bit[4:0] &#xff1a;不同的电平组合表示不同的模式&#xff0c;[10000]User [10001]FIQ [10010]IRQ [10011]SVC …

【Hadoop】二、Hadoop MapReduce与Hadoop YARN

文章目录 二、Hadoop MapReduce与Hadoop YARN1、Hadoop MapReduce1.1、理解MapReduce思想1.2、Hadoop MapReduce设计构思1.3、Hadoop MapReduce介绍1.4、Hadoop MapReduce官方示例1.5、Map阶段执行流程1.6、Reduce阶段执行流程1.7、Shuffle机制 2、Hadoop YARN2.1、Hadoop YARN…

导入源码至Android Studio

导入源码至Android Studio 参考&#xff1a; Android源码环境搭建&#xff08;aosp Ubuntu 16.04&#xff09; 使用如下的步骤&#xff1a; 1.. build/envsetup.sh (source可以用 .代替&#xff0c;即". build/envsetup.sh") 2.lunch&#xff0c;并选择要编译的项…

jmeter请求Sse长链接接口

文章目录 1.背景1.1 什么是SSE接口 2. **解决思路-尝试方法⬇️&#xff1a;**2.1 &#x1f3f3;️‍&#x1f308; **postman-sse请求结果**2.2 **⚡ jmeter报错**2.3 ☀️**封装此SSE接口**2.3.1 ❌httpclient2.3.2 ❌HttpURLConnection2.3.3 ✔️okhttp3 3. jmeter-beanshel…

跟我一起使用 compose 做一个跨平台的黑白棋游戏(3)状态与游戏控制逻辑

前言 在上一篇文章中&#xff0c;我们已经完成了黑白棋的界面设计与编写&#xff0c;今天这篇文章我们将完成状态控制和游戏逻辑代码的编写。 正如第一篇文章所述&#xff0c;在本项目中&#xff0c;我们需要实现不依赖于平台的状态管理&#xff0c;也就是使用 Flow 和 compo…

浏览器扩展一些好用插件

给浏览器添加一些插件功能&#xff0c;能够让我们用的更方便&#xff0c;开发中非常实用&#xff0c;下面直接开始 我们这里选择的是微软自带的Microsoft Edge浏览器&#xff08;谷歌也行。这两款浏览器都是非常好用的&#xff09; 我们打开浏览器找到扩展应用这个&#xff0c;…

opencv 中值滤波

中值滤波是一种常用的图像滤波算法&#xff0c;是在像素点周围进行多个点的中值滤波&#xff0c;将点的灰度值根据其周围像素点的灰度值进行平均&#xff0c;并使这些点的灰度值具有相似性&#xff0c;以达到平滑去噪的目的。中值滤波在图像处理中应用广泛&#xff0c;在图像滤…

利用java编写的项目设备调配系统代码示例(内含5种设备调配的算法)

利用java编写的项目设备调配系统代码示例&#xff08;内含5种设备调配的算法&#xff09; 一、设备调配方案二、设备匹配算法三、代码实现&#xff08;java&#xff09; 最近在做一个项目设备调配系统&#xff0c;分享一些干货&#xff01;&#xff01;&#xff01; 一、设备…

Godot引擎 4.0 文档 - 入门介绍 - Godot 关键概念概述¶

本文为Google Translate英译中结果&#xff0c;DrGraph在此基础上加了一些校正。英文原版页面&#xff1a;Overview of Godots key concepts — Godot Engine (stable) documentation in English Godot 关键概念概述 每个游戏引擎都围绕您用来构建应用程序的抽象展开。在 Godo…

【mysql】库的操作+表的操作

文章目录 启动mysql登录mysql1.MySQL环境安装与基础认识修改端口号连接服务器服务器&#xff0c;数据库&#xff0c;表关系建表 第二讲_库与表的操作1.创建数据库2.创建数据库案例3.指明字符集和校验集校验规则对数据库的影响不区分大小写的查询以及结果&#xff1a;区分大小写…

SQL Backup Master 6.3.6 Crack

SQL Backup Master 能够为用户将 SQL Server 数据库备份到一些简单的云存储服务中&#xff0c;例如 Dropbox、OneDrive、Amazon S3、Microsoft Azure、box&#xff0c;最后是 Google Drive。它能够将数据库备份到用户和开发者的FTP服务器上&#xff0c;甚至本地机器甚至网络服务…

速通二次型、二次型标准型、二次型规范型

浅过二次型 理解二次型可以从二次型的多项式入手&#xff1a; 显然&#xff0c;在系数都为实数的情况下&#xff0c;二次型矩阵即为一个实对称矩阵。 取一个代入值的例子就是&#xff1a; 二次型的标准型 OK&#xff0c;再从二次型的标准型的多项式入手&#xff0c;如下&…

FPGA System Planner(FSP)使用手册

FSP工具是cadence公司为了FPGA/PCB协同设计而推出的一个解决方案工具包。它的主要工作是由软件来自动生成、优化FPGA芯片的管脚分配,提高FPGA/PCB设计的工作效率和连通性。FSP完成两顷重要工作:一、可以自动生成FPGA芯片的原理图符号(symbol);二、自动生成、优化和更改FPG…

C++模板(上)

文章目录 模板函数模板函数模板的实例化 类模板总结 模板 模板是C种为了方便用户对于一些场景的使用&#xff0c;引入的新概念&#xff0c;使得我们的代码不会冗余 template关键字 template关键字的意思就是模板&#xff0c;语法为&#xff1a;template<typename T1,type…

内网渗透之Linux权限维持-OpenSSHPAM后门SSH软链接公私钥登录

0x01替换版本-OpenSSH后门 原理&#xff1a;替换本身操作系统的ssh协议支撑软件openssh&#xff0c;重新安装自定义的openssh,达到记录帐号密码&#xff0c;也可以采用万能密码连接的功能&#xff01; 可以修改软件版本和删除安装记录 1.环境准备&#xff1a; yum -y install…

【Java EE 初阶】网络初识

目录 1.网络互连 1.局域网&#xff1a; 2.广域网WAN 2.网络通信基础 3.IP地址&#xff1a;端口号 4.协议 1.五元组 2.协议分层 1.为什么要用网络分层&#xff1f; 3.OSI七层模型 4.TCP/IP五层&#xff08;或四层&#xff09;模型 5.封装和分用 1.应用层 2.传输层A…

Oracle数据库中了locked1勒索病毒攻击后怎么办,什么是locked1勒索病毒

Oracle数据库是一种被集团企业广泛使用的关系型数据库管理系统&#xff0c;但是随着科学技术的不断发展&#xff0c;在现代互联网环境中数据库安全性成为了一个非常重要的问题。而其中主要的威胁就是勒索病毒攻击。一旦数据库被勒索病毒攻击入侵&#xff0c;许多重要的数据就会…

【JVM】3. 运行时数据区及程序计数器

文章目录 3.1. &#x1f379;运行时数据区3.1.1. &#x1f942;概述3.1.2. &#x1f942;线程3.1.3. &#x1f942;JVM系统线程 3.2. &#x1f379;程序计数器(PC寄存器) 3.1. &#x1f379;运行时数据区 3.1.1. &#x1f942;概述 本节主要讲的是运行时数据区&#xff0c;也就…

跟我一起使用 compose 做一个跨平台的黑白棋游戏(2)界面布局

前言 在上一篇文章中&#xff0c;我们讲解了实现这个游戏的总体思路&#xff0c;这篇文章我们将讲解如何实现游戏界面。 本文将涉及到 compose 的自定义绘制与触摸处理&#xff0c;这些内容都可以在我往期的文章中找到对应的教程&#xff0c;如果对这部分内容不太熟悉的话&am…

论文阅读_语音合成_VALL-E

论文阅读 number headings: auto, first-level 2, max 4, _.1.1 name_en: Neural Codec Language Models are Zero-Shot Text to Speech Synthesizers name_ch: 神经网络编解码器语言模型实现零样本TTS paper_addr: http://arxiv.org/abs/2301.02111 date_read: 2023-04-25 da…