SysTick的优先级是高还是低

发布者:骄阳少年最新更新时间:2018-07-20 来源: eefocus关键字:SysTick  优先级 手机看文章 扫描二维码
随时随地手机看文章

SysTick系统嘀嗒定时器并非STM32独有的,它是Cortex内核的部分,CM3为它专门开出一个异常类型,并且在中断向量表中占有一席之地(异常号15)。这样它可以很方便的移植到不同厂商出CM3内核的芯片上,尤其对于有实时操作系统的软件,它一般会作为整个系统的时基,所以这个对操作系统非常重要。

但在STM32开发手册中对它的介绍却很少,几乎到一笔带过的程度。有关SysTick的详细介绍可参考《Cortex-M3权威指南》第133 页第八章及第179页第十三章。

刚接触SysTick时,因它属于内核中断优先级,我一直有个疑问,它是比所有的可屏蔽中断优先级都高呢还是都低,或是处在等同设置地位 ?
最初我自以为内核中断优先级要比所有可屏蔽中断优先级高,当认真查阅资料与做实验后,发觉并非如此。

SysTick总共有四个寄存器:
1、

此寄存器在系统代码中由 SysTick->CTRL变量表示;

2、

此寄存器在系统代码中由 SysTick-> LOAD变量表示;

3、

此寄存器在系统代码中由 SysTick-> VAL变量表示;

4、

此寄存器在系统代码中由SysTick-> CALIB 变量表示,没有用过,也不常用,暂不作介绍。


这几个寄存器的偏移量如下图所示:

上面寄存器结构体的定义在 \CMSIS\CM3\CoreSupport  core_cm3.h中如下所示:


/

**@addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick

  memory mapped structure for SysTick

  @{

  */

typedef struct

{

    __IO uint32_t CTRL; /*!< Offset: 0x00 SysTick Control and Status Register */

    __IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register */

    __IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register */

    __I uint32_t CALIB; /*!< Offset: 0x0C SysTick Calibration Register */

} SysTick_Type;

SysTick 是一个24 位的定时器,即一次最多可以计数 224个时钟脉冲,这个脉冲计数值被保存到SysTick->VAL 当前计数值寄存器中,它只能向下计数,每接收到一个时钟脉冲SysTick->VAL 的值就向下减 1,直至0,然后由硬件自动把重载寄存器SysTick->LOAD 中的值到SysTick->VAL重新计数,并且当SysTick->VAL值计数到0时,触发异常,调用void SysTick_Handler(void)函数,可以在此中断服务函数中处理定时中断事件了,一般是对设定值进行递减计数操作。只要不把它在SysTick控制及状态寄存器SysTick->CTRL中的第0位使能位清除,就永不停息。


它属于系统异常,是内核级中断,并且优先级是可以设置的,具体设置也是在  core_cm3.h中代码如下:



/**

 * @brief Initialize and start the SysTick counter and its interrupt.

 *

 * @param ticks number of ticks between two interrupts

 * @return 1 = failed, 0 = successful

 *

 * Initialise the system tick timer and its interrupt and start the

 * system tick timer / counter in free running mode to generate 

 * periodical interrupts.

 */

static __INLINE uint32_t SysTick_Config(uint32_t ticks)

    if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */

    SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */

    NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); 

    SysTick->VAL = 0; 

    SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | 

        SysTick_CTRL_TICKINT_Msk | 

        SysTick_CTRL_ENABLE_Msk; 

    return (0); /* Function successful */

}

在此段代码中,优先级的设置是通过NVIC_SetPriority()函数实现,此函数对内核中断优先级和外部中断优先级设置都可以,比较强大,但需要手动算出来抢占和从优先级,不太方便,当跳进此函数,我们可以算出Systick默认优先是最低的(效果相当于SCB->SHP[11] = 0xF0,如果你推算下,SHP[11] 正好对应于Systick优先级的设置);对于可屏蔽中断,优先级的设置一般通过 NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)函数来实现,具体应用可参考下面的示例代码。


