以前在学习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. Hamburgers

    Hamburgers http://codeforces.com/problemset/problem/371/C time limit per test 1 second memory limit ...

  2. Too Rich(贪心+DFS)

    Too Rich http://acm.hdu.edu.cn/showproblem.php?pid=5527 Time Limit: 6000/3000 MS (Java/Others)    Me ...

  3. 关于swift语言中导入OC三方类找不到头文件的解决方法

    首先我遇到的问题是这样的: 我之前封装的OC类,我导入现在的swift工程中,然后建立桥接文件,在Swift的控制器中可以找到这个OC写的东西. 但是问题来了,当你使用cocoapods导入的OC三方 ...

  4. IBM MQ 与spring的整合

    文件名:applicationContext-biz-mq.xml 新浪博客把里面的代码全部转换成HTML了,所以无法粘贴 可以查看CSDN里面的:http://blog.csdn.net/xiazo ...

  5. VINS-mono详细解读

    VINS-mono详细解读 极品巧克力 前言 Vins-mono是香港科技大学开源的一个VIO算法,https://github.com/HKUST-Aerial-Robotics/VINS-Mono ...

  6. dede自定义标签

    在dede安装目录下的include/taglib下创建标签文件,比如mytest.lib.php.(必须以.lib.php为后缀) <?php if(!defined('DEDEINC')) ...

  7. IIS文件名解析漏洞扼要分析

    概括: 从技术角度分析IIS6文件名解析漏洞的原理与IIS7的相关情况. a.IIS6错误解析文件类型现象 1.当WEB目录下,文件名以 xxx.asp;xxx.xxx 来进行命名的时候,此文件将送交 ...

  8. python 调试方法

    一.使用pdb http://blog.csdn.net/wyb_009/article/details/8896744 二.使用gdb 需首先配置gdb pythin支持,步骤如下: 1.修改Pyt ...

  9. LINUX 笔记5

    配置环境变量:(只是在当前命令行窗口中有用) 单独查看PATH环境变量,可用: [root@localhost u-boot-sh4]#echo $PATH 添加PATH环境变量,可用: [root@ ...

  10. python性能测试大致计划

      hi guy: 如果注意到创建时间,那就对了.这份文章,是我学习Python一个月以后动手写的.   写下这份计划以后,只完成了第一步,其中磕磕绊绊编写代码的过程,很大一部分时间是完全用txt写的 ...