STM32与LPC17XX中的位带(bit-band)操作理解

发布者:平安守护最新更新时间:2019-11-28 来源: 51hei关键字:STM32  LPC17XX  位带(bit-band)操作 手机看文章 扫描二维码
随时随地手机看文章

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


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


CM3 使用如下术语来表示位带存储的相关地址:


位带区:支持位带操作的地址区


位带别名:对别名地址的访问最终作用到位带区的访问上(这中途有一个地址映射过程)


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

 

读以上描述有点累


我个人理解如下

位带解释:

 

位带处理把一寄存器的每一位转换成字寄存器(32位)。

这样一个寄存器(32位)变成32个寄存器(32位)。

占硬件资源大。

51单片机有专门硬位区。位处理编程高效

Cortex-M3没有专门硬位区,位处理通过软件方法,可用位转成字。

具体操作如下


支持位带操作的两个内存区的范围是:


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 个比特。


这里再不嫌啰嗦地举一个例子:

1. 在地址 0x20000000 处写入 0x3355AACC

2. 读取地址0x22000008。本次读访问将读取 0x20000000,并提取比特 2,值为 1。

3. 往地址 0x22000008 处写 0。本次操作将被映射成对地址 0x20000000 的“读-改-写”操作(原子的),把比特2 清 0。

4. 现在再读取 0x20000000,将返回 0x3355AAC8(bit[2]已清零)。


位带别名区的字只有 LSB 有意义。另外,在访问位带别名区时,不管使用哪一种长度的数据传送指令(字/半字/字节),都把地址对齐到字的边界上,否则会产生不可预料的结果。

///////////////////////////////////////////////////////////////

//位带操作,实现51类似的GPIO控制功能

//具体实现思想,参考<>第五章(87页~92页).

//IO口操作宏定义

#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)  //输入


以上方法可移植到LPC17xx。只是地址不同。

关键字:STM32  LPC17XX  位带(bit-band)操作 引用地址:STM32与LPC17XX中的位带(bit-band)操作理解

上一篇:lpc1700 can通讯例程
下一篇:STM32 DSP库函数详解

推荐阅读最新更新时间:2024-11-12 07:42

