以前在学习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位带操作随笔的更多相关文章

  1. STM32位带操作总结---浅显易懂

    正在准备做毕业设计,配置LED_Config()的时候,又看到了位带操作的宏定义,我又嘀咕了,什么是位带操作,一年前在使用位带操作的时候,就查阅过好多资料,Core-M3也看过,但是对于博主这种“低能 ...

  2. STM32位带操作

    STM32的位带操作是基于cortex内核自带的,而不是st公司独创.基本的思路就是用一个32位的地址空间访问一个bit,因为stm32只支持32位数据的读取,不像51单片机一样,是可以单独对一位操作 ...

  3. 【ARM】---STM32位带操作总结---浅显易懂

    正在准备做毕业设计,配置LED_Config()的时候,又看到了位带操作的宏定义,我又嘀咕了,什么是位带操作,一年前在使用位带操作的时候,就查阅过好多资料,Core-M3也看过,但是对于博主这种“低能 ...

  4. STM32—位带操作

    STM32中的位带操作: 名字为位带操作,实际上是对位的操作,位操作就是可以单独的对一个比特位读和写,这个在 51 单片机中非常常见. 51 单片机中通过关键字 sbit 来实现位定义, STM32 ...

  5. (stm32学习总结)—GPIO位带操作

    本章参考资料:<STM32F10X-中文参考手册>存储器和总线构架章节.GPIO 章节,<CM3 权威指南 CnR2>存储器系统章节. 位带简介 位操作就是可以单独的对一个比特 ...

  6. STM32之GPIO端口位带操作

    #ifndef __SYS_H #define __SYS_H #include "stm32f10x.h" //位带操作 //把“位带地址+位序号”转换别名地址宏 #define ...

  7. STM32F030系列实现仿位带操作

    1.闲言 最近开发的时候,用到了STM32F030F4P6型号的单片机,它只有20个引脚,价格非常便宜,但是功能齐全:定时器.外部中断.串口.IIC.SPI.DMA和WWDG等等,应用尽有,非常适合用 ...

  8. 玩转X-CTR100 l STM32F4 l 基础例程printf、LED、蜂鸣器、拨码开关、位带操作

    我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ]      本文介绍X-CTR100控制器基础板载资源 ...

  9. 玩转X-CTR100 | STM32F4 l GPIO位带操作

    更多塔克创新资讯欢迎登陆[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ]       STM32F4位带概念,及位带的GPIO操作实践应用. 原理介 ...

随机推荐

  1. ECMAScript5新特性之isSealed、seal

    封闭对象后: 1 不能增加属性. 2 不能删除属性. 3 可以修改属性.(赋值) 4 不能修改属性描述符.(抛异常) var fruit = { name : '苹果', desc : '红富士' } ...

  2. manacher最长回文序列c++

    算法真心读不懂 #include <iostream>#include<string>#include<cstring> using namespace std;c ...

  3. Mysql、Oracle、SqlServer的JDBC连接实现和对比(提供驱动包)

    首先,我们需要准备数据库连接所需的jar包.目前mysql的驱动包可能比较好找,但是oracle和sqlserver的有很多,要找到能用的要花一点点心思,这里直接把下载地址和版本发送出来. Mysql ...

  4. OpenGLES.Functions.Missing.in.OpenGLES1.x

    转载自: http://maniacdev.com/2009/05/big-list-of-opengl-functions-missing-in-iphone-opengl-es The funct ...

  5. 02 请求库之 requests模块

    requests模块   一 介绍 #介绍:使用requests可以模拟浏览器的请求,比起之前用到的urllib,requests模块的api更加便捷(本质就是封装了urllib3) #注意:requ ...

  6. 80% UI 初学者走过的弯路,你走了几条?

    关于UI 对于初学UI设计的人而言,可能对UI具体是做什么,或者自己是否能顺利转行胜任这样的岗位存在一定的顾虑,今天我们就来重点说说UI是做什么的,以及学UI到有哪些需要避免的弯路. 1.UI设计是做 ...

  7. 用 npm 安装删除模块

    npm安装模块 [npm install xxx]利用 npm 安装xxx模块到当前命令行所在目录: [npm install -g xxx]利用npm安装全局模块xxx: 本地安装时将模块写入pac ...

  8. vue-route 路由传参的使用

    1 router/index.js 中的定义 { path: '/product', component: ProductIndex, meta: { requiredAuth: true, }}, ...

  9. 关于apicloud图片缓存

    imageCache如果是同一个地址,得到的缓存文件名字是一样的.可能是对url md5了一下. apicloud目前有两种清除方式1 一种是api.clearCache   另一种方法当然是强大的 ...

  10. apicloud代码压缩和全局加密

    首先说代码压缩,因为没什么用,就先说它了.代码压缩后,apicloud里面的css和js文件里面的空格呀回车呀都去掉了,就是文件小了,所有代码显示为一行了.这些代码的变量没有重命名,我们知道jquer ...