我对STM32所用位带操作宏的超详细剖析、优势分析及应用推广探索研究(持续更新,欢迎讨论交流)

2019-07-20 23:21发布

本帖最后由 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=


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
49条回答
warship
2019-07-24 19:59
本帖最后由 warship 于 2018-7-9 11:07 编辑

用到的寄存器位:
RCC寄存器基址  4002 1000
RCC->CR   +0
RCC_CR_HSEON    位16
RCC_CR_HSERDY   位17
RCC_CR_PLLON     位24
RCC_CR_PLLRDY   位25

RCC->CFGR +4
RCC_CFGR_SW0      位0
RCC_CFGR_SW_PLL  位1
RCC_CFGR_SWS_PLL  位3
现在定义一下位别名地址:
// #define RCC_BASE   0x40021000    //这个官方已有定义
#define bRCC_CR_HSEON   BIT_ADDR(RCC_BASE, 16)  
#define bRCC_CR_HSERDY   BIT_ADDR(RCC_BASE, 17)
#define bRCC_CR_PLLON   BIT_ADDR(RCC_BASE, 24)
#define bRCC_CR_PLLRDY    BIT_ADDR(RCC_BASE, 25)

#define bRCC_CFGR_SW0       BIT_ADDR(RCC_BASE+4, 0)
#define bRCC_CFGR_SW_PLL   BIT_ADDR(RCC_BASE+4, 1)
#define bRCC_CFGR_SWS_PLL   BIT_ADDR(RCC_BASE+4, 3)

为了与官方定义区别,位地址宏均加上前缀b
话说这种基础性的工作,一个上午就可以全部搞定,做成一个位别名地址宏的头文件。

一周热门 更多>