历史上的今天
返回首页

历史上的今天

今天是:2024年09月29日(星期日)

正在发生

2021年09月29日 | STM32的位带操作分析

2021-09-29 来源:eefocus

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 finishedrn");

GPIOA->ODR = 0xffff; /* 传统方式写:将GPIOA->ODR各个位写1 */

printf("Tratidional operate: GPIOA->ODR[0x%x]:0x%xrn", &GPIOA->ODR, GPIOA->ODR);

GPIOA->ODR = 0x0; /* 将GPIOA->ODR清零 */

printf("Clear GPIOA->ODR: GPIOA->ODR[0x%x]:0x%xrn", &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%xrn", &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%xrn", &GPIOA->ODR, Data); /* 可以看到位带操作读后,GPIOA->ODR各个比特位对应的别名区的值 */

while(1)

{

}

return 1;

}


串口打印的信息:

 本文主要参考以下资料编写:


 ·《CM3权威指南》第五章(87页~92页)


 ·《STM32F4xx中文参考手册》

推荐阅读

史海拾趣

Dow-Key Microwave Corporation公司的发展小趣事

为了保持市场竞争力,Dow-Key Microwave始终将创新作为公司发展的核心动力。公司不断推出新产品、新技术和新服务,以满足客户不断变化的需求。同时,公司还加强对员工的培训和激励,鼓励员工积极参与创新活动。这些措施的实施,使得Dow-Key Microwave在技术创新和产品升级方面取得了显著成效,进一步巩固了公司在行业中的领先地位。

Goldentech Discrete Semiconductor Inc公司的发展小趣事

为了进一步提升国际竞争力,Goldentech制定了明确的国际化战略。公司通过设立海外研发中心、销售网络和服务中心,加强与国际市场的联系和沟通。同时,Goldentech还积极参与国际标准的制定和推广工作,提升其在全球半导体行业的话语权和影响力。经过多年的努力,Goldentech已经成功在多个国家和地区建立了完善的业务体系和服务网络,为全球客户提供更加便捷、高效的服务和支持。

爱特姆(ATOM)公司的发展小趣事

爱特姆在国内市场取得一定成绩后,开始积极拓展国际市场。通过与欧洲、美国等国家的知名企业建立合作关系,爱特姆的产品逐渐打入国际市场,并赢得了良好的口碑。同时,公司还积极参加国际电子展会,与全球同行交流学习,不断提升自身的国际竞争力。

Axon' Cable公司的发展小趣事

Axon' Cable公司自1965年在法国成立起,便致力于通讯连接器的研发与生产。在创业初期,公司面临着资金短缺、技术瓶颈和市场竞争的诸多挑战。然而,Axon' Cable凭借其坚定的信念和不懈的努力,逐步突破了技术难关,并成功开发出了一系列具有竞争力的产品。这些产品在市场上得到了广泛认可,为公司的后续发展奠定了坚实的基础。

兵字(BingZi)公司的发展小趣事

随着公司规模的不断扩大和产品线的日益丰富,兵字公司开始注重品牌建设和市场拓展。公司注册了“BingZi兵字”商标,并通过一系列的市场推广活动,提升了品牌的知名度和美誉度。同时,兵字公司还积极开拓国内外市场,与多家知名企业建立了长期稳定的合作关系,实现了业务的快速增长。

CCS[Custom Computer Services]公司的发展小趣事

在电子行业中,产品质量和客户服务是企业生存和发展的关键。CCS公司始终坚持质量第一的原则,建立了严格的质量管理体系和客户服务体系。公司从原材料采购到产品生产、销售等各个环节都进行严格的质量控制,确保产品的质量和性能达到客户的期望。同时,CCS公司还提供了全方位的客户服务,包括售前咨询、售后服务和技术支持等,为客户提供了全方位的支持和帮助。

问答坊 | AI 解惑

放大电路的直流工作状态

这一节是本章的重点内容,在这一节中我们要掌握公式法计算Q点和图形法计算Q点  在学习之前,我们先来了解一个概念: 什麽是Q点?它就是直流工作点,又称为静态工作点,简称Q点。我们在进行静态分析时,主要是求基极直流电流IB ...…

查看全部问答>

问个初级问题:关于checksum

题目是这样的:从主控板给压缩机发送指令,每隔一秒一次,每次发送20个字节,其中前十位为发送起始标志位1bit,命令字节(8bit),发送结束标志位1bit。后十位为发送起始标志1位,checksum(8bit),结束标志1位。如果命令字节是10000000,请问chec ...…

查看全部问答>

关于发表话题回复话题时的系统故障

我们发表话题或者回复话题的时候。有事写很长,要很多时间。当好不容易打完了,然后点发表,这个时候会出现各种各样的错误(很正常而且几率很大。我试过基本十次有五六次都会错误),这个时候如果实现没保存那么辛辛苦苦打出来的东西就付诸东流,希 ...…

查看全部问答>

编译多媒体程序时,报错:cannot open input file 'strmiids.lib'

  首先用PB定制了一个内核,并生成了相应的SDK,安装了SDK后,用EVC调试一个多媒体程序时总是报错:   LINK : fatal error LNK1181: cannot open input file \'strmiids.lib\'       请问:     ...…

查看全部问答>

串口转USB出现乱码

不知道大家有没有出现过串口转USB在UBOOT下面出现乱码的?我用的sbc2410的板子,在vivi上正常,在norflash上启动uboot出现乱码用的是HL340的芯片…

查看全部问答>

FPGA时钟输出问题

EP3Cls200  fpGA中 pllout时钟输出引脚中说Optional negative terminal for external clock outputs from PLL[1..4]. These pins can only use thedifferential I/O standard if it is being fed by a PLL output  什么意思,时钟输出引 ...…

查看全部问答>

在做两块LM3S9B96用spi通信,从机收不到数。

把主机发送和从机接收的程序附上请大家帮我看看问题出在哪里?先谢谢了。SPI_rec_slave(从机接收程序)#include \"inc/hw_memmap.h\"#include \"inc/hw_ssi.h\"#include \"inc/hw_types.h\"#include \"driverlib/ssi.h\"#include \"driverlib/gpio.h ...…

查看全部问答>

【ULP Advisor Rule Table】规则2.1利用定时器完成延时操作

很多时候我们偷懒采用CPU在那里空跑的方式来获得延时,下面看看有哪些延时语句 __no_operation(); _NOP();复制代码这是空操作语句,其实我认为少量的这样的语句是可以接受的volatile int i = MAX_VALUE; while (i-- > 0);复制代码这种是最常见的 ...…

查看全部问答>

问个UCOS条件编译的问题

#ifdef OS_GLOBALS #define OS_EXT #else #define OS_EXT extern #endif 问题可能有些幼稚,我不知道存不存在这种可能。 在一个项目中很多C文件调用这段程序,有的C文件里定义的OS_GLOBALS,而有些没有定义,那么OS_EXT是什么情况? NULL还 ...…

查看全部问答>

飞行模式下手机充电速度翻倍?真 假?

近日有人说,把手机调到飞行模式,充电速度快一倍,适用于紧急用途。 专业人士称:手机充电时,信号功能也在运作,会消耗许多电量,飞行模式下充电,手机本身就能省不少电量。至于能快多少? 根据手机种类、新旧程度而定。赶紧试试! …

查看全部问答>