寄存器
STK_CTRL
- SysTick 控制和状态寄存器( SysTick control and status register )
- COUNTFLAG: 如果在上次读取本寄存器后, SysTick 已经计到了 0,则该位为 1
- CLKSOURCE: 时钟源选择
- 0:AHB/8
- 1:处理器时钟 AHB
- TICKINT: SysTick异常请求使能
- 0:数到 0 时无动作。
- 1:数到 0 时触发 SysTick 异常请求
- ENABLE: SysTick 定时器的使能位
- 0:禁止
- 1:使能
STK_LOAD
- 重装载数值寄存器(SysTick reload value register)
- RELOAD[23:0]: 当倒数计数至零时,将被重装载的值
STK_VAL
- 当前数值寄存器(SysTick current value register)
CURRENT[23:0]: 读取时返回当前倒计数的值,写任意值则使之清零(包括COUNTFLAG)
STK_CALIB
- 校准数值寄存器(SysTick calibration value register),用法不明,略过。
上述寄存器在内核头文件中的定义
typedef struct
{
__IO uint32_t CTRL;
__IO uint32_t LOAD;
__IO uint32_t VAL;
__I uint32_t CALIB;
} SysTick_Type;
例程
寄存器
int main(void){
while(1){
LED_ON();
Delay_ms(1000);
LED_OFF();
Delay_ms(1000);
}
return 0;
}
void Delay_ms(__IO uint32_t ms){
SysTick->LOAD = 72000; // 计数器重装载值,1ms 中断一次(系统时钟72MHZ)
SCB->SHP[11] |= (uint8_t)0xF0; // 配置 SysTick 中断优先级,具体看下一小节说明
SysTick->VAL = (uint32_t)0x00; // 计数器初始值
SysTick->CTRL |= (uint32_t)0x07; // 选择AHB时钟源,使能 SysTick 中断,使能 SysTick
while(ms-- > 0){
// 当计数器的值减小到 0 的时候,CRTL 寄存器的位 16 会置 1
while(!((SysTick->CTRL) & ((uint32_t)0x01 << 16)));
}
SysTick->CTRL &= ~(uint32_t)0x01; //关闭 SysTick
}
void SysTick_Handler(void){
// SysTick中断函数,本例中用不到
}
SCB->SHP[11] 配置 SysTick 中断优先级
- 系统中断优先级寄存器 (System handler priority register)
SysTicks
属于内核(中断号 -1),不要和外部中断搞混,下面是官方手册的描述:
SysTick
中断优先级设置对应 SCB_SHPR3
寄存器的 PRI_15[7:0]
,高四位有效。
再看头文件 core_cm3.h
中的定义:
typedef struct
{
/* 篇幅有限略去 */
__IO uint8_t SHP[12];
/* 篇幅有限略去 */
} SCB_Type;
刚好每个 SHPR 寄存器占 4 个
可知,SHP[11]
对应 PRI_15[7:0]