STM32中的位带操作: 名字为位带操作,实际上是对位的操作,位操作就是可以单独的对一个比特位读和写,这个在 51 单片机中非常常见。 51 单片机中通过关键字 sbit 来实现位定义, STM32 没有这样的关键字,而是通过访问位带别名区来实现。STM32 的全部寄存器都可以通过访问位带别名区的方式来达到访问原始寄存器比特位的效果,这比 51 单片机强大很多。因为 51 单片机里面并不是所有的寄存器都是可以比特位操作,有些寄存器还是得字节操作,比如 SBUF。

51单片机中的位操作:
51单片机中可以对寄存器实现单个位的操作,靠的就是关键字sbit,如
sbit led=P1^0; led=1;就可实现对P1.0位置1的效果。

为什么STM32不推崇直接进行位操作?
本人认为STM32是32位MCU,一次处理32位数据,所以一次只处理一位的数据未必大材小用了,除非特殊情况,否则都以32位处理。

如何处理STM32中要对某一位进行操作时的情况?
要知道STM32中采用库函数编程,所以有很多的对位操作的任务都用具体的函数来完成,而这些函数都已经做好了我们只需要知道怎么用就行。但我们仍然可以自己实现位操作,这种神操作就是位带操作

位带区与位带区别名:
在 STM32 中,有两个地方实现了位带,一个是 SRAM 区的最低 1MB 空间,令一个是外设区最低 1MB 空间。这两个 1MB 的空间除了可以像正常的 RAM 一样操作外,他们还有自己的位带别名区,位带别名区把这 1MB 的空间的每一个位膨胀成32 位 (要知道 STM32 的系统总线是 32 位的,按照 4 个字节访问的时候是最快的,所以膨胀成 4 个字节来访问是最高效的。),当访问位带别名区的这些字时,就可以达到访问位带区某个比特位的目的。
位带区就是就是可以进行位带操作的寄存器的映射地址。
位带区别名可以理解为将位带区每一个位都膨胀32倍(用一个字节代表一个位,以便于32位MCU操作)后的地址。

如何实现位带操作?
要进行位带操作需要知道被操作的位的地址,因为SRAM和外设中都可以位带操作,所以形式上可以将位带操作归纳为俩个公式。
对于位带区的某个比特,记它所在字节的地址为 A,位序号为 n(0<=n<=7),则其在位带区别名地址为:

外设:AliasAddr= =0x42000000+ (A-0x40000000)*8*4 +n*4
SRAM:AliasAddr= =0x22000000+ (A-0x20000000)*8*4 +n*4

用外设解释公式:0X42000000 是外设位带别名区的起始地址, 0x40000000 是外设位带区的起始地址,(A-0x40000000)表示该比特前面有多少个字节,一个字节有 8 位,所以8,一个位膨胀后是 4 个字节,所以4, n 表示该比特在 A 地址的序号,因为一个位经过膨胀后是四个字节,所以也*4。
当然,也可以将俩个公式合二为一:

 // 把“位带地址+位序号”转换成别名地址的宏
AliasAdd = (addr & 0xF0000000)+0x02000000+((addr &0x00FFFFFF)<<5)+(bitnum<<2)

知晓了位带区别名的地址,然后将此地址转换为指针类型就可以通过位带操作对原始的为进行操作。
附上野火的位带操作代码:

