STM32位带操作-详解-计算过程

发布者:psi33最新更新时间:2021-11-02 来源: eefocus关键字:STM32  位带操作 手机看文章 扫描二维码
随时随地手机看文章

位带操作

位带操作的概念其实很多年前就有了,那还是 8051 单片机开创的先河。如今,CM3 将此能力进化,这里的位带操作是 8051 位寻址区的威力大幅加强版。


官方解释

先来看一下Cortex-M3权威指南中描述的位带操作:

支持了位带操作后,可以使用普通的加载/存储指令来对单一的比特进行读写操作。在CM3中,有两个区中实现了位带。其中一个是 SRAM 区的最低1MB 范围,第二个则是片内外设区的最低 1MB 范围。这两个区中的地址除了可以像普通的 RAM 一样使用外,它们还都有自己的“位带别名区”,位带别名区把每个比特膨胀成一个 32 位的字。当你通过位带别名区访问这些字时,就可以达到访问原始比特的目的。

在这里插入图片描述

正点原子库函数指导书解释

位带操作简单的说,就是把每个比特膨胀为一个 32 位的字,当访问这些字的时候就达到了访问比特的目的,比如说 BSRR 寄存器有 32 个位,那么可以映射到 32 个地址上,我们去访问这 32 个地址就达到访问 32 个比特的目的。这样我们往某个地址写 1 就达到往对应比特位写 1 的目的,同样往某个地址写 0 就达到往对应的比特位写 0 的目的。

在这里插入图片描述

对比下来还是下面写的更容易理解一些,现在我们知道了位带操作是将一位是数据膨胀为32位的字,那么他是怎么实现的呐?


位带操作地址转换计算

大家先看一下这个图注意一下,下面为位带区(就是原来的位置,占一位),而上面位带别名区(新地址,站32位)。(这里真的不知道咋解释了,试着理解一下吧)



CM3中支持位带操作的地址

首先我们要了解在STM32中有两个区域可以进行位带操作,支持位带操作的两个内存区的范围是:

0x2000 0000-0x200F FFFF (SRAM区中的最低1MB)

0x4000 0000-0x400F FFFF (片上外设区中的最低1MB)

对应别名区的范围为:

0x2200 0000-0x23FF FFFF

0x4200 0000-0x43FF FFFF


从这连个范围就可以看出点问题,支持位带操作的区域大小,差不多比位带别名区小32倍。

这也就表明了确实是位带区的一位,在别名区是32位。那么是怎么转换的那。

官方给了计算公式:

是不是感觉不太好理解,那我们就一起来算一下,到地是不是这么回事。

首先一个官方给的图来做对比,看看结果对不对。

我们就计算两个位置,分别为0x20000000的第0位和0x20000000的第1位.

因为这两个位置都是SRAM位带区的数据所以我们要用对应的公式:


AliasAddr = 0x22000000+((A-0x20000000)*8+n)*4= 0x22000000+(A-0x20000000)32+n4


首先我们需要注意的一点是,A是SRAM位带区的某个比特的字节地址,注意是字节地址,我们都知道STM32中每个寄存器是32位的,所以每个寄存器站用4个字节,而0x20000000是总线地址,也就是基地址,寄存器地址是在这个基地址的基础上偏移的。如下图:

OK,了解这些就可以进行计算了。


要计算数据:0x20000000的第0位


A = 0x20000000

n = 0

公式:

AliasAddr = 0x22000000+((A-0x20000000)*8+n)*4= 0x22000000+(A-0x20000000)*32+n*4

第一步:带入数据

AliasAddr =  0x22000000+(0x20000000-0x20000000)*32+0*4

这里将一下计算规则:

加/减运算,只需要对应的位进行减就可以了

乘除运算:需要化为十进制进行计算。

结果:

AliasAddr = 0x22000000


对应上面的图片:

位带区 —> 等效的别名地址

0x20000000.0 --> 0x22000000.0

说明我们计算正确了,有人可能认为我们取得值太简单,那我们就在换一个再进行一次计算。


