位域指针在cortex-m3/4架构单片机中的应用

位域指针在cortex-m3/4架构中的应用

众所周知,stm32采取的arm cortex 部分系列支持位寻址操作.
下图源于cortex -m4 内核手册.

位操作的介绍

请添加图片描述
Bit band region 为支持位寻址的区域, Bit band alias为Bit band region的位编址区 ( 为Bit band region中的每一位都编址 ) .

尽管存储器中支持位寻址的区域有限,但这仍然囊括stm32中大部分常用外设寄存器.

以stm32f4系列为例.
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

由表可知,以0x4xxx xxxx 开头的外设寄存器地址都是在内核支持的位操作区域内的, 我们可以修改这些外设寄存器中的单独一位,而不用进行 读出寄存器值–>位运算改–>写回寄存器 系列操作.

此图截自cortex -m4 内核手册

位寻址操作映射关系如下.
请添加图片描述

下面是官方给出的例子.
请添加图片描述

以下是我个人的用法.

/*注意该宏仅支持外设部分的位设置*/
#define __BIT_SET(WORD_ADDR, BIT_ADDR, BIT) *(uint32_t *)(0x42000000 + (((WORD_ADDR) & 0x0fffffff) << 5) + ((BIT_ADDR) << 2)) = (BIT)

官方给出的映射算式可以替换为由移位和逻辑运算组成的版本,提高运算速度.

//eg:
__BIT_SET(GPIOA_ODR, 7, 1); 
//可以以极快的速度修改GPIOA Pin7 的输出电平.

接近于软件翻转电平的理论上限(50MHz,100MHz…)
同时相较于下程序所示用法

GPIOA->ODR|=1<<7; 

避免了数据读->改->写的繁琐步骤.
消除了程序在多线程运行时,同时修改ODR寄存器导致数据紊乱的情况.
呃…虽然说直接修改BSRR寄存器也可达到同样效果,但是说,可能不太直观?

GPIOA->BSRR = 1<<7;//位设置 
GPIOA->BSRR = 1<<(7+16); //位清除

位域指针的应用

得益于cortex 内核可以精细寻址到部分位.
那么是否在STM32中也可以使用位域语法呢?
还是以操作IO口为例.

// GPIOA base: 0x40020000
//ODR偏移: 0x14
/*初始化结构体*/
typedef struct
{
  uint32_t p0 : 1;
  uint32_t p1 : 1;
  uint32_t p2 : 1;
  uint32_t p3 : 1;
  uint32_t p4 : 1;
  uint32_t p5 : 1;
  uint32_t p6 : 1;
  uint32_t p7 : 1;
  uint32_t p8 : 1;
  uint32_t p9 : 1;
  uint32_t p10 : 1;
  uint32_t p11 : 1;
  uint32_t p12 : 1;
  uint32_t p13 : 1;
  uint32_t p14 : 1;
  uint32_t p15 : 1;
  uint32_t reverse : 16;
} GPIOA_odr_t; 
GPIOA_odr_t *gpioa = (GPIOA_odr_t *)(0x40020014);

/*应用*/
gpioa->p7 = 0;//翻转电平
gpioa->p7 = 1;

是否有种51的既视感呢?
集直观与速度与一身的用法,对软件刷屏大有脾益.

好了,今天就分享到这了,新人发帖,感谢观看!
限于编者水平,有误还望海涵,欢迎批评指正.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值