先上代码,这是 core_cm3.h 中关于 SysTick 寄存器的一些定义。
/* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1ul << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1ul << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1ul << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
其中的寄存器位指示宏: SysTick_xxx_Pos ,宏展开后即为 xxx 在相应寄存器中的位置,如控制 SysTick 时钟源的 SysTick_CTRL_CLKSOURCE_Pos ,宏展开为 2,这个寄存器位正是在寄存器 STK_CTRL 中的 Bit2。
而寄存器位屏蔽宏:
SysTick_xxx_Msk
,宏展开是 xxx 的位全部置 1 后,左移 SysTick_xxx_Pos 位。如控制 SysTick 时钟源的
SysTick_CTRL_CLKSOURCE_Msk
,宏展开为
(1ul << SysTick_CTRL_CLKSOURCE_Pos)
,把无符号长整型数值(ul) 1 左移 2 位,得到了一个只有 Bit2:CLKSOURCE 位被置 1,其它位为 0 的数值,这样的数值配
合位操作 &(按位与)、| (按位或)可以很方便地修改寄存器的某些位。假如控制 CLKSOURCE 需要四个寄存器位,这个宏就应该被改为
(0xf ul << SysTick_CTRL_CLKSOURCE_Pos)
,这样就会得到一个关于 CLKSOURCE 的四位被置 1 的值,这些宏的参数就是这样被确定的。