STM32 定时器输出 PWM
我们通过TIM3 输出PWM 去驱动 SG90电机 配置如下 1.GPIO结构体 2.配置通用定时器结构体 3.配置定时去输出PWM结构体 4.打开时钟 — GPIO时钟,TIM定时器时钟,部分重映射时钟 5.配置PWM比较值 一 我们使用定时器3 通道2 重映射之后为PB5 GPIO_InitTypeDef GPIO_motorstruct; GPIO_motorstruct.GPIO_Mode =GPIO_Mode_AF_PP; GPIO_motorstruct.GPIO_Pin = GPIO_Pin_5; GPIO_motorstruct.GPIO_Speed =GPIO_Speed_50M
[单片机]
基于STM32的外设的GPIO外设设置总结
1、背景 外设驱动的寄存器设置对于外设功能正常运行异常重要。现在对GPIO的配置进行总结。 2、GPIO的配置总结 复用GPIO配置 GPIO设置为输出或者是复用模式时,需要设置输出速度;而无论设置为什么模式,都要对GPIO的内部上下拉进行设置。 注意:在输入模式(普通输入/模拟输入)下,OTYPE和OSPEED参数无效!!
[单片机]
基于<font color='red'>STM32</font>的外设的GPIO外设设置总结
关于STM32通用定时器更新事件中断
//定时器3中断服务程序 void TIM3_IRQHandler(void) { if(TIM3- SR&0X0001) //产生更新事件 { LED1=!LED1; LED0=!LED0; } TIM3- SR&=~(1 0);//清除中断标志位 } //通用定时器中断初始化 //这里时钟选择为APB1的2倍,而APB1为36M //arr:自动重装值。 //psc:时钟预分频数 //这里使用的是定时器3! void Timerx_Init(u16 arr,u16 psc) { TIM3- SMCR&=0xfffffff8; //从模式控制寄存器设置预分
[单片机]
STM32的存储分配问题
keil编译后产生下面的信息: Program Size: Code=37970 RO-data=7598 RW-data=212 ZI-data=12340 其中 code ro-data rw-data zi-data分别代表什么意思? 回答: 代码段+初始化数据段=FLASH,数据段+0初始化数据段=RAM; ARM编译中的RO、RW和ZI DATA区段 ARM程序(指在ARM系统中正在执行的程序,而非保存在ROM中的bin文件)的组成 一个ARM程序包含3部分:RO段,RW段和ZI段 RO是程序中的指令和常量 RW是程序中的已初始化变量 ZI是程序中的未初始化的变量 由以上3点说明可以理解为: RO就是readonly
[单片机]
STM32小问题-复用调试接口JTAG/SWD为普通GPIO
这几天做毕业设计,按键模块用到了PA14和PA15这两个IO口(由于IO是引出到拓展板上,所以刚开始并不知道PA14和PA15是被调试接口占用了)。设置好相应的寄存器后发现只有PA15正常按下能被拉低,而PA14用万用表检测始终处于低电平状态。刚开始我以为这个管脚坏了,就想着设置成输出高电平试试,结果可想而知,查看手册后发现在在复位后JTAG接口的PA14被设置为下拉了,所以按键读回来的永远是低电平。 后来发现核心板上PA15引脚连接到了JTAG接口就想能不能通过复用把这几个口解放出来,毕竟在正常应用中调试接口是不工作的,还不如利用起来(其实是我懒得再改板子PCB了),后来查看手册发现真的可以复用起来。 手册描述如下 手册
[单片机]
STM32堆栈学习
STM32里面 STACK 和 HEAP ,前者为堆,后者为栈。 今天在调试一段向Server发送程序的时候:出现一个奇怪的现象: fun(){ fun1( ); //初始化 fun2( ); //链接远程服务器 fun3( ); //发送数据 } 整体运行的时候,运行到fun3( );的地方就出现HaltFault!注释掉fun3( ),然后运行fun1( )和fun2( );可以运行。再注释掉fun1( )和fun2( )(此时已经链接上),单独运行fun3( );也能运行。吃午饭是和同事说明这一情况,他提醒说是不是因为堆栈的问题,后来回来查看MAP文件情况。 ===================
[单片机]
Visual Studio 2019 +STM32实现串口通讯
1.下载 免费版 Visual Studio 2019 并进行安装visualstudio.microsoft.com/zh-hans/ 2.双击软件创建项目 3.选择Windows窗体应用程序(.NET Framework)创建项目。 4.项目创建完成,初始界面。 5.选择左侧的工具栏,选择 组件,然后双击 串口组件将串口添加进入项目。 6.点击鼠标右键,修改串口模块的属性,包括 波特率等,本实验采用默认。 7.双击串口模块,添加数据接收中断函数 8.添加按钮模块,控制STM32开发板LED灯的亮灭。 9.好的现在基本界面与模块添加完成,开始写程序,添加程序各种变量: //串口通讯命令 publi
[单片机]
Visual Studio 2019 +<font color='red'>STM32</font>实现串口通讯
意法半导体推出STM32微处理器专用高集成度电源管理芯片
优化的集成化电源管理芯片,内置保护功能,驱动MPU及外设 2024 年 10 月 18 日, 中国——意法半导体 STM32MP2 微处理器配套电源管理芯片STPMIC25 现已上市。 新产品在一个便捷封装内配备 16 个输出通道,可为MPU的所有电源轨以及系统外设供电,完成硬件设计仅需要少量的外部滤波和稳定功能组件。评估板STEVAL-PMIC25V1现已上市,开发者可立即开始开发应用。 新电源管理芯片包含七个 DC/DC 降压转换器和八个低压差 (LDO) 稳压器,还有一个额外的 LDO稳压器为系统 DDR3 和 DDR4 DRAM 提供参考电压 (Vref) 。在八个 LDO稳压器中有一个3.3V 通道专用稳压
[嵌入式]
意法半导体推出<font color='red'>STM32</font>微处理器专用高集成度电源管理芯片
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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