本帖最后由 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=
没有人回帖讨论,有点孤独,但我还是将专题研究进行到底。
回到在SRAM区实现位操作的话题。
个人认为,12楼所介绍的方法是最理想的方法,
手工分配一个固定地址存放标志位综合寄存器就好了。
有些人可能要问,如果不用手工分配固定地址的方法行不行?
我今天也进行了一些探索,是完全可行的。
那就是在程序中查询地址。
闲话少说,直接上代码:
u32 MyFlag; //定义一个我们用于存放各类标志位的全局变量
volatile u32* pMyFlag; //再定义一个指向此变量对应的别名区地址的指针
// 在系统初始化代码中,查询并计算出这个别名指针的具体值
u32 *pwMyFlag; //临时定义一个指向MyFlag变量本身的指针
pwMyFlag=&MyFlag; //查询该变量的地址赋值给pwMyFlag
pMyFlag=(void *)(0x22000000+(((u32)pwMyFlag & 0xFFFFF)<<5)); //计算出对应的别名区地址
//这样,所有的准备工作就完成了,以后可在程序的任何地方使用位操作
//访问时用例-置位某标志: *(pMyFlag+n)=1; 或者数组形式: pMyFlag[n]=1;
//条件语句用例: if(pMyFlag[3]) pMyFlag[3]=0;
一周热门 更多>