要计算数据:0x20000004的第2位

代入数据

AliasAddr =  0x22000000+(0x20000004-0x20000000)*32+2*4

这里计算就要借助计算器了,大家可以自行计算一下,注意在乘的时候一定要转化为十进制。计算结束后在转化为16进制

经过计算结果:

AliasAddr = 0x22000088


对照上表说明我们计算的只是正确的。这样我们就了解是如何进行转化的了,但是这就有新的问题了,32位的位带地址是如何给的位带区传递值的呐。


官方文档给出了解释:

在位带区中,每个比特都映射到别名地址区的一个字,这是只有一个 LSB有效的字。当一个别名地址被访问时,会先把该地址变换成位带地址。对于读操作,读取位带地址中的一个字,再把需要的位右移到LSB,并把LSB返回。对于写操作,把需要写的位左移至对应的位序号处,然后执行一个原子的“读一改一写”过程。

注释:LSB–最低有效位


这样位带操作就显得很简单了嘛,最后再看一下位带操作的实现


#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 

#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 

#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 

//IO¿ÚµØÖ·Ó³Éä

#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C 

#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C 

#define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C 

#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C 

#define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C 

#define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C    

#define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C    


#define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808 

#define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 

#define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008 

#define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408 

#define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808 

#define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08 

#define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08 

 

//IO¿Ú²Ù×÷,Ö»¶Ôµ¥Ò»µÄIO¿Ú!

//È·±£nµÄֵСÓÚ16!

#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //Êä³ö 

#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //ÊäÈë 


#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //Êä³ö 

#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //ÊäÈë 


#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //Êä³ö 

#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //ÊäÈë 


#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //Êä³ö 

#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //ÊäÈë 


#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //Êä³ö 

#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //ÊäÈë


#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //Êä³ö 

#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //ÊäÈë


#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //Êä³ö 

#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //ÊäÈë


这里开头三行是实现地址转化的,原理就是将位带区的某一位转化位位带别名区的一个32位的字节。大家可以分析一下,看看能不能算出来。


位带操作的优点

位带操作有什么优越性呢?最容易想到的就是通过GPIO的管脚来单独控制每盏LED的点亮与熄灭。另一方面,也对操作串行接口器件提供了很大的方便(典型如74HC165,CD4094)。总之位带操作对于硬件I/0密集型的底层程序最有用处了。


读取比特时传统方法与位带方法的比较

这就很直观的看出位带操作的相对而言更简便一些。


结语

位带操作在实际开发中可能只是用来 IO 口的输入输出还比较方便,其他操作在日常开发中也基本很少用。

关键字:STM32  位带操作 引用地址:STM32位带操作-详解-计算过程

上一篇:快速理解STM32位带操作原理和用途
下一篇:STM32位带操作详细介绍

推荐阅读最新更新时间:2024-11-13 10:35

