OS能夠支持多任務,能夠以周期性地完成上下文的切換,以并行的架構處理任務,單一任務的崩潰并不會牽連到整個系統。上下文周期性切換需要一個定時器能夠打斷程序執行,SysTick定時器就可以提供必要的時鐘節拍,為OS的任務調度提供一個有節奏的“心跳”。
SysTick定時器即系統滴答定時器,也稱“心跳定時器”,它是一個24 位的倒計數定時器,計到0 時,將從重裝載寄存器中自動重裝載定時初值。只要不把它在SysTick 控制及狀態寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。
SysTick定時器被捆綁在NVIC中,用于產生SysTick異常(異常號:15),SysTick中斷的優先級也可以設置。
它會根據節拍來工作,把整個時間段分成很多小小的時間片,而每個任務每次只能運行一個時間片的時間長度,超時就退出給別的任務運行,這樣可以確保任何一個任務都不會霸占操作系統提供的各種定時功能,都與這個滴答定時器有關。
當啟用時,定時器從重載值遞減計數到零,在下一個時鐘周期將重裝載SYST\_RVR 中的值,然后在后續時鐘周期遞減。將零值寫入 SYST\_RVR 會在下一次回調時禁用計數器。當計數器變為零時,COUNTFLAG 狀態位設置為 1。讀取 SYST\_CSR 將 COUNTFLAG 位清除為 0。寫入 SYST\_CVR 將清除寄存器和 COUNTFLAG 狀態位為 0,寫入不會觸發 SysTick 異常邏輯,讀取該寄存器會在訪問時返回其值。
1. SysTick寄存器
SysTick定時器主要由4個寄存器組成:
在CMSIS中系統控制寄存器結構體:
typedefstruct {__IOuint32_tCTRL;/*!
在Arm官方資料中4個寄存器的命名分別是SYST\_CSR、SYST\_RVR、SYST\_CVR和SYST\_CALIB,但是在CMSIS中進行了簡化命名,更加清晰明了。
1.1 SysTick控制和狀態寄存器(SYST\_CSR)
CSR寄存器用到的位有4個,bit0用于是否開啟定時器,置1表示使能SysTick定時器;bit1用于控制是否產生中斷,該位置為1為允許產生中斷;bit2用于設置定時器的時鐘源,設為1,定時器的時鐘源為主時鐘,反之設為0的話定時器的時鐘源為主時鐘的四分之一。
MM32F0130系列的SysTick的HCLK來源于AHB總線經過硬件4分頻,FCLK直接來源于AHB時鐘總線。
當 SysTick 定時器從1計到0時,它將把COUNTFLAG位置位;
而下述方法可以清零:
-
讀取 SysTick 控制及狀態寄存器(STCSR)
-
往 SysTick 當前值寄存器(STCVR)中寫任何數據
1.2 SysTick重裝載寄存器(SYST\_RVR)
?RVR寄存器用到0~23位,這個值是定時器倒計時的初始值,打開定時器以后,就會從這里設置的值倒計時到0,倒計時到0以后,又會從此值開始倒計時。1.3 SysTick當前值寄存器(SYST\_CVR)
?CVR寄存器也是用到0~23位,這是一個狀態寄存器,當定時器開始運作的時候,這個值在不斷的變化,從RVR寄存器獲取初值以后,倒計時到0。CURRENT:讀此寄存器返回系統定時器的當前值,給這個寄存器賦值,將使定時器歸0,且清CTRL中的COUNTFLAG位。1.4 SysTick當前值寄存器(SYST\_CALIB)
?如果不知道校準信息,則根據處理器時鐘或外部時鐘的頻率計算所需的校準值。校準值寄存器提供了這樣一個解決方案:它使系統即使在不同的CM0產品上運行,也能產生恒定的SysTick中斷頻率。最簡單的作法就是:直接把TENMS的值寫入重裝載寄存器,這樣一來,只要沒突破系統極限,就能做到每10ms來一次 SysTick異常。如果需要其它的SysTick異常周期,則可以根據TENMS的值加以比例計算。在系統定時器的四個寄存器中,SYST\_CALIB為校準寄存器,這個是在出廠之前就已經配置好了的,我們不必考慮這個寄存器。2. SysTick編程
SysTick配置需要遵循一定的流程:-
開始
-
禁止SysTick
-
設置重裝值寄存器
-
清除當前值寄存器
-
使能SysTick
-
完成
SysTick操作相關函數有:
__STATIC_INLINEuint32_tSysTick_Config(uint32_tticks); voidSysTick_CLKSourceConfig(u32systick_clk_source); voidRCC_SystickDisable(void); voidRCC_SystickEnable(u32sys_tick_period);
下面的代碼演示啟用 SysTick 的基本程序:;使能SysTick定時器,并且使能SysTick異常 LDRR0,=0xE000E010;加載STCSR的地址 MOVR1,#0 STRR1,[R0];先停止SysTick,以防意外產生異常請求 LDR R1, =0x3FF ;讓SysTick每1024周期計完一次。因為是從1023數到 ;0,總共數了1024個周期,所以加載值為0x3FF STRR1,[R0,#4];寫入重裝載的值 STRR1,[R0,#8];往STCVR中寫任意的數,以確保清除COUNTFLAG標志 MOVR1,#0x7;選擇FCLK作為時鐘源,并使能SysTick及其異常請求 STRR1,[R0];寫入數值,開啟定時器
在CMSIS庫中有定義對應的配置函數:__STATIC_INLINEuint32_tSysTick_Config(uint32_tticks) { /*Reloadvalueimpossible*/ if((ticks-1UL)>SysTick_LOAD_RELOAD_Msk){ return(1UL); } /*setreloadregister*/ SysTick->LOAD=(uint32_t)(ticks-1UL); /*setPriorityforSystickInterrupt*/ NVIC_SetPriority(SysTick_IRQn,(1UL<VAL=0UL; /*EnableSysTickIRQandSysTickTimer*/ SysTick->CTRL=SysTick_CTRL_CLKSOURCE_Msk| SysTick_CTRL_TICKINT_Msk| SysTick_CTRL_ENABLE_Msk; /*Functionsuccessful*/ return(0UL); }
SysTick可以通過輪詢或者中斷方式進行操作,使用輪詢的程序可以讀取SysTick控制和狀態寄存器,檢查COUNTFLAG,如果該位置位,則表明SysTick計數已減到0。中斷方式延時參考程序:static__IOuint32_tTimingDelay; voidDelay(__IOuint32_tnTime) { TimingDelay=nTime; while(TimingDelay!=0); } voidSysTick_Handler(void) { if(TimingDelay!=0x00) { TimingDelay--; } } intmain(void) { //systick時鐘為HCLK,中斷時間間隔1ms if(SysTick_Config(SystemCoreClock/1000)) { while(1); } while(1) { Delay(200);//200ms } }
輪詢方式延時參考程序:voiddelay_init() { SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div4);//選擇外部時鐘HCLK/4 //為系統時鐘的1/4,實際上也就是在計算1usSysTick的VAL減的數目 fac_us=SystemCoreClock/4000000; //代表每個ms需要的systick時鐘數,即每毫秒SysTick的VAL減的數目 fac_ms=(u16)fac_us*1000; } voiddelay_ms(u16nms) { u32temp; SysTick->LOAD=(u32)nms*fac_ms;//時間加載(SysTick->LOAD為24bit) SysTick->VAL=0x00;//清空計數器 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;//開始倒數 do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16)));???//等待時間到達,看CTRL的第16位(COUNTFLAG)是否為1,看STRL的第0位(ENABLE)是否為1??? ?????SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;//關閉計數器 SysTick->VAL=0X00;//清空計數器 } voiddelay_us(u32nus) { u32temp; SysTick->LOAD=nus*fac_us;//時間加載 SysTick->VAL=0x00;//清空計數器 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;//開始倒數 do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16)));????????//等待時間到達??? ????SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;//關閉計數器 SysTick->VAL=0X00;//清空計數器 }
SysTick定時器除了能服務于操作系統之外,還能用于其它目的:如時間測量、定時或者鬧鈴等。
原文標題:技術分享 | Cortex-M0中斷控制和系統控制(五)
文章出處:【微信公眾號:安芯教育科技】歡迎添加關注!文章轉載請注明出處。
-
寄存器
+關注
關注
31文章
5363瀏覽量
121162 -
定時器
+關注
關注
23文章
3255瀏覽量
115371 -
Systick
+關注
關注
0文章
62瀏覽量
13149
原文標題:技術分享 | Cortex-M0中斷控制和系統控制(五)
文章出處:【微信號:Ithingedu,微信公眾號:安芯教育科技】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論