以前在学习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. [leetcode]158. Read N Characters Given Read4 II - Call multiple times 用Read4读取N个字符2 - 调用多次

    The API: int read4(char *buf) reads 4 characters at a time from a file. The return value is the actu ...

  2. win 下 nginx 的虚拟主机创建

    1.在nginx安装目录下的conf下创建vhost目录,用于存放虚拟主机配置文件.   2.在nginx安装目录下的conf/nginx.conf的http{}中加入 include vhost/* ...

  3. bootstrap下modal模态框中webuploader控件按钮异常(无法点击)问题解决办法【转】

    http://bbs.csdn.net/topics/391917552 具体如下:   $(function () {         var _$modal = $('#MyModal');    ...

  4. EXPAT(XML解析库)

    一.简介 expat是一个由C语言编写的XML解析库.James Clark创建了这个库,现在是制定XML标准的W3组织的技术leader.现在的版本是2.0.2.0开始就由Clark Cooper领 ...

  5. KMP(2)

    KMP 算法(2):其细微之处 2017 年 05 月 13 日 • 技术 系列文章目录 KMP 算法(1):如何理解 KMP KMP 算法(2):其细微之处 本篇来谈一谈 KMP 的一些细微之处,直 ...

  6. dump()

    输出格式化的对象

  7. dedecms模型类的引入

  8. OpenSCManager

    添加服务程序 执行级别:必须管理员

  9. Hibernate不能实时获取MySQL数据库的更新

    在hibernate.cfg.xml配置文件中,增加以下内容: <property name="hibernate.connection.provider_class"> ...

  10. W-D-S-UART编程

    1.协议原理 2.原理框图 3.开发板底板与核心板图 4.开始配置寄存器 a).使相应I/O引脚配置为UART引脚 b).配置数据发送模式 c).设置为中断或查询模式 d).使能串口缓存 e).流量控 ...