本帖最后由 warship 于 2018-7-16 19:56 编辑
在原子例程的sys.h中,使用宏定义建立了位带操作的基础,
使得操作IO端口可以像51一样实现位操作。
其实深入了解了位带操作的原理,几乎就可以实现对STM32所有外设寄存器的访问,
极端情况下,什么库函数版本,什么寄存器版本都可以不用,直接精准地操控所有寄存器的每一位的读写!!!
知道了STM32将所有外设寄存器的每一位都建立了位带别名区,
你只要再花一点点时间,彻底搞明白下面的三句宏定义,位带操作就都不在话下了:
#define
BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define
MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define
BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
************************************************************************************************
注:本文后文所探索的寄存器位段操作宏定义包含在另文所附范例(外部中断试验的工程包)中,并随时更新。
有需要研究探讨的网友,可移步下载http://www.openedv.com/forum.php ... d=274724&extra=
如F103C8T6,SRAM的SRAM为20K,
即地址范围为:2000 0000至2000 5000
则定义地址时,不能超出2000 5000
STM32内部的位段操作机理的实质是:把对别名区的地址的读写--〉映射成对相应的位的读写
而不是反过来(注意理解二者的差别)。
这是STM32设计的一种内部机制,它无须CPU的寄存器(Rn)参与运算,直接在CACHE中完成原子操作,效率较高。
我们有些人经常反过来说:“比特位被映射到别名区”,其实是对这种内部机制规则的反向推算。
那个著名的别名地址计算公式实质是由比特位反推出对应的别名区地址,其目的就是为了
算得别名区地址后,运用STM32的内部机制,通过读写别名区实现对其相对应的比特位的读写。
具体效果是:
对2200 0000的读写,被映射成对2000 0000所存字节中BIT0的读写;
对2200 0004的读写,被映射成对2000 0000所存字节中BIT1的读写;
对2200 0008的读写,被映射成对2000 0000所存字节中BIT2的读写;
......
注意:别名区的地址是以字(32位,占用连续的4个字节)对齐的,
每个字只有LSB有意义。在访问别名区时,要把地址对齐到字的边界上,
否则会产生不可预料的结果。什么意思?就是说:只能对别名区中的LSB所在的地址进行读写。
如上述22000000、22000004、22000008、......等地址是有效的,这些地址都是4的整数倍。
必须避免对其它的地址如:22000001、20000002......20000007等地址的读写!!!
一周热门 更多>