当介绍完了理论后,发现还是没有搞清楚最初的疑惑!现在就做实现来揭示真相。


先设置一事件中断,把优先级设置高一些,



void Exti_Config(void)

{

    EXTI_InitTypeDef EXTI_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

    EXTI_InitStructure.EXTI_Line = EXTI_Line1;

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;

    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; 

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

}



注:中断分组我在实验中,最初初始化设置为如下:



NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

设为第二组。


在系统滴答中断里触发外部中断事件,并点亮LED1 :



void SysTick_Handler(void)

    EXTI_GenerateSWInterrupt(EXTI_SWIER_SWIER1); 

    LED_1 = ON;

    Delay();

}

外部中断处理函数中点亮LED0,如下:



void EXTI1_IRQHandler(void)

{

    if (EXTI_GetITStatus(EXTI_Line1) != RESET) 

    {

        EXTI_ClearITPendingBit(EXTI_Line1); 

        LED_0 = ON;

        Delay();

    }

}

当外部中断优先级比较高时,它可以抢占Systick中断先执行,以上代码实验结果为,LED0先点亮后,再回到LED1再点亮。



但当把外部中断设置为与systick相同的优先级时,则systick优先级就会相对较高,例如把上面的优先级改为:



NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; 

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;

则会LED1先亮,执行完SysTick_Handle函数后才轮到EXTI1_IRQHandler执行。


由以上实验可得出,当优先级相同时,内核级中断要优先于外部可屏蔽中断执行,但设置外部可屏蔽中断优先级大于内核级中断时,它是可抢占内核中断的。


另外,个人认为,若要实现systick精确延时,最好把systick优先级设置高一些,如 NVIC_SetPriority (SysTick_IRQn, 0);

即把SCB->SHP[11] = 0x00;则可达到systick优先级高于任合外部中断的效果,此时延时会更少被其它中断干扰,会更加精准。


关键字:SysTick  优先级 引用地址:SysTick的优先级是高还是低

上一篇:systick使用出错总结
下一篇:Systick 延时函数详解

推荐阅读最新更新时间:2024-03-16 16:09

