野火例子
因为 SysTick 属于内核外设,跟普通外设的中断优先级有些区别,并没有抢占优先级和子优先级的说法。滴答定时器优先级也是可以设置的同样受NVIC控制。
SysTick_Config()库函数主要配置了 SysTick 中的三个寄存器: LOAD、 VAL 和 CTRL。其中还调用了固件库函数 NVIC_SetPriority()来配置系统定时器的中断优先级,该库函数也在 core_m4.h 中定义
试试到底需要配置不
试试到底需要配置不//记得需要设置中断优先级
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 配置 NVIC 为优先级组 1 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* 配置中断源:按键 1 */
NVIC_InitStructure.NVIC_IRQChannel = SysTick_IRQn;
/* 配置抢占优先级: 1 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 配置子优先级: 1 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中断通道 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// 设置系统定时器中断优先级
//NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
SysTick 初始化函数
/**
* @brief 启动系统滴答定时器 SysTick
* @param 无
* @retval 无
*/
void SysTick_Init(void)
{
/* SystemFrequency / 1000 1ms 中断一次
* SystemFrequency / 100000 10us 中断一次
* SystemFrequency / 1000000 1us 中断一次
*/
if (SysTick_Config(SystemCoreClock / 100000)) {
/* Capture error */
while (1);
}
}
/**
* @brief 获取节拍程序
* @param 无
* @retval 无
* @attention 在 SysTick 中断函数 SysTick_Handler()调用
*/
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00) {
TimingDelay--;
}
}
TimingDelay 的值等于延时函数中传进去的 nTime 的值,比如 nTime=100000,则延时的时间等于 100000*10us=1s
/**
* @brief us 延时程序,10us 为一个单位
* @param
* @arg nTime: Delay_us( 1 ) 则实现的延时为 1 * 10us = 10us
* @retval 无
*/
void Delay_us(__IO u32 nTime)
{
TimingDelay = nTime;
while (TimingDelay != 0);
}
函数 Delay_us()中我们等待 TimingDelay 为 0,当 TimingDelay 为 0 的时候表示延时时间到。变量 TimingDelay 在中断函数中递减,即 SysTick 每进一次中断即 10us 的时间TimingDelay 递减一次
SysTick 中断时间的计算
SysTick 定时器的计数器是向下递减计数的,计数一次的时间 TDEC=1/CLKAHB,当重装载寄存器中的值 VALUELOAD 减到 0 的时候, 产生中断,可知中断一次的时间TINT=VALUELOAD * TDEC 中断= VALUELOAD/CLKAHB,其中 CLKAHB =180MHZ。如果设置为180,那中断一次的时间 TINT=180/180M=1us。不过 1us 的中断没啥意义,整个程序的重心都花在进出中断上了,根本没有时间处理其他的任务
SysTick_Config()配置为 SystemCoreClock / 100000=180M/100000=1800,从分析知道这个形参的值最终是写到重装载寄存器 LOAD 中的,从而可知现在把 SysTick 定时器中断一次的时间 TINT=1800/180M=10us
SysTick 中断服务函数
void SysTick_Handler(void)
{
TimingDelay_Decrement();
}