STM32与LPC1700的应用比较
NXP的东西在汽车上用的很多。我从毕业就在车载行业混。车上用的东西,飞思卡尔的最多,英飞凌那是车厂级别的采用,就是所谓的前装标准.汽车收音机出了ST的TDA7540外,最大的还是NXP的、 ST的东西才是有不少BUG。比如STM32刚出来的时候,为了快速抢占市场,那些芯片问题很多的,只是说现在好很多。ST最成功的还是STM8 深圳车载行业以前用的MCU都8位的,厂家有很多,松下,瑞萨,东芝、、、、、自从STM8出来以后已下子都 叛变了 转投ST阵营。 我09年开始玩STM32,后来,用STM32的64脚,100脚的做了几个应用。感触如下:《仅个人之言。》 1.开发容易,借助于那个让人 爱 有让人 恨 的库,开发周期比较快。 2.管
[单片机]
stm32—普通串口(接收查询和中断相结合)
串口实验 1. 在做任何实验之前都是将目标文件导入库文件,然后在main函数中导入头文件,在FWLIB中写入路径,当然串口也不例外 2.导入文件之后第二步也都是端口初始化(初始化里面语句的作用已经在后面说明) 在初始化完成之后,记得在main函数中调用 3.用串口发送数据 利用USART_SendData(USART1,'9');来发送一个字节的数据,printf();也可使用来发送字符串,在使用printf的时候记得给main()函数添加 #include stdio.h
[单片机]
STM32外部中断易出错总结
前言:这些问题都是我之前在工作中遇到的,后来觉得需要总结,自己记忆不好,所以在这个给自己打个mark。 一:触发方式 STM32 的外部中断是通过边沿来触发的,不支持电平触发; 二:外部中断分组 STM32 的每一个GPIO都能配置成一个外部中断触发源,STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB0,PC0,PD0,PE0,PF0,PG0为第一组,那么依此类推,我们能得出一共有16 组,STM32 规定,每一组中同时只能有一个中断触发源工作,那么,最多工作的也就是16个外部中断。 STM32 分组和对应中断处理函数分配: 管脚 中断标志 中断处理函
[单片机]
浅谈 STM32 硬件I2C的使用 (中断方式 无DMA 无最高优先级)
引子 STM32的硬件I2C很多人都对它望而却步。因为很多电工都说,STM32 硬件 I2C有BUG、不稳定、死机等等……最后都使用GPIO模拟I2C。 的确,模拟I2C好用。但是在我看来在一个72M的Cortex-M3的MCU上这样做非常不妥。一般来说I2C是一种慢速总线,就算工作在400kHz的快速模式上,I2C传送每个字节仍需要至少23us——还没有计算地址、起始信号和结束信号的发送。如果使用GPIO模拟的I2C,这23us的CPU时间都在空转中浪费了,而这23us已经可以做不少的事情了,所以在STM32上I2C还是使用硬件为佳——虽然它多多少少有点缺陷。 这篇文章不是给完全没有接触过STM32 硬件I2C的新手看的,看这篇
[单片机]
浅谈 <font color='red'>STM32</font> 硬件I2C的使用 (中断方式 无DMA 无最高优先级)
stm32入门——跑马灯(基于stm32f103zet6)
最近开始学stm32,着实感觉到了stm32和51之间的区别,但也有联系,总我感觉32与51之间最大的区别就是在使用某个外设之前,要对该外设进行时钟的使能(以达到降低功耗的目的),和相关配置。 刚学完跑马灯,下面对跑马灯用到的对IO口的配置相关知识分别对应官方库函数和寄存器进行总结。 如有错误或不足,请在下方留言。 文章内容基于正点原子战舰。 IO口的状态 IO口有八大模式:─ 输入浮空( GPIO_Mode_IN_FLOATING = 0x04,) ─ 输入上拉( GPIO_Mode_IPU = 0x48,) ─ 输入下拉( GPIO_Mode_IPD
[单片机]
<font color='red'>stm32</font>入门——跑马灯(基于stm32f103zet6)
stm32的IO 8种基本类型设置
GPIO_Mode_AIN //模拟输入 一般用作ADC等 GPIO_Mode_IN_FLOATING //浮空输入 可以用作按键 GPIO_Mode_IPD //下拉输入 GPIO_Mode_IPU //上垃输入 GPIO_Mode_Out_OD //开漏输出 GPIO_Mode_Out_PP //推挽输出 GPIO_Mode_AF_OD //复用开漏输出 GPIO_Mode_AF_PP //复用推挽输出 IO的输出类型设置主要还是查询芯片手册或者根据自己应用设置对应的类型。
[单片机]
【MCP3208/MCP3204】STM32多通道AD采集
芯片简介 MCP3208/MCP3204是一种片外12位精度的AD采集芯片,前者是8通道,后者是4通道,其他的都一样。找不到该芯片的中文手册的点这里。 引脚定义 时序 结合手册5.0章节的说明看时序图。 电平状态稳定时间 可以看到,最短稳定时间的最长的为500ns(0.5us),均小于1us,只要在程序中保证引脚的电平稳定时间至少超过1us即可。 控制位 第一个CS拉低且Din拉高的信号为起始位。紧跟着其实位的是Single/Diff位、以及D0 D1 D2位。 起始位后的第四个时钟周期的上升沿开始采样,在第五个时钟周期的下降沿采样结束。 如果设备上电的时候CS引脚是低电平,需要拉高再拉低
[单片机]
【MCP3208/MCP3204】<font color='red'>STM32</font>多通道AD采集
STM32管脚重定义
最近在学习STM32,在BZ上一篇关于的串口通信文章里有这么一段代码:RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO,ENABLE); 当初是参考开发的里子写的一直对GPIOD或上“RCC_APB2Periph_AFIO”这句话的意思没搞懂,通过这几天在网上查找资料和看手册,终于高清楚了,不敢独享,希望能对跟我一样的新手有所帮助吧o(∩_∩)o... STM32上有很多I/O口,也有很多的内置外设想I2C,ADC,ISP,USART等 ,为了节省引出管脚,这些内置外设基本上是与I/O口共用管脚的,也就是I/O管脚的复用功能。但是STM32还有一特别
[单片机]

