首页 > 技术文章 > stm32F4XX 位带操作

mrAAron 2018-11-23 09:52 原文

 

环境:stm32f429 原子哥的开发板 Keil5

问题来源:在例子程序中操作LED灯的方式,为什么不是原来的使用HAL_GPIO_WrirePin()

寻找答案:

因为我是根据项目需求来看例子的没有仔细的阅读跑马灯实验,其实在里面还是提及了 位带操作

但是当时没有看见就直接去LED1的定义了

(1)

(2)

(3)

(4)

(5)

(6)

(7)

 

 下面是一直使用转到定义一路追定义的根源,到最后发现 PERIPH_BASE ,阅读文档知道他是M4的存储器映射过来的alias region,以此根据下图:

(8)

看见 Perpherals 的起始地址 0x4000 0000 - 0x5FFF FFFF 

(9)

通过文档查询AHB,知道GPIOB是在一个叫AHB 私有外设总线,但是他是在 0x4002 0400 -0x4002 07FF(图9中发现),已经计算好位带的地址了,

上面 图8 中知道这段地址属于 bit-banding Region,位带操作的地址,那么什么是位带

 在上面的图片中有程序中定义的GPIOB_BASE 明显不是这个地址,是经过上面图片中的BIT_ADDR 位带计算公式代出来的。

 (10)

(11)

(12)

(13)

(14)

实际是就是把1M范围的地址膨胀成32M的地址

根据(图11)说的公式,正好对应程序里面的BIT_ADDR ,偏移地址乘以32,也就是 << 5 左移操作,后面第几位就乘以4 也就是 << 2

第几位为什么要乘以4呢,Bit_number is the bit position, 0-7, of the targeted bit. 一共有8个位,一个字节膨胀32,一个位就是膨胀4倍

所以就有上述(图7)的公式

那么我们为什么要进行位带操作

(15)

防止操作系统不同task的访问,解决互斥操作,存储用的总线就解决了不同task在同一时间同一内存的操作,就算是普通的C语言写的代码不需要进行加锁操作就能执行。

因为是总线上的操作,同一时间同一内存的操作不同的task进行都会生效,不用担心丢失。(英语不好!!不知道错了没),说白就是原子操作。

 

推荐阅读