历史上的今天
返回首页

历史上的今天

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

正在发生

2021年09月30日 | STM32位带操作详细介绍

2021-09-30 来源:eefocus

前言

//在STM32中,如果我们要使PB0端口输出低电平,可以用如下语句

GPIOB->ODR |= 0<<0;

//在51单片机中我们是这样的

P0 = 0xff;   //总线操作

//还有一种方法

sbit LED1 = P0^0;

LED1 = 0;//位操作


在STM32中能不能实现位操作呢,当然是可以的,这种方法我们叫做位带操作。位操作就是可以单独的对一个比特位读和写。


1.位带简介

在STM32中,有两个地方实现了位带,一个是 SRAM 区的最低 1MB 空间,另一个是外设区最低 1MB 空间。这两个 1MB 的空间除了可以像正常的 RAM 一样操作外,他们还有自己的位带别名区,位带别名区把这 1MB 的空间的每一个位膨胀成一个 32 位的字,当访问位带别名区的这些字时,就可以达到访问位带区某个比特位的目的。


比如位带区:外设区,这其中的一个位,可以在位带别名区重新找到4个字节的地址,也就是32位,来重新命名,而这32位,只有最低位有效。所以空间利用不是很充足,但是提供了方便。


例子:

PB的ODR寄存器地址为0x40010C0C,假设我们就操作PB0,即操作ODR寄存器第0位,那么这个位新的地址Addr= =0x42000000+ (0x40010C0C-0x40000000)84 +0*4。


给这个地址命名为PBout(0);


2.计算公式

外设区:

AliasAddr= =0x42000000+ (A-0x40000000)84 +n*4


0X42000000 是外设位带别名区的起始地址, 0x40000000 是外设位带区的起始地址,(A-0x40000000)表示该比特前面有多少个字节,一个字节有 8 位,所以8,一个位膨胀后是 4 个字节,所以4, n 表示该比特在 A 地址的序号,因为一个位经膨胀后是四个字节,所以也*4。


SRAM区:

AliasAddr= =0x22000000+ (A-0x20000000)84 +n*4


公式分析同上


统一公式

为了方便操作,我们可以把这两个公式合并成一个公式,把“位带地址+位序号”转

换成别名区地址统一成一个宏。


 // 把“位带地址+位序号”转换成别名地址的宏

2 #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF)<<5)+(bitnum<<2))


addr & 0xF0000000 是为了区别 SRAM 还是外设,实际效果就是取出 4 或者 2,如果是外设,则取出的是 4, +0X02000000 之后就等于 0X42000000, 0X42000000 是外设别名区的起始地址。如果是 SRAM,则取出的是 2, +0X02000000 之后就等于 0X22000000,0X22000000 是 SRAM 别名区的起始地址。

addr & 0x00FFFFFF 屏蔽了高三位,相当于减去 0X20000000 或者 0X40000000,但是为什么是屏蔽高三位?因为外设的最高地址是: 0X2010 0000, 跟起始地址 0X20000000 相减的时候,总是低 5 位才有效,所以干脆就把高三位屏蔽掉来达到减去起始地址的效果,具体屏蔽掉多少位跟最高地址有关。 SRAM 同理分析即可。 <<5 相当于84, <<2 相当于*4,这两个我们在上面分析过。


最后我们就可以通过指针的形式操作这些位带别名区地址,最终实现位带区的比特位操作。


// 把一个地址转换成一个指针

#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))

// 把位带别名区地址转换成指针

#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))


3.GPIO位带实现

// 把“位带地址+位序号”转换成别名地址的宏

#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF)<<5)+(bitnum<<2))


// 把一个地址转换成一个指针

#define MEM_ADDR(addr)           *((unsigned long *)(addr))

// 把位带别名区地址转换成指针

#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))


//GPIO ODR 和 IDR 寄存器地址映射

#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 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


//单独操作 GPIO 的某一个 IO 口, n(0,1,2...16),n 表示具体是哪一个 IO 口

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


这样就可以使用PBout(0),相比之下还是很方便的。

推荐阅读

史海拾趣

Gemmy Electronics Co Ltd公司的发展小趣事
高压电击式捕鼠器在工作时会产生高压电,操作时必须注意防止触电。非专业人员请勿私自拆卸或维修捕鼠器。
CT Micro公司的发展小趣事
  1. 创业初期与技术创新

CT Micro公司最初由几位电子工程领域的专家创立,他们看到了微型计算机断层扫描(Micro-CT)技术在电子行业中的巨大潜力。初期,公司面临着资金短缺和技术难题,但他们通过不断研发和创新,成功开发出了一款具有高性价比的Micro-CT设备,迅速获得了市场的认可。

  1. 市场拓展与合作伙伴关系

随着产品的成熟,CT Micro开始积极寻求市场拓展。他们与多家电子制造企业建立了合作关系,为这些企业提供Micro-CT设备的定制服务。通过与这些企业的合作,CT Micro不仅扩大了市场份额,还进一步提升了产品的技术水平和应用范围。

  1. 研发升级与产品迭代

面对日益激烈的市场竞争,CT Micro不断投入研发力量,对Micro-CT设备进行升级和迭代。他们成功推出了多款新型设备,具有更高的分辨率、更快的扫描速度和更低的辐射剂量。这些新产品的推出,进一步巩固了CT Micro在电子行业中的领先地位。

  1. 国际化战略与市场拓展

