STM32的位带操作分析_位代操作-程序员宅基地

技术标签: 位带操作  STM32  mcu  MCU  

8051单片机可以直接对某一位IO进行读写操作,而Cortex-M3的位带操作是8051位寻址区的加强版。使用位带操作后,可以使用普通的加载/存储指令对单一的比特进行读写操作。
一、相关概念。
位带区:支持位带操作的地址区。
位带别名区:对别名地址的访问最终作用到位带区的访问上。位带别名区对位带区的访问有个地址映射过程。

二、位带操作的原理
位带操作的最终目的是想对位带区的比特位进行独立的读写操作。但它是通过对位带别名区的操作来实现的。
具体过程如下:
对位带别名区进行读写访问,位带别名区通过地址映射关系映射到相应的位带区,对位带区进行原始比特的读写操作。

三、地址映射
上面对位带操作进行了简单的介绍,那么哪些地址支持位带操作?它们对应的位带别名区地址又是多少?两者间的地址映射关系又是怎么样的?
1、支持位带操作的地址
Cortex-M3有两个区支持位带操作。这两个区除了像普通的RAM一样使用外,还可以通过位带别名区进行操作。这两个区(位带区)分别是:
SRAM区中的最低1MB:0x2000 0000 - 0x200F FFFF
片上外设去中的最低1MB:0x4000 0000 - 0x400F FFFF
这两个位带区对应的位带别名区是:
SRAM区中的最低1MB的位带区对应的位带别名区:

片上外设去中的最低1MB的位带区对应的位带别名区:

2、位带区与位带别名区的地址映射关系
位带别名区把位带区的每一个比特位膨胀成32位的字,即位带区的每一个比特位对应位带别名区中一个4个字节大小的地址。
下图示例SRAM区中的最低1MB的位带区与位带别名区的膨胀对应关系:

计算公式:
对于SRAM位带区的某个比特,记它所在字节地址为A,比特位序号为n(0<=n<=7),则该比特位对应的位带别名区的地址为:

对于片上外设位带区的某个比特,记它所在字节地址为A,比特位序号为n(0<=n<=7),则该比特位对应的位带别名区的地址为:

说明:“*4”表示一个字为4个字节,“*8”表示一个字节中有8个比特。

四、读写操作的机制
在位带区中,虽然每个比特位都映射到别名区的一个字,但别名区的字只有LSB(最低位有效)有效,所以读写操作是对别名区字的LSB进行读写,LSB的数值是0或1.
1、读流程:

举例子:
读取SRAM地址0x2000 0000 的第二位的值:

2、写流程:读、改、写

举例子:
将SRAM地址0x2000 0000 的第二位的值置1:


五、位带操作编程实现
在C编译器中并没有直接支持位带操作,比如,C编译器并不知道同一块内存可以用不同的地址来访问,也不知道对位带别名区的访问只对LSB有效。欲在C中使用位带操作,最简单的做法时#define一个位带别名区的地址。
1、位带操作的宏定义
为了简化位带操作,我们可以建议一个把”位带地址+位序号“转换为别名地址的宏,再建立一个把别名地址转换为指针类型的宏:
#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)) 	/* 某地址某一位的位带操作的宏  */