MSP430的中断优先级及中断嵌套
MSP430的中断优先级、打开关闭、中断嵌套 优先级顺序从高到低为: PORT2_VECTOR (1 * 2u) /* 0xFFE2 Port 2 */ PORT1_VECTOR (4 * 2u) /* 0xFFE8 Port 1 */ TIMERA1_VECTOR (5 * 2u) /* 0xFFEA Timer A CC1-2, TA */ TIMERA0_VECTOR (6 * 2u) /* 0xFFEC Timer A CC0 */ ADC_VECTOR (7 * 2u) /* 0xFFEE ADC */ USART0TX_VECTOR (8 * 2u) /* 0xFFF0 USART 0 Transmit */ USA
[单片机]
双输入优先级排序器提供低静态电流 备份电源切换解决方案
亚德诺半导体 (Analog Devices, Inc.,简称 ADI) 旗下凌力尔特公司 (Linear Technology Corporation) 推出适用于 2.5V 至 40V 系统的双输入电源优先级排序器 LTC4418。为了实现便携性、在欠压期间保持存储器运作、以及在电源缺失时确保平稳的停机,电子系统采用电池和电容器作为备份电源。LTC4418 一般使用墙上适配器或主电池等较高优先级主电源来给负载供电,并在主电源欠压或电源缺失的情况下切换至备份电源 (通常是一个电池或大数值电容器)。由于能在高达 40V 的输入电压下工作,因此 LTC4418 可适应多种电源,例如:墙上适配器、USB 端口、超级电容器、以及多节铅酸
[电源管理]
双输入<font color='red'>优先级</font>排序器提供低静态电流 备份电源切换解决方案
stm32f4使用Systick实现延时
使用Systick定时器实现延时 一、SysTick定时器特性 SysTick定时器是一个24位的递减计数器,即vlue自减等于0时触发中断,并重新加载load值,如此循环。 在stm32f4库文件中,默认将优先级设置为最低优先级,可进入函数SysTick_Config查看优先级设置。 SysTick是Cortex-M内核的一部分,因此只要是Cortex-M内核都有该定时器。 SysTick的时钟源可由HCLK产生,或则HCLK/8产生。 二、如何使用SysTick定时器 既然是定时器,那么至少应该设置2方面内容: 1. 定时时间 2. 定时时间到后做什么。 三、程序解析 1. SysTick定时器初始化
[单片机]
STM32的中断优先级和库函数的 开、关总中断
一,中断优先级: STM32(Cortex-M3)中的优先级概念 STM32(Cortex-M3)中有两个优先级的概念——抢占式优先级和响应优先级,有人把响应优先级称作'亚优先级'或'副优先级',每个中断源都需要被指定这两种优先级。 具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套低抢占式优先级的中断。 当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决
[单片机]
【stm32f103】SysTick实现延时(寄存器版)
一.SysTick寄存器介绍 SysTick要参照Programming manual手册,寄存器一共有4个,如图: 分别为STK_CTRL STK_LOAD STK_VAL STK_CALIB校验,此基本用不到,或者水平没到那个程度,暂时用不到 二.程序分析 Delay_us void Delay_us(unsigned int nTime) { SysTick- LOAD = 72*nTime; SysTick- CTRL =SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_CLKSOURCE_Msk; while(!(SysTick- CT
[单片机]
【stm32f103】<font color='red'>SysTick</font>实现延时(寄存器版)
STM32F4(用SysTick实现Delay函数)
1,开发环境 1,适用芯片:STM32F4全部芯片 2,固件库:STM32F4xx_DSP_StdPeriph_Lib_V1.8.0 3,IDE:MDK517 2,驱动源码 Delay.h文件 /**************************************************************** * Copyright (C) 2016, XinLi, all right reserved. * File name: Delay.h * Date: 2016.03.22 * Description: Delay Driver ****
[单片机]
第18章 SysTick—系统定时器—零死角玩转STM32-F429系列
本章参考资料《 ARM Cortex™-M4F 技术参考手册》-4.5 章节SysTick Timer(STK),和4.48章节SHPRx,其中STK这个章节有SysTick的简介和寄存器的详细描述。因为SysTick是属于CM4内核的外设,有关寄存器的定义和部分库函数都在core_cm4.h这个头文件中实现。所以学习SysTick的时候可以参考这两个资料,一个是文档,一个是源码。 18.1 SysTick简介 SysTick—系统定时器是属于CM4内核中的一个外设,内嵌在NVIC中。系统定时器是一个24bit的向下递减的计数器,计数器每计数一次的时间为1/SYSCLK,一般我们设置系统时钟SYSCLK等于180M。当重装载数
[单片机]
第18章 <font color='red'>SysTick</font>—系统定时器—零死角玩转STM32-F429系列
多通道优先级放大器的设计与应用
图1所示的模拟优先级放大器最初是作为多输出电源的一部分进行设计,其中稳压操作基于最高优先级通道的电压。该放大器的另一个应用是带电子节气门控制的引擎控制系统,其中引擎需要对多个输入命令中优先级最高的一个作出响应。 图1. 输入优先级放大器提供的输出对应的是四个输入中具有最大正值的一个。虽然该电路响应正输入,但通过反转二极管的方向和重新配置电源即可响应负输入。 在该电路中,具有最大正值输出的放大器通过放大器输出中的正向偏置二极管来控制负反馈路径。它通过R1、R2、R3或R4(具体取决于哪个通道具有最大正值)构成一个简单的单位增益路径进入放大器的反相输入。反相输入与输出之间的二极管在具有最大输入的放大器上反向偏置,最终电路作
[嵌入式]
多通道<font color='red'>优先级</font>放大器的设计与应用
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved