历史上的今天
返回首页

历史上的今天

今天是:2024年11月20日(星期三)

正在发生

2018年11月20日 | 高手经验!STM32中的位带(bit-band)操作

2018-11-20 来源:eefocus

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


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


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


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


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

 

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

 

1.jpg?imageView2/2/w/550 

2.jpg?imageView2/2/w/550

4.png?imageView2/2/w/550

 

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


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


[cpp] view plain copy///////////////////////////////////////////////////////////////

//位带操作,实现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) //输入


推荐阅读

史海拾趣

Corsair Electrical Connectors Inc公司的发展小趣事

在国内市场取得一定成绩后,Corsair开始将目光投向了更广阔的国际市场。公司积极参加国际电子展会,与海外客户建立联系,拓展销售渠道。同时,Corsair还根据不同国家和地区的市场需求,调整产品策略,提供定制化的解决方案。这些努力使得Corsair的产品逐渐走进了国际市场,公司的影响力也不断扩大。

Abracon公司的发展小趣事

Corsair Electrical Connectors Inc公司自创立之初,便专注于电气连接器的制造。公司创始人凭借其深厚的行业经验和敏锐的市场洞察力,准确把握了连接器在电子行业中的重要地位,并决定以此为切入点,打造一家专业的连接器制造商。在创立初期,Corsair面临着资金短缺、技术落后等多重困难,但创始人凭借坚定的信念和不懈的努力,带领公司逐步走上了正轨。

Applied Micro Circuits (MACOM)公司的发展小趣事

在经历了多次的收购与转手后,MACOM公司重新获得了独立地位,并开始了新的发展历程。公司推出了首个GaN功率器件,这一技术创新在行业内引起了广泛关注。随后,MACOM继续通过收购微波和射频公司MIMIX以及高速光通信公司Optomai来扩展其业务范围。这些举措不仅增强了公司的技术实力,也为其在全球市场上取得竞争优势奠定了基础。

Carlisle Interconnect Technologies公司的发展小趣事

随着电子行业的快速发展,Carlisle Interconnect Technologies不断进行技术升级和产品创新。公司不断引进先进的生产设备和技术,提升产品的质量和性能。同时,公司还积极拓展产品线,从最初的绝缘电线电缆扩展到连接器、传感器等多个领域。这种多样化的产品策略使得公司能够更好地满足客户的多样化需求,也在市场上取得了更大的成功。

EMMICRO公司的发展小趣事

面对竞争激烈的电子市场,EMMICRO公司制定了精准的市场拓展策略。公司根据市场需求和客户需求,不断调整产品结构和市场定位,积极开拓新的销售渠道和合作伙伴。同时,公司还加大了对新兴市场的投入和布局,通过差异化竞争策略,成功打开了多个新的市场领域。

ABL Aluminum Components公司的发展小趣事

ABL Aluminum Components公司自成立以来,一直注重技术创新。早期,公司研发出了一种新型铝合金材料,这种材料具有优异的导电性和轻量化特点,迅速在电子行业引起关注。随着技术的不断迭代,ABL公司逐步将这种材料应用于手机、电脑等消费电子产品的内部组件,大大提高了产品的性能和用户体验。凭借这一技术优势,ABL公司逐渐在电子行业中占据了一席之地。

问答坊 | AI 解惑

无线发射功率以及接收灵敏度

发射功率与增益 无线电发射机输出的射频信号,通过馈线(电缆)输送到天线,由天线以电磁波形式辐射出去。电磁波到达接收地点后,由天线接收下来(仅仅接收很小很小一部分功率),并通过馈线送到无线电接收机。因此在无线网络的工程中,计算发 ...…

查看全部问答>

请教:如何从硬盘引导进入vxworks

各位,我先从优盘引导进入dos,盘符为C: 然后把生成的bootrom.sys,vxworks以及vxload.com拷贝到硬盘D:(已用format d:/s格式化了) 结果启动到verifying DMI pool data......就不动了,我的硬盘是4G的电子盘,我不知道这个做法对否?希望大家能帮 ...…

查看全部问答>

又是可怕的DEMO: InterruptInitialize failed!!! 请各位前辈帮帮忙。

InterruptInitialize(SysInt,Interruptevent,NULL,0)      我的这个函数总是返回为FALSE,      SysInt在oalintr.h上已经定义,而且在cfw.s   和armint.c也加入相应的中断处理,使能,代码Interru ...…

查看全部问答>

你知道预处理器标识#error的目的吗?

   这问题对区分一个正常的伙计和一个书呆子是很有用的。只有书呆子才会读C语言课本的附录去找出象这种问题的答案。当然如果你不是在找一个书呆子,那么应试者最好希望自己不要知道答案。…

查看全部问答>

成立一个电子技术论坛,大家去看看!!www.520ic.cn

关于单片机、开关电源、信号源与频率计的专业论坛,大家有问题或者想下相关资料的去看看。另外本站首页提供200多万的ic芯片pdf资料搜索下载。www.520ic.cn…

查看全部问答>

网络驱动无法调用我的中断服务程序?/(帮忙)

通过PCI 总线配置寄存器,并安装了中断服务程序,查看中断寄存器也显示发送 和接收包正常,但就是发完和接完就是没有调用中断程序…

查看全部问答>

各位用过的兄弟:STM32生产时怎么设置保密性?

                                 如题,怎样设置以防止软件被读出??…

查看全部问答>

不好意思顶了老帖子,我对UART超时的用法。

我在CC2430上实现了MODBUS,在CC1110上实现了UART透传。 UART应用程序中超时,串口中断的时候数据往环形队列里面放,队列就是一个组数,有两个标记表示头和尾,这个方法我也是模仿一些国外开发系统中集成的程序。 主程序中用getch函数,读队 ...…

查看全部问答>

请教关于STM8S105的问题

                                 请问什么原因会导致STM8S105的可用RAM空间小于128字节呢?文档上不是说有2K的RAM吗。程序出了一点小问题,感觉是ra ...…

查看全部问答>