推荐帖子

Yocto linux
有人用过Yoctolinux吗?这种移植方便吗?YoctolinuxIntel的Edison就是用的Yoctolinux只是一种根文件系统,还好把
hinii23 嵌入式系统
LPC2131入门.pdf
分享~~分享LPC2131入门.pdf好,言简意骇赞个
小草~ 单片机
STM32MPU全国线下培训正式启动,多个城市等您报名!
培训主题:基于Buildroot制作STM32MP13启动镜像时间:2024年3月21日9:30-17:30地点:苏州市工业园区星海书香世家酒店(金鸡湖店)桐星阁(具体地点可能会根据实际情况调整)时间:2024年3月26日9:30-17:30地点:郑州市中原区牡丹路与金梭路交叉口2F漫威咖啡(具体地点可能会根据实际情况调整)时间:2024年3月28日9:30-17:30地点:西安市高新区高新二
eric_wang ST传感器与低功耗无线技术论坛
测量铜板电阻
测量铜板电阻应该怎么做啊。求助测量铜板电阻本帖最后由maychang于2015-4-2515:11编辑 说“铜板”,大概不是指圆形铜质上有花纹和文字作为钱币使用的物体吧?测量电阻,那就必须指定该物体上面两个位置,所谓电阻,是这两个位置之间的电阻。另外在已经确定的两个位置之外(内外的外)确定另两个位置以接入电流。测量仪器,使用开尔文电桥(双电桥)。如果指定用伏安法测量,那就要在该物体上确定好四个位置后,外面两个位置接入电流,内面两个位置测量电压。就是一个非常小的电阻,
qqxiaoai 电子竞赛
通过MSP430F149的串口配置DS18B20的c语言程序
有谁知道写通过MSP430F149的串口配置DS18B20的c语言程序吗?通过MSP430F149的串口配置DS18B20的c语言程序串口配置?我刚跳过单独的串口和DS18B20/*************************************************程序功能:用DS18B20测量室温并在数码管上显示。-------------------------------------------------测试说明:观察显示温度数值。**********
qiao2012 微控制器 MCU
希望厂家出厂就是这款
空调罩子的创意,不得不服 哈哈哈希望厂家出厂就是这款111111等要拿下来洗的时候,就会感觉好麻烦,怀疑自己为什么要买这些东西不好意思,接受不了,担心晚上要被吓到空调上面应该也有风口吧,每次擦上面都很费事哦,吼吼~~~这个颜色一定要选好,空调位置也得选好。不然感觉会做噩梦哈哈哈,想到以前的彩灯充电器啊啊啊,你们这么说我忽然感觉也有点害怕,但是明明是初音未来啊哈哈,我家娃最爱哈哈,看到这个图心情好一点了啊,不过不同的人喜欢的样式不太一样
吾妻思萌 创意市集
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved