关于STM32位带操作随笔
以前在学习STM32时候关注过STM32的位带操作,那时候只是知道位带是啥,用来干嘛用,说句心里话,并没有深入去学习,知其然而不知其所以然。但一直在心中存在疑惑,故今日便仔细看了一下,写下心得供日后参考。
位带操作,我所理解的是就是像51单片机那样驱动IO引脚一样,比如要驱动P1端口的第一个引脚直接用P1^1即可对P1.1引脚进行输入和输出,由于STM32基于32位寄存器操作,不允许直接访问某一位,要想控制GPIO端口的某一位怎么办,于是就有了位带操作,说白了就是为解决STM32不能直接访问GPIO中的具体位而提出的办法。

在STM32的存储结构中外设区有位带区和位带别名区,这两个有何区别呢,位带区就是实际操作的外设地址,而位带别名区就是这个位带区的另一个名字。要想操作位就要把这个位变成一个能访问的地址,于是就将位带区膨胀成位带别名区,区别就是在位带别名区可以直接访问,因为已经把每一位都变成了一个字。
因此1M内存的BitBand区就对应32M内存的BitBand别名区,因为将每一位膨胀成为了一个32位的地址,所以相应的别名区的内存也会是位带区的32倍。

位带操作具体实现如下图片中公式所示:

实现过程就是先找到端口的起始地址获得要操作端口的偏移地址也就是A-0X40000000,因为在别名区上的偏移也是对等的,将获得的这个偏移地址扩大到字(乘以8)也就是具体到某一位都有一个地址,然后在这个基础上想要操作哪位就是n直接加上就行,最后再乘以4扩到到字,再加上别名区的起始地址就获得了要设置的端口在别名区中的地址了,此时对别名区中的32位地址操作实际就是对GPIO的位操作。
位带别名区的起始地址为:0x42000000
GPIO端口起始地址如下所示(以STM32F4为例):