2、举个例子
下面以STM32F407的GPIOA->ODR寄存器(地址为0x40020014)为例,通过位带操作进行读写,并与传统方式读写比较,并通过串口将信息发送到控制台显示。代码如下:
头文件定义:
#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+20) //0x40020014
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  
main函数:
int main(void)
{
	u8 Temp;
	u16 Data;
	Data = 0;
	
	Stm32_Clock_Init(336,8,2,7);//初始化时钟为 168Mhz
	delay_init(168);  //初始化延时函数
	uart_init(84,115200);  //串口初始化为 115200

	printf("init finished\r\n");
	
	GPIOA->ODR = 0xffff;			/* 传统方式写:将GPIOA->ODR各个位写1 */
	printf("Tratidional operate: GPIOA->ODR[0x%x]:0x%x\r\n", &GPIOA->ODR, GPIOA->ODR);		
	GPIOA->ODR = 0x0;			/* 将GPIOA->ODR清零 */
	printf("Clear GPIOA->ODR: GPIOA->ODR[0x%x]:0x%x\r\n", &GPIOA->ODR, GPIOA->ODR);

	for(Temp = 0; Temp < 16; Temp++)
	{
		PAout(Temp) = 1;		/* 位带操作写:通过位带别名区写GPIOA->ODR每一位为1 */
	}		
	printf("Bit-band write: GPIOA->ODR[0x%x]:0x%x\r\n", &GPIOA->ODR, GPIOA->ODR);	/* 可以看到位带操作写后,GPIOA->ODR各位的值 */

	for(Temp = 0; Temp < 16; Temp++)
	{
		Data |= (PAout(Temp) << Temp);		/* 位带操作读:通过位带别名区读GPIOA->ODR每一位的值,并存在Data中 */
	}		
	printf("Bit-band read: GPIOA->ODR[0x%x]:0x%x\r\n", &GPIOA->ODR, Data);		/* 可以看到位带操作读后,GPIOA->ODR各个比特位对应的别名区的值 */
	
	while(1)
	{
		
	}
	
	return 1;
}

串口打印的信息:


本文主要参考以下资料编写:
·《CM3权威指南》第五章(87页~92页)
·《STM32F4xx中文参考手册》
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/bulebin/article/details/73730141

智能推荐

Linux中安装JDK-RPM_linux 安装jdk rpm-程序员宅基地

文章浏览阅读545次。Linux中安装JDK-RPM方式_linux 安装jdk rpm

net高校志愿者管理系统-73371,计算机毕业设计(上万套实战教程,赠送源码)-程序员宅基地

文章浏览阅读25次。免费领取项目源码,请关注赞收藏并私信博主,谢谢-高校志愿者管理系统主要功能模块包括页、个人资料(个人信息。修改密码)、公共管理(轮播图、系统公告)、用户管理(管理员、志愿用户)、信息管理(志愿资讯、资讯分类)、活动分类、志愿活动、报名信息、活动心得、留言反馈,采取面对对象的开发模式进行软件的开发和硬体的架设,能很好的满足实际使用的需求,完善了对应的软体架设以及程序编码的工作,采取SQL Server 作为后台数据的主要存储单元,采用Asp.Net技术进行业务系统的编码及其开发,实现了本系统的全部功能。

小米宣布用鸿蒙了吗,小米OV对于是否采用鸿蒙保持沉默,原因是中国制造需要它们...-程序员宅基地

文章浏览阅读122次。原标题:小米OV对于是否采用鸿蒙保持沉默,原因是中国制造需要它们目前华为已开始对鸿蒙系统大规模宣传,不过中国手机四强中的另外三家小米、OPPO、vivo对于是否采用鸿蒙系统保持沉默,甚至OPPO还因此而闹出了一些风波,对此柏铭科技认为这是因为中国制造当下需要小米OV几家继续将手机出口至海外市场。 2020年中国制造支持中国经济渡过了艰难的一年,这一年中国进出口贸易额保持稳步增长的势头,成为全球唯一..._小米宣布用鸿蒙系统

Kafka Eagle_kafka eagle git-程序员宅基地

文章浏览阅读1.3k次。1.Kafka Eagle实现kafka消息监控的代码细节是什么?2.Kafka owner的组成规则是什么?3.怎样使用SQL进行kafka数据预览?4.Kafka Eagle是否支持多集群监控?1.概述在《Kafka 消息监控 - Kafka Eagle》一文中,简单的介绍了 Kafka Eagle这款监控工具的作用,截图预览,以及使用详情。今天_kafka eagle git

vue.js not detected问题解决-程序员宅基地

文章浏览阅读7.8k次,点赞9次,收藏20次。最近在看vue的时候,发现之前装过的vuedevtools提示vue.js is not detected。_vue.js not detected