#include "stm32f10x.h"
#include "./led/bsp_led.h" #define PCout(n) (*(unsigned int*)(((GPIOC_BASE+0x0c) & 0xF0000000)+0x02000000+(((GPIOC_BASE+0x0c) &0x000FFFFF)<<5)+(n<<2)))
#define PBout(n) (*(unsigned int*)(((GPIOB_BASE+0x0c) & 0xF0000000)+0x02000000+(((GPIOB_BASE+0x0c) &0x000FFFFF)<<5)+(n<<2))) void delay(uint32_t count)
{
for(; count!=0; count--);
} int main(void)
{
LED_GPIO_Config(); //LED初始化函数 while(1)
{
PCout(2) = 1;
//GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
delay(0xfffff);
PCout(2) = 0;
//GPIO_ResetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
delay(0xfffff); PCout(3) = 1;
//GPIO_SetBits(LED2_GPIO_PORT, LED2_GPIO_PIN);
delay(0xfffff);
PCout(3) = 0;
//GPIO_ResetBits(LED2_GPIO_PORT, LED2_GPIO_PIN);
delay(0xfffff);
}

代码简述:用宏定义的方法来操作GPIOC中的ODR寄存器和IDR寄存器中的某一位来实现led灯的亮灭

#define PCout(n) (*(unsigned int*)(((GPIOC_BASE+0x0c) & 0xF0000000)+0x02000000+(((GPIOC_BASE+0x0c) &0x000FFFFF)<<5)+(n<<2)))

文章部分参考:【野火】《零死角玩转STM32》

STM32—位带操作的更多相关文章

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

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

  2. 关于STM32位带操作随笔

    以前在学习STM32时候关注过STM32的位带操作,那时候只是知道位带是啥,用来干嘛用,说句心里话,并没有深入去学习,知其然而不知其所以然.但一直在心中存在疑惑,故今日便仔细看了一下,写下心得供日后参 ...

  3. STM32位带操作

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

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

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

  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. linux学习之路第二天(xshell和xftp的使用图解)

    以上xshell的连接过程 2.远程上传和下载文件xftp6 一定要换成22和sftp,否则连接不上 如果出现中文乱码的情况 先点击那个小齿轮 再点击选项 把编码编程UTF-8就ok了

  2. hdu 2093 成绩排名

    思路: 没啥思路,就是定义结构体,跟题目,走,当时没想到对那个括号的处理,后面看了题解,才知道用个getchar直接判断 算是一个值得思考的点. 代码: #include<bits/stdc++ ...

  3. 《Do Neural Dialog Systems Use the Conversation History Effectively? An Empirical Study》

    https://zhuanlan.zhihu.com/p/73723782 请复制粘贴到markdown 查看器查看! Do Neural Dialog Systems Use the Convers ...

  4. if语句 条件测试 shell编程之条件语句

    shell 编程之条件语句一.条件测试  ① test命令 测试  ② 文件测试  ③ 整数值比较  ④ 字符串比较  ⑤ 逻辑测试二.if语句的结构  单分支结构  双分支结构  多分支结构三.ca ...

  5. DNS域名解析四种配置实验 ---Linux DNS域名解析服务

    DNS域名解析服务一.BIND域名服务基础1) DNS的定义2)域名结构3)DNS系统的作用① 正向解析:根据域名查找对应的IP地址② 反向解析:根据IP地址查找对应的域名③ DNS系统的分布式数据结 ...

  6. python 抓取异常

    aa={"a":2,"b":1} for i in range(10): aa["a"]=aa["a"]-i print ...

  7. CocoaPods 私有化

    一.创建所需要的代码仓库 创建 Spec 私有索引库(ZFSpec),用来存放本地spec 创建模块私有库(ZFPodProject),用来存放项目工程文件 二.私有索引库添加到本地 CocoaPod ...

  8. Scala学习——面向对象

    Scala面向对象 三大特征:封装.继承.多态 1.类的定义和使用 package top.ruandb.scala.Course02 object Simple { def main(args: A ...

  9. Linux安装Tomcat-Nginx-FastDFS-Redis-Solr-集群——【第十一集补充:修改fastdfs的http.conf文件进行防盗链,重启nginx失败】

    1,进入fastdfs的安装目录: 2,修改http.conf文件,详情可参考: https://www.cnblogs.com/xiaolinstudy/p/9341779.html 3,重启ngi ...

  10. C标准库学习

    前言 C标准库源码可通过下列两个网站进行查看:The GNU C Library.Welcome to uClibc-ng! - Embedded C library 以下学习记录也是以这两个网站提供 ...