首页 > 其他分享 >【单片机/嵌入式】【梁山派】学习日志07:位带操作

【单片机/嵌入式】【梁山派】学习日志07:位带操作

时间:2022-11-05 17:57:00浏览次数:55  
标签:位带 07 单片机 地址 GPIOD 操作 对应 字节

位带操作

一、位带操作介绍

为了减少“读-改-写”操作的次数,Cortex-M4处理器提供了一个可以执行单原子比特操作的位带功能。存储器映射包含了两个支持位带操作的区域。其中一个是SRAM区的最低1MB范围,第二个是片内外设区的最低1MB范围。这两个区域中的地址除了普通应用外,还有自己的“位带别名区”。位带别名区把每个比特扩展成一个32位的字。当用户访问位带别名区时,就可以达到访问原始比特的目的。总结就是CPU不能直接对位带区中的单个数据位位寻址,只能通过对位带别名区的访问(或读/写)实现对位带区单个数据位的访问(或读/写),这种操作被称为位带操作。使用位带操作的目的是能够像51单片机那样直接给IO口拉高拉低,例如P60 = 1这种操作。

二、位带操作内存地址

前面我们说了存储器映射支持两个位带操作的区域。关于支持位带操作的两个内存区的范围是: 0x2000_0000‐0x200F_FFFF(SRAM 区的最低1MB) 0x4000_0000‐0x400F_FFFF(片上外设区的最低 1MB)

对应的位段别名区的起始地址分别为0x2200 0000和0x4200 0000,这个在编程的时候需要使用。

三、位带操作优势

更高效

读取更简单

访问速度快

相对安全。在带有操作系统的开发中,多任务并发运行的时候就有可能在任务切换的过程中发生不可预料的问题,而位带操作由于是属于硬件完成的不可被异常打断的操作(原子操作),相对于读-写-改的操作模式会更安全。

提高运行效率和节省代码空间。简单的程序直接使用库函数或者寄存器操作,对于比较复杂的程序建议尽量使用位带操作来实现。

四、配置位带操作

上面介绍了位带操作的地址和优势,那怎么去查找目标比特对应的位带别名区的地址呢?关于位带操作的介绍在用户手册的第41页。

可以看到,通过bit_word_addr = bit_band_base +(byte_offset×32)+(bit_number×4)这个公式可以计算出对应的位带别名区的地址。

这里给大家介绍一下这个公式如何去使用,以PD7为例。

先分析一下这个公式,要计算位带操作别名区地址,首先要知道位带别名区的起始地址、位带区目标比特所在的字节的字节地址偏移量和目标比特在对应字节中的位置。位带别名区的地址在1.2节可以了解到是0x42000000。

我们需要配置PD7引脚的输出功能,那么对应的寄存器为端口输出控制寄存器(GPIOx_OCTL),我们要操作的是这一个字节地址的第7位,那对应的字节地址偏移量就是GPIOx_OCTL的偏移量0x14 + GPIOD的基地址然后还要减去地址0x40000000(片上外设的起始地址为0x4000_0000),对应目标比特在对应字节中的位置就是7。如果是配置为输入功能的话,要操作的寄存器为端口输入状态寄存器(GPIOx_ISTAT),对应的偏移量为0x10 + GPIOD 的地址然后还要减去起始地址0x40000000,对应目标比特在对应字节中的位置也是7。

bit_word_addr =bit_band_base +(byte_offset×32)+(bit_number×4)转化为代码就是

#define BIT_ADDR(byte_offset,bitnum) 

 (volatile unsigned long*)(0x42000000 + (byte_offset * 32) + (bitnum * 4))

PD7输出对应的字节偏移量为
#define GPIOD_OCTL_OFFSET ((GPIOD + 0x14) - 0x40000000) PD7输入对应的字节偏移量为
#define GPIOD_ISTAT_OFFSET ((GPIOD + 0x10) - 0x40000000) PD7输出最终可配置为
#define PDout(n)  *(BIT_ADDR(GPIOD_OCTL_OFFSET,n))  // 输出 PD7输入最终可配置为
#define PDin(n)  *(BIT_ADDR(GPIOD_ISTAT_OFFSET,n))  // 输入 这里的n就是对应的第几位(n取值范围为0-15)。

 

标签:位带,07,单片机,地址,GPIOD,操作,对应,字节
From: https://www.cnblogs.com/steven913/p/16860713.html

相关文章