SBUS协议的串口发送数据和DMA解码数据问题详解_subs协议-程序员宅基地

文章浏览阅读856次,点赞12次,收藏15次。SBUS协议编码和解析_subs协议

随便推点

OC学习笔记-Objective-C概述和特点_objective-c特点及应用领域-程序员宅基地

文章浏览阅读1k次。Objective-C概述Objective-C是一种面向对象的计算机语言,1980年代初布莱德.考斯特在其公司Stepstone发明Objective-C,该语言是基于SmallTalk-80。1988年NeXT公司发布了OC,他的开发环境和类库叫NEXTSTEP, 1994年NExt与Sun公司发布了标准的NEXTSTEP系统,取名openStep。1996_objective-c特点及应用领域

STM32学习笔记6:TIM基本介绍_stm32 tim寄存器详解-程序员宅基地

文章浏览阅读955次,点赞20次,收藏16次。TIM(Timer)定时器定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断16位计数器、预分频器、自动重装寄存器的时基单元,在 72MHz 计数时钟下可以实现最大 59.65s 的定时,59.65s65536×65536×172MHz59.65s65536×65536×721​MHz不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能。_stm32 tim寄存器详解

前端基础语言HTML、CSS 和 JavaScript 学习指南_艾编程学习资料-程序员宅基地

文章浏览阅读1.5k次。对于任何有兴趣学习前端 Web 开发的人来说,了解 HTML、CSS 和JavaScript 之间的区别至关重要。这三种前端语言都是您访问过的每个网站的用户界面构建块。而且,虽然每种语言都有不同的功能重点,但它们都可以共同创建令人兴奋的交互式网站,让用户保持参与。因此,您会发现学习所有三种语言都很重要。如果您有兴趣从事前端开发工作,可以通过多种方式学习这些语言——在艾编程就可以参与到学习当中来。在本文中,我们将回顾每种语言的特征、它们如何协同工作以及您可以在哪里学习它们。HTML vs C._艾编程学习资料

三维重构(10):PCL点云配准_局部点云与全局点云配准-程序员宅基地

文章浏览阅读2.8k次。点云配准主要针对点云的:不完整、旋转错位、平移错位。因此要得到完整点云就需要对局部点云进行配准。为了得到被测物体的完整数据模型,需要确定一个合适的坐标系变换,将从各个视角得到的点集合并到一个统一的坐标系下形成一个完整的数据点云,然后就可以方便地进行可视化,这就是点云数据的配准。点云配准技术通过计算机技术和统计学规律,通过计算机计算两个点云之间的错位,也就是把在不同的坐标系下的得到的点云进行坐标变..._局部点云与全局点云配准

python零基础学习书-Python零基础到进阶必读的书藉:Python学习手册pdf免费下载-程序员宅基地

文章浏览阅读273次。提取码:0oorGoogle和YouTube由于Python的高可适应性、易于维护以及适合于快速开发而采用它。如果你想要编写高质量、高效的并且易于与其他语言和工具集成的代码,《Python学习手册:第4 版》将帮助你使用Python快速实现这一点,不管你是编程新手还是Python初学者。本书是易于掌握和自学的教程,根据作者Python专家Mark Lutz的著名培训课程编写而成。《Python学习..._零基础学pythonpdf电子书

Linux socket编程实例 多进程 文件传输 服务器 网络通信【C语言】_linux网络编程文件传输,基于c语言-程序员宅基地

文章浏览阅读2.6k次,点赞11次,收藏60次。在Linux系统中,使用C语言编程设计一个基于TCP/IP的文件传输系统,从而实现网络文件的收发。主要实现为一个面向连接的、并发服务器,并由客户端程序请求文件。编写网络文件传输服务器和客户端程序,其中客户端能够将文件名称传输给服务器,服务器从客户端接收文件名,并用请求的文件内容应答客户端。同时要求一个服务器能够为多个客户并发提供服务。_linux网络编程文件传输,基于c语言