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

news2024/11/17 19:31:31

目前掌握的对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/548524.html

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

相关文章

网络协议与攻击模拟-11-DHCP协议原理

DHCP 协议 1、掌握 DHCP 的工作原理 2、会在 Windows server 上去部署 DHCP 服务 3、抓流量 &#xff0e;正常 收到攻击后 一、 DHCP 1、 DHCP 基本概念 dhcp &#xff08;动态主机配置协议&#xff09;&#xff1a;主要就是给客户机提供 TCP / IP 参数&#xff08; IP 地…

微信小程序nodejs+vue社区居民健康服务系统uniapp

系统分为社区居民&#xff0c;管理员&#xff0c;县区工作员&#xff0c;社区工作员三个角色 县区工作员的主要功能&#xff1a; 1.对社区的工作人员进行添加&#xff0c;修改&#xff0c;删除&#xff0c;查询 2.疫情专栏的信息进行添加&#xff0c;修改&#xff0c;删除&…

特瑞仕 :8种PCB接地方案+14种PCB接地技巧

​在PCB设计中&#xff0c;接地是非常重要的一环&#xff0c;它涉及到整个电路的性能、可靠性和EMI等问题。在实际设计中&#xff0c;有多种接地方案和技巧可供选择&#xff0c;如何选择合适的接地方案和技巧对于设计的成功至关重要。本文将详细介绍8种常见的PCB接地方案和14种…

【软考】系统集成项目管理工程师 第1章 信息化知识

文章目录 1.1 信息与信息化1.1.1 信息1.1.2 信息系统1.1.3 信息化1.1.4 国家信息化体系要素1.1.5 信息技术发展趋势 1.3 电子政务1.3.1电子政务的概念和内容1.3.2我国电子政务开展的现状1.3.3电子政务建设的指导思想和发展方针1.3.4电子政务建设的发展方向和应用重点 1.4 企业信…

分布式锁问题_演示问题

通过idea创建两个服务 启动Nginx服务 下载Nginx windows服务&#xff0c;官网nginx: download 当然我这里提供了&#xff1a; 我们打开nginx的conf目录&#xff0c;然后打开配置文件nginx.conf进行配置&#xff1a; upstream test{ server localhost:9090 ; se…

geoserver跨域问题多种解决方案

geoserver发布服务完成之后&#xff0c;很重要的一个应用场景是前端服务调用&#xff0c;来展示服务数据&#xff0c;那么很可能遇到一个跨域问题&#xff0c;今天我们分享一下跨越问题的多种解决方案&#xff0c;来适用不同需求的业务场景。 一、nginx服务均衡策略 如果你的…

Spring:Spring 框架概述、IoC 设计思想、依赖注入、各种配置

文章目录 Spring&#xff1a;Day 01一、简介1. 概述2. Spring 组成 二、IoC 设计思想三、编写一个 Spring四、IoC 创建对象方式五、Spring 配置1. 别名2. Bean 的配置3. import 六、依赖注入1. 搭建环境2. Set 注入3. 总结补充&#xff1a;c 命名和 p 命名空间注入 七、Bean 的…

1.nginx基础学习笔记

1.nginx基础 一.Nginx介绍 Nginx是十分轻量级的HTTP服务器。Nginx&#xff0c;它的发音为“engine X”&#xff0c;是一个高性能的HTTP和反向代理服务器&#xff0c;同时也是一个IMAP/POP3/SMTP 代理服务器。Nginx是由俄罗斯人 Igor Sysoev为俄罗斯访问量第二的 Rambler.ru站…

Cisco AnyConnect Secure Mobility Client 4.10.07061 (macOS, Linux, Windows)

Cisco AnyConnect Secure Mobility Client 4.10.07061 (macOS, Linux, Windows) Cisco Secure Client&#xff08;包括 AnyConnect&#xff09; 请访问原文链接&#xff1a;https://sysin.org/blog/cisco-anyconnect-4/&#xff0c;查看最新版。原创作品&#xff0c;转载请保…

Apache Kafka - 安装注意事项

文章目录 概述安装Kafka配置Kafka启动Kafka配置注意事项导图 概述 在现代的大数据时代&#xff0c;消息队列成为了极为重要的组件。Kafka作为一种高吞吐量、低延迟、可扩展的分布式发布订阅消息系统&#xff0c;在大数据领域得到了广泛的应用。来&#xff0c;这里我们将介绍如…