随着国内市场的饱和,CT Micro开始实施国际化战略。他们积极参与国际展览和研讨会,展示自己的产品和技术实力。同时,他们还在海外设立了销售和服务中心,为国际客户提供更加便捷的服务。通过这些努力,CT Micro成功打开了国际市场的大门。

  1. 社会责任与可持续发展

在快速发展的同时,CT Micro也积极履行社会责任。他们注重环保和可持续发展,采用环保材料和节能技术生产产品。此外,他们还积极参与公益事业,为贫困地区的教育和医疗事业贡献力量。这些举措不仅提升了公司的社会形象,也为其可持续发展奠定了坚实基础。

请注意,这些故事框架是虚构的,并不代表CT Micro公司的实际发展情况。如果您需要了解CT Micro公司或类似公司的真实故事,建议您查阅相关公司的官方网站、新闻报道或行业分析报告。

對餘科技(DIOFIT)公司的发展小趣事

在市场竞争日益激烈的情况下,DIOFIT公司凭借敏锐的市场洞察力和灵活的营销策略,不断拓展市场份额。他们针对不同地区、不同行业的需求,制定个性化的产品推广方案,通过线上线下相结合的方式,加强品牌推广和渠道建设。同时,DIOFIT公司还积极参与各类展会和论坛,与业界同仁交流合作,拓展国际视野,为公司的发展注入新的活力。

晨晶电子(Chenjing Electronics)公司的发展小趣事

晨晶电子的前身是始建于1958年的国营第七O七厂。作为一家具有深厚历史底蕴的企业,它在中国电子行业的发展历程中扮演了重要角色。然而,随着时代的变迁和市场环境的转变,国营第七O七厂逐渐面临着体制僵化、市场竞争力下降等问题。为了适应现代企业制度的要求,该厂在2000年进行了转制,成立了北京晨晶电子有限公司。这一转制不仅为企业注入了新的活力,也为其后续的发展奠定了坚实基础。

AD Semiconductor公司的发展小趣事

晨晶电子的前身是始建于1958年的国营第七O七厂。作为一家具有深厚历史底蕴的企业,它在中国电子行业的发展历程中扮演了重要角色。然而,随着时代的变迁和市场环境的转变,国营第七O七厂逐渐面临着体制僵化、市场竞争力下降等问题。为了适应现代企业制度的要求,该厂在2000年进行了转制,成立了北京晨晶电子有限公司。这一转制不仅为企业注入了新的活力,也为其后续的发展奠定了坚实基础。

Diode Laser Concepts公司的发展小趣事

Diode Laser Concepts公司始终关注社会责任,积极参与各类公益活动。公司定期向贫困地区捐赠教育设备和资金,支持当地的教育事业发展;同时,公司还组织员工参与环保志愿活动,宣传环保理念,为保护地球环境贡献一份力量。这些公益活动不仅体现了公司的社会责任感,也增强了员工之间的凝聚力和向心力。

问答坊 | AI 解惑

直接接在普通开关两端的延时开关电路

本帖最后由 jameswangsynnex 于 2015-3-3 19:59 编辑 如题。直接接在普通开关两端的延时开关电路,不用改变目前的布线方式直接接与开关两端, 可用原开关两端引出两个线作为一个控制信号,也可以加上声控,光控功能, 下图这个电路当可控硅导通 ...…

查看全部问答>

汇编语言入门教程

汇编语言入门教程…

查看全部问答>

弱问 wince怎么用directdraw,想把yuv的格式显示出来

如题,就是有些不懂帮忙科普下,上网貌似搜不到什么…

查看全部问答>

串口驱动的问题(iso7816)

最近我在做9260的iso7816驱动,方便起见,我在atmel_serial.c基础上修改。现在发现驱动发送没有问题,但是接收read时,总是无法读到数据。驱动层中发现硬件上数据是接收到了的,atmel_rx_from_dma服务中dma缓冲区中的数据是对的。tty_insert_flip_s ...…

查看全部问答>

{转载}51单片机 Keil C 延时程序的简单研究

51单片机 Keil C 延时程序的简单研究 by: InfiniteSpace Studio/isjfk, 1.21.2004 任何人都可以在注明原作者和出处的前提下随意转载这篇文章,但不得用于商业目的。   应用单片机的时候,经常会遇到需要短时间延时的情况。需要的延时时间很短 ...…

查看全部问答>

有没人在弄IMX51+WINCE60? 我的系统怎么跑不起来啊,也不知道是软件问题还是硬件问题

有没人在弄IMX51+WINCE60? 我的系统怎么跑不起来啊,也不知道是软件问题还是硬件问题…

查看全部问答>

传说I+2+C=I2C

I2C的工程应用 本工程基于LM3S8962的I2C总线来模拟EEPROM(CAT24C02)传输协议的操作过程,系统简单实用,可以移植到所有的LM3Sxxx系列的MCU上。 在PROGRAM中,采用INT的方式进行数据传输过程的处理和实现,工程的功能实现都是在中断函数中进行的。 ...…

查看全部问答>

如何复制ROM到RAM执行

KEIL中,如何把一个数据段,或者一个函数,在启动后复制到RAM中运行呢? 发散加载后,如何段的地址。 如果函数复制到RAM后,又如何执行它? 谢谢…

查看全部问答>

MSP430单片机的双机串口通讯

求有关MSP430单片机的双机串口通讯的资料,最好能有程序,急~谢谢啦…

查看全部问答>

编译ARM的linux内核的问题

在编译内核时报错了,请问高手这是什么错误啊?…

查看全部问答>