然后在STM32F4中ODR寄存器的偏移地址为0X14,IDR寄存器的偏移地址为0X10,根据上述具体公式便设置如以下代码便可实现对GPIO端口的位进行操作:
#define PAout(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X20000 + 0X14) * 32) + (Pin_x * 4)))
#define PBout(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X20400 + 0X14) * 32) + (Pin_x * 4)))
#define PCout(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X20800 + 0X14) * 32) + (Pin_x * 4)))
#define PDout(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X20C00 + 0X14) * 32) + (Pin_x * 4)))
#define PEout(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X21000 + 0X14) * 32) + (Pin_x * 4)))
#define PFout(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X21400 + 0X14) * 32) + (Pin_x * 4)))
#define PGout(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X21800 + 0X14) * 32) + (Pin_x * 4)))
#define PHout(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X21C00 + 0X14) * 32) + (Pin_x * 4)))
#define PIout(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X22000 + 0X14) * 32) + (Pin_x * 4))) #define PAin(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X20000 + 0X10) * 32) + (Pin_x * 4)))
#define PBin(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X20400 + 0X10) * 32) + (Pin_x * 4)))
#define PCin(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X20800 + 0X10) * 32) + (Pin_x * 4)))
#define PDin(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X20C00 + 0X10) * 32) + (Pin_x * 4)))
#define PEin(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X21000 + 0X10) * 32) + (Pin_x * 4)))
#define PFin(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X21400 + 0X10) * 32) + (Pin_x * 4)))
#define PGin(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X21800 + 0X10) * 32) + (Pin_x * 4)))
#define PHin(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X21C00 + 0X10) * 32) + (Pin_x * 4)))
#define PIin(Pin_x) * ((volatile unsigned long *)(0x42000000 + ((0X22000 + 0X10) * 32) + (Pin_x * 4)))
设置后就可直接用PXout(n)和PXin(n)进行X端口的n位进行输出和输入了。
关于STM32位带操作随笔的更多相关文章
- STM32位带操作总结---浅显易懂
正在准备做毕业设计,配置LED_Config()的时候,又看到了位带操作的宏定义,我又嘀咕了,什么是位带操作,一年前在使用位带操作的时候,就查阅过好多资料,Core-M3也看过,但是对于博主这种“低能 ...
- STM32位带操作
STM32的位带操作是基于cortex内核自带的,而不是st公司独创.基本的思路就是用一个32位的地址空间访问一个bit,因为stm32只支持32位数据的读取,不像51单片机一样,是可以单独对一位操作 ...
- 【ARM】---STM32位带操作总结---浅显易懂
正在准备做毕业设计,配置LED_Config()的时候,又看到了位带操作的宏定义,我又嘀咕了,什么是位带操作,一年前在使用位带操作的时候,就查阅过好多资料,Core-M3也看过,但是对于博主这种“低能 ...
- STM32—位带操作
STM32中的位带操作: 名字为位带操作,实际上是对位的操作,位操作就是可以单独的对一个比特位读和写,这个在 51 单片机中非常常见. 51 单片机中通过关键字 sbit 来实现位定义, STM32 ...
- (stm32学习总结)—GPIO位带操作
本章参考资料:<STM32F10X-中文参考手册>存储器和总线构架章节.GPIO 章节,<CM3 权威指南 CnR2>存储器系统章节. 位带简介 位操作就是可以单独的对一个比特 ...
- STM32之GPIO端口位带操作
#ifndef __SYS_H #define __SYS_H #include "stm32f10x.h" //位带操作 //把“位带地址+位序号”转换别名地址宏 #define ...
- STM32F030系列实现仿位带操作
1.闲言 最近开发的时候,用到了STM32F030F4P6型号的单片机,它只有20个引脚,价格非常便宜,但是功能齐全:定时器.外部中断.串口.IIC.SPI.DMA和WWDG等等,应用尽有,非常适合用 ...
- 玩转X-CTR100 l STM32F4 l 基础例程printf、LED、蜂鸣器、拨码开关、位带操作
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] 本文介绍X-CTR100控制器基础板载资源 ...
- 玩转X-CTR100 | STM32F4 l GPIO位带操作
更多塔克创新资讯欢迎登陆[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] STM32F4位带概念,及位带的GPIO操作实践应用. 原理介 ...
随机推荐
- Django的mode的分组查询和聚合查询和F查询和Q查询
1.聚合查询 # 聚合函数aggregate,求指定字段的最大值,最小值,平均值,和的值,方法如下 from django.db.models import Avg from django.db.mo ...
- centos7 二进制安装包安装 mysql5.6
centos7 二进制安装包安装 mysql5.6 一.下载mysql5.6二进制安装包 http://mirrors.sohu.com/mysql/MySQL-5.6/ 如:mysql-5.6.34 ...
- CSS中margin边界叠加问题及解决方案(转)
边界叠加简介 边界叠加是一个相当简单的概念.但是,在实践中对网页进行布局时,它会造成许多混淆.简单地说,当两个垂直边界相遇时,它们将形成一个边界.这个边界的高度等于两个发生叠加的边界的高度中的较大者. ...
- 求N的阶乘N!中末尾0的个数
求N的阶乘N!中末尾0的个数 有道问题是这样的:给定一个正整数N,那么N的阶乘N!末尾中有多少个0呢?例如:N=10,N=3628800,则N!的末尾有两个0:直接上干货,算法思想如下:对于任意一个正 ...
- Codeforces 710C. Magic Odd Square n阶幻方
C. Magic Odd Square time limit per test:1 second memory limit per test:256 megabytes input:standard ...
- jQuery 用$.param(json) 将 Json 转换为 Url queryString
如: var params = { param1: 'bar', param2: 'foo' }; var queryString = $.param(params); // queryString ...
- Spring官方文档翻译(1~6章)
Spring官方文档翻译(1~6章) 转载至 http://blog.csdn.net/tangtong1/article/details/51326887 Spring官方文档.参考中文文档 一.S ...
- 值得一看!2018年最优秀的9个Android Material Design Apps!
今年4月,谷歌Gmail推出了全新的设计外观,全新的配色方案,更多的空白区域和精致的图标.也带来了Material Design 的一些改变 – Material Theming (材料主题),旨在自 ...
- 任务取消TASK
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- c++11 stl 学习之 pair
pair以模板的方式存储两个数据 namespace std {template <typename T1, typename T2>struct pair {// memberT1 fi ...