历史上的今天
今天是:2024年09月30日(星期一)
2021年09月30日 | STM32 进阶教程 8 - 位带操作
2021-09-30 来源:eefocus
前言
有过51单片机开发经历的朋友应该都对51的IO口或一些特殊寄存器可以直接按位操作的方式不陌生吧,那么在stm32中有没有类似的操作呢,答案是肯定的,本节将给大家介绍如何在STM32中实现位带操作。
在《ARM Cortex-M3权为指南》中的第87页对位带操作如下描述:
位带操作
支持了位带操作后,可以使用普通的加载/存储指令来对单一的比特进行读写。在 CM3中,有两个区中实现了位带。其中一个是 SRAM 区的最低 1MB 范围,第二个则是片内外设区的最低 1MB 范围。这两个区中的地址除了可以像普通的 RAM 一样使用外,它们还都有自己的“位带别名区”,位带别名区把每个比特膨胀成一个 32 位的字。当你通过位带别名区访问这些字时,就可以达到访问原始比特的目的。

位带区与位带别名区的膨胀关系图 A

位带区与位带别名区的膨胀对应关系图 B
示例详解
基于硬件平台: STM32F10C8T6最小系统板, MCU 的型号是 STM32F103c8t6, 使用stm32cubemx 工具自动产生的配置工程,使用KEIL5编译代码。

本示例所用的最小系统板原理图:

关于CUBEMX工具及KEIL工具的操作将不再细讲,如果还有不熟悉的可以查看之前的教程文档。下面直接介绍工程配置:
系统时钟树

定时器配置

引脚配置
中断配置(保持默认)

工程代码
本节以stm32f103芯片为例,关于位带操作的基本说明/举例(可参看《ARM Cortex-M3权为指南》):
位带操作的概念其实30年前就有了,那还是8051 单片机开创的先河。如今,CM3 将此能力进化,这里的位带操作是 8051 位寻址区的威力大幅加强版。
CM3 使用如下术语来表示位带存储的相关地址
z 位带区: 支持位带操作的地址区
z 位带别名: 对别名地址的访问最终作用到位带区的访问上(注意:这中途有一个对
地址映射过程)
在位带区中,每个比特都映射到别名地址区的一个字——这是只有 LSB 有效的字。当一个别名地址被访问时,会先把该地址变换成位带地址。对于读操作,读取位带地址中的一个字,再把需要的位右移到 LSB,并把 LSB 返回。对于写操作,把需要写的位左移至对应的位序号处,然后执行一个原子的“读-改-写”过程。
支持位带操作的两个内存区的范围是:
0x2000_0000‐0x200F_FFFF(SRAM 区中的最低 1MB)
0x4000_0000‐0x400F_FFFF(片上外设区中的最低 1MB)
对于 SRAM 位带区的某个比特,记它所在字节地址为 A, 位序号为 n(0<=n<=7),则该比特在别名区的地址为:
AliasAddr= 0x22000000+((A‐0x20000000)*8+n)*4 =0x22000000+ (A‐0x20000000)*32 + n*4
对于片上外设位带区的某个比特,记它所在字节的地址为 A,位序号为 n(0<=n<=7),则该比特在别名区的地址为:
AliasAddr= 0x42000000+((A‐0x40000000)*8+n)*4 =0x42000000+ (A‐0x40000000)*32 + n*4
上式中,“*4”表示一个字为 4 个字节,“*8”表示一个字节中有 8 个比特。
对于 SRAM 内存区,位带别名的重映射如表 5.2 所示:
表 5.2 SRAM 区中的位带地址映射
位带区 等效的别名地址
0x20000000.0 0x22000000.0
0x20000000.1 0x22000004.0
0x20000000.2 0x22000008.0
…
0x20000000.31 0x2200007C.0
0x20000004.0 0x22000080.0
0x20000004.1 0x22000084.0
0x20000004.2 0x22000088.0
…
0x200FFFFC.31 0x23FFFFFC.0
对于片上外设,映射关系如下表所示:
表 5.3 SRAM 区中的位带地址映射
位带区 等效的别名地址
0x40000000.0 0x42000000.0
0x40000000.1 0x42000004.0
0x40000000.2 0x42000008.0
…
0x40000000.31 0x4200007C.0
0x40000004.0 0x42000080.0
0x40000004.1 0x42000084.0
0x40000004.2 0x42000088.0
…
0x400FFFFC.31 0x43FFFFFC.0
在main.c中加入如下图所示代码:
编译工程,下载程序看效果,可以看到LED(PC13引脚驱动)亮500ms灭500ms交替进行,查看PC13引脚上的波形:

通过上面的实例,我们成功地通过使用位带别名地址实现对寄存器中位的操作程,成功控制PC13引脚来控制LED的亮灭。是不是很简单,对于在SRAMSRAM 内存区,通过位带别名同样可以轻易实现对位操作,有兴趣的同学可以自行实险一下。
上一篇:STM32位带操作的详解
史海拾趣
|
0.引 言 目前,我国对于大部分供电电力设备的监控和管理上基本还停留在人工巡查这种比较原始的管理方式下(例如铁路道口的信号电源),不但管理效率低下,而且供电质量和水平都得不到有效的保证。本文以实时操作系统small RTOS51为基础,主要探 ...… 查看全部问答> |
|
目录: 上册: 第1章 电路元件的电路定律 1.1 电路和电路模型 1.2 电流、电压、电动势 1.3 电路元件的功率 1.4 电阻元件 1.5 电感元件 1.6 电容元件 1.7 电源元件 1.8 受控电源 1.9 基尔霍夫定律 习题 第2章 简单电阻电路 ...… 查看全部问答> |
|
本人最近正在用VeriLog HDL语言编写一个异步FIFO,我采用的是二进制转换为格雷码来判空判满。但能力有限,两天下来都没有结果,希望得到高人指点。… 查看全部问答> |
|
近来公司网络很不稳定,时不时出现所有人不能上网的现象,我在其中一台电脑上装上了赛门铁克的网络安全特警NIS2007,马上2007就发现了一个ARP病毒,我把所有的电脑都装上了NIS2007,老大很高兴,当即批准购买8套正版NIS2007。… 查看全部问答> |
|
本帖最后由 dontium 于 2015-1-23 13:21 编辑 问题描述写在附件的图片上。望高人指点迷津。谢谢! 实际测量一个样品,Vp=2.84V。 [ 本帖最后由 y651848590 于 2011-7-14 21:42 编辑 ] … 查看全部问答> |
|
#ifndef __YIWEI595_H__#define __YIWEI595_H__#include \"msp430x14x.h\"#include \"delay.h\" #define LCK_OUT P3DIR|=BIT3 #define LCK_IN P3DIR&=~BIT3 #define LCK_H P3OUT|=BIT3 #def ...… 查看全部问答> |