【场景方案】如何去设计并二次封装一个好用的axios,给你提供一个好的参考(1.0版)

文章目录 前言文件结构建议封装的文件结构接口管理文件 二次封装axios的初始配置initutilswebConfig 再封一层环境配置使用 前言 以下演示基于vue3与element-plus 文件结构建议 封装的文件结构 把二次封装axios所有有关的代码全部放在request文件夹中&#xff0c;其中init.js…

【系统移植】SD卡 分区

目录 1、分区框架 2、清空磁盘分区 3、开始分区 4、格式化分区 1、分区框架 制作SD卡时&#xff0c;我们需要对 SD 卡进行分区&#xff0c;每个区存入对应的内容&#xff0c;整体框架如下&#xff1a; 第二扇区&#xff1a;uboot程序从这里开始存储&#xff0c;最开始的第…

Class 07 - 功能包的安装和 tidyverse 介绍

Class 07 - 功能包的安装和 tidyverse 介绍 tidyverse 简介功能包&#xff08;package&#xff09;的安装tidyverse 的安装 功能包&#xff08;package&#xff09;的加载tidyverse 的加载 功能包&#xff08;package&#xff09;的更新tidyverse 核心功能browseVignettes 函数…

组合数学第三讲

composition&#xff08;组成&#xff09; k-composition&#xff1a; 20块巧克力分给4个小朋友&#xff0c;有几种分法&#xff1f; 隔板法&#xff0c;19个间隙插入3个板&#xff0c; 推广&#xff1a;n块分给k个 weak k-composition: 20块巧克力分给4个小朋友&#xff0c;每…

Ajax基础知识点总结

努力前进 目录 为什么需要Ajax&#xff1f; 1.提高用户体验&#xff0c;实现局部刷新效果 2.提高性能和降低带宽消耗 什么是 Ajax Ajax 的工作原理 Ajax的工作过程分为以下几个步骤&#xff1a; 最基础的Ajax代码演示&#xff1a; open函数中的参数分析: 在Ajax中ready…

Dijkstra单源最短路

Dijkstra单源最短路径 什么是单源最短路径 描述&#xff1a;给定一个带权有向图G (V&#xff0c;E)&#xff0c;其中每条边的权时非负数。另外&#xff0c;给定V中的一个顶点&#xff0c;称为源。现在要计算从源到所有其他各顶点的最短路长度。这里路的长度是指路上各边权之…

数据在 Mocaverse 项目启动过程中是如何发挥作用的

日期&#xff1a;2023年5月 数据源&#xff1a; Mocaverse Realm Ticket Collection Airdrop & Mocaverse Optimizes an NFT Project at Launch & Beyond NFT 是 Web3 社区的基础。它们是区块链游戏、DAO 和 metaverses 的入场券&#xff0c;以及成为社区参与者的数字…

[创业之路-69]:对管理理念的理解和解读

目录 前言&#xff1a; 一、管理者与领导者的区别 二、管理活动的分类 三、业务管理&#xff1a;以终为始 3.1 业务目标到高效执行 &#xff08;1&#xff09;先明确要做哪些正确的事 》 需求分析、目标 &#xff08;2&#xff09;再明确怎样正确的做事 》 设计、实现 …

chatgpt赋能Python-python3_pygame

Python3 Pygame&#xff1a;游戏引擎进入开发者的时代 Python是一种常用的编程语言&#xff0c;有许多优秀的库和框架&#xff0c;而其中Pygame是许多游戏开发者的首选。Pygame是一个用Python编写的开源软件包&#xff0c;旨在帮助游戏制作者创建交互式游戏和媒体程序。在本篇…

OpenCV基础操作(2)OpevCV算术运算

OpenCV基础操作(2)OpevCV算术运算 import cv2 as cv import numpy as np一、图像的基础操作 1、获取并修改像素值 你可以根据像素的行和列的坐标获取他的像素值。 对 BGR 图像而言&#xff0c;返回值为 B&#xff0c;G&#xff0c;R 的值。对灰度图像而言&#xff0c;会返回他…