【嵌入式C语言】位带操作

15 篇文章 0 订阅

位带操作实现了通过普通的加载/存储等指令对单一的1bit进行读写的功能。也就是说把1bit膨胀为32bit的字来操作(位带操作就是用一个地址代表一个比特,正常来说一个地址代表的是32bit,一次性操作的也是32bit)。

比如:

#define LED0 PBout(1) //其中 PBout(1)是位带操作

我们直接

LED0 = 1;

通过这个位带操作直接将IO口PB1置为了高电平,也就是通过位带操作直接改变了某一bit的值。

而普通的操作比如

int a = 1;

是将a所代表的内存最低位置为1,其余31bit置为0,这是直接操作了32bit内存。

CM3在两个区实现了位带

1. SRAM区的低1M字节:

位带区 0x2000 0000 ~ 0x200F FFFC

对应别名区 0x2200 0000 ~ 0x23FF FFFC

2. 片上外设低1M字节:

位带区 0x4000 0000 ~ 0x400F FFFC

对应别名区 0x4200 0000 ~ 0x43FF FFFC

下面通过0x40000000的8个bit举例说明位带区和别名区的关系

位带区

别名区

0x4000 0000 bit1

0x4000 0000

0x4000 0000 bit2

0x4000 0000

···

···

0x4000 0000 bit8

0x4000 0000

通过表格可以看到,位带区的一个bit对应别名区的1个字即32bit,位带区每移动一个bit,别名区移动一个字。因为位带操作是用32bit来操作1bit,而每一个地址代表了8bit,所以别名区地址每次移动(32 / 8)。这就是通过别名区把位带区的1个bit膨胀为32bit。

别名区地址的求解公式如下

别名区地址 = 别名区基址 + ((位带区地址 - 位带区基址)* 8 + bit位) * 4

通过一段代码实例来深入理解

#define BITBAND(addr, bitnum) ((addr & 0xF0000000) + 0x20000000 + 
                          ((addr & 0xFFFFF) << 5) + (bitnum << 2))
//addr & 0xFFFFF相当于 addr - 位带基址
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
#define GPIOA_ODR_Addr 0x40020014   //GPIOA的输出寄存器地址
#define PAout(n) BIT_ADDR(GPIO_ODR_Addr, n)

//代码参考正点原子《STM32F429开发指南-HAL库版本_V1.1》

下面就可以通过

PAout(1) = 1;

直接将GPIOA的bit1置1,即引脚PA1置1.

参考《Cortex M3与M4权威指南》《STM32F429开发指南-HAL库版本》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嵌入C语言是C标准委员会指定的C编程语言的一组语言扩展,通常用于解决不同嵌入系统的C扩展之间存在的共性问题。它需要对C语言进行非标准扩展,以支持增强的微处理器功能,如定点算术、多个不同的内存库和基本I/O操作。与C++相比,C语言更加简洁和轻量级,适用于嵌入系统开发。\[1\] 堆是用于程序动态申请分配和释放空间的一种内存区域。在C语言中,可以使用malloc和free函数,在C++中可以使用new和delete操作符来在堆中进行内存分配和释放。堆中的空间需要程序员手动释放,否则在程序结束后由系统自动回收。需要注意的是,这里的堆并不是数据结构中的堆。\[2\] 嵌入系统开发需要对硬件和软件进行深入理解,并结合特定的项目需求进行设计和实现。通过不断学习和实践,可以提高嵌入开发技能,开发出高效、稳定的嵌入系统。\[3\] #### 引用[.reference_title] - *1* *2* [嵌入C基础知识(1)](https://blog.csdn.net/xiaoyi9812/article/details/128920427)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [嵌入系统开发:使用C语言进行嵌入编程](https://blog.csdn.net/m0_75198698/article/details/130715374)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值