日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SysTick的优先级是高还是低

發布時間:2025/3/21 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SysTick的优先级是高还是低 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

摘要?????????????SysTick系統嘀嗒定時器是Cortex內核的部分,尤其對于有實時操作系統的軟件,它一般會作為整個系統的時基,所以這個對操作系統非常重要。????????????

SysTick??????? ????????、CM3、系統嘀嗒??????? ???????????

?

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中如下所示:

?

1

2

3

4

5

6

7

8

9

10

11

12

/

**@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中代碼如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

/**

?*?@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)函數來實現,具體應用可參考下面的示例代碼。

當介紹完了理論后,發現還是沒有搞清楚最初的疑惑!現在就做實現來揭示真相。

先設置一事件中斷,把優先級設置高一些,

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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);

}

?

注:中斷分組我在實驗中,最初初始化設置為如下:

?

1

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

設為第二組。

在系統滴答中斷里觸發外部中斷事件,并點亮LED1 :

?

1

2

3

4

5

6

void?SysTick_Handler(void)

{?

????EXTI_GenerateSWInterrupt(EXTI_SWIER_SWIER1);?

????LED_1?=?ON;

????Delay();

}

外部中斷處理函數中點亮LED0,如下:

?

1

2

3

4

5

6

7

8

9

void?EXTI1_IRQHandler(void)

{

????if?(EXTI_GetITStatus(EXTI_Line1)?!=?RESET)?

????{

????????EXTI_ClearITPendingBit(EXTI_Line1);?

????????LED_0?=?ON;

????????Delay();

????}

}

當外部中斷優先級比較高時,它可以搶占Systick中斷先執行,以上代碼實驗結果為,LED0先點亮后,再回到LED1再點亮。
?

但當把外部中斷設置為與systick相同的優先級時,則systick優先級就會相對較高,例如把上面的優先級改為:

?

1

2

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的优先级是高还是低的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。