Cortex-M3的SysTick 定時器

目錄

概述

1 SysTick 定時器

1.1?SysTick 定時器功能介紹

1.2?SysTick 定時器功能實現

1.3?SysTick在系統中的作用

2 SysTick應用的實例

2.1?建立異常服務例程

2.2 使能異常

2.3?鬧鐘功能

2.4??重定位向量表

2.5?消滅二次觸發

3?SysTick在FreeRTOS中的應用

3.1 STM32Cube配置SysTick

3.2 STM32HAL中sysTick接口


概述

本文主要介紹Cortex-M3的SysTick 定時器的相關知識,還介紹了一個使用匯編語言編寫的Cortex-M3的SysTick的應用實例。還介紹基于Cortex-M3內核的經典MCU STM32F103中SysTick在實際項目應用的方法。

1 SysTick 定時器

1.1?SysTick 定時器功能介紹

SysTick 是一個 24 位的倒計數定時器,當計到 0 時,將從 RELOAD 寄存器中自動重裝載定時初值。只要SysTick 控制及狀態寄存器中的使能位被置位, 就永不停息。下圖是SysTick的相關寄存器:

CM3 允許為 SysTick 提供兩個時鐘源以供選擇:

1)是內核的“自由運行時鐘” FCLK。“自由” 表現在它不來自系統時鐘 HCLK, 因此在系統時鐘停止時 FCLK 也繼續運行。

2)一個外部的參考時鐘。但是使用外部時鐘時,因為它在內部是通過 FCLK 來采樣的,因此其周期必須至少是 FCLK 的兩倍(采樣定理)。

很多情況下芯片廠商都會忽略此外部參考時鐘,因此通常不可用。通過檢查校準寄存器的位[31](NOREF), 可以判定是否有可用的外部時鐘源,而芯片廠商則必須把該引線連接至正確的電平。

1.2?SysTick 定時器功能實現

當 SysTick 定時器從 1 計到 0 時,它將把 COUNTFLAG 位置位;

下述方法可以清零之:
1)讀取 SysTick 控制及狀態寄存器(STCSR)
2)往 SysTick 當前值寄存器(STCVR)中寫任何數據

1.3?SysTick在系統中的作用

1)SysTick 的最大使命,就是定期地產生異常請求,作為系統的時基。 OS 都需要這種“滴答” 來推動任務和時間的管理。

2)如欲使能 SysTick 異常, 則把 STCSR.TICKINT 置位。 另外, 如果向量表被重定位到 SRAM 中,還需要為 SysTick 異常建立向量,提供其服務例程的入口地址。

2 SysTick應用的實例

2.1?建立異常服務例程

建立SysTick異常服務例程

MOV R0, #0xF                ; 異常號: 15
LDR R1, =systick_handler    ; 加載服務例程的入口地址
LDR R2, =0xE000ED08         ; 加載向量表偏移量寄存器的地址
LDR R2, [R2]                ; 讀取向量表的首地址
STR R1, [R2, R0, LSL #2]    ; 寫入向量

2.2 使能異常

LDR R0, =0xE000E010       ; 加載STCSR的地址
MOV R1, #0
STR R1, [R0]              ; 先停止SysTick,以防意外產生異常請求
LDR R1, =0x3FF            ; 讓SysTick每1024周期計完一次。因為是從1023數到; 0,總共數了1024個周期,所以加載值為0x3FF
STR R1, [R0,#4]           ; 寫入重裝載的值
STR R1, [R0,#8]           ; 往STCVR中寫任意的數,以確保清除COUNTFLAG標志
MOV R1, #0x7              ; 選擇FCLK作為時鐘源,并使能SysTick及其異常請求
STR R1, [R0]              ; 寫入數值,開啟定時器

除此之外, SysTick 定時器還提供了走完 10ms 所需要的格數(TENMS 位段),作為時間校準的參考信息。在 CM3 處理器的頂層有一個 24 位的輸入,芯片廠商可以寫入一個 10ms 的加載值,寫程序時就可以讀取 STCR 寄存器中的 TENMS 位段來獲取此信息。不一定每個芯片都實現了此功能,因此在使用時還需查閱芯片的數據手冊。

2.3?鬧鐘功能

SysTick 定時器還可以用作鬧鐘,作為啟動一個特定任務的時間依據。例如,如果需要在 300 周期后執行一段代碼,就可以在 SysTick 異常服務例程中設置執行那段代碼的軟件標志。使用 SysTick 時,清零 CURRENT 再編程 RELOAD 寄存器,以使它在 300 周期后產生異常,如下述代碼所演示:

    LDR r0, =15LDR r1, =SysTickAlarm  ; SysTick異常服務例程為SetupExcpHanlerBL SetupExcpHandler    ; 調用前面章節講到的子程來建立向量LDR R0, =0xE000E010    ; SysTick寄存器組的基地址MOV R1, #0             ; 編程前先除能SysTickSTR R1, [R0]STR R1, [R0,#0x8]      ; 清零CURRENTLDR R1, =(300-12)      ; 設置裝載值。減去12是為了補償中延遲STR R1, [R0,#0x4]      ; 寫入RELOADLDR R4, =SysTickFired  ; 在RAM中的一個變量,指示是計時到期MOV R5, #0             ; 初始為0STR R5, [R4]MOV R1, #0x7           ; 使用FCLK,使能SysTick,使能SysTick異常STR R1, [R0]           ; 啟動計時LDR R4, =SysTickFired
WaitLoopLDR R5, [R4]           ; 循環查詢軟件標志CMP R5, #0BEQ WaitLoop...                    ; SysTickFired在服務例程中被置位,主程序可以繼續執行

2.4??重定位向量表

因為計數器是從 0 開始計數的,所以它會立即把 300‐12 加載入 CURRENT。 12 是中斷響應的最短延時,因此減去它用以補償。但是如果有更高優先級的異常搶占或者阻塞了它,則中斷延遲還是會有的。

SetupExcpHandler 來建立向量表,但注意:必須重定位向量表到RAM 中才行。

SetupExcpHandler; 入口條件: R0 = 異常號; 入口條件: R1 = 異常服務例程PUSH {R0, R2, LR}LDR R2, =NVIC_VECTTBLLDR R2, [R2]                ; 讀取向量表的地址STR.W R1, [R2, R0, LSL #2]  ; 表中[R2+R0<<2]的位置就是為該向量的POP {R0, R2, PC}            ; 快速返回

2.5?消滅二次觸發

2.4節?重定位向量表時,減去12 只適用于一次性(one shot)的鬧鐘操作,必須在 SysTick 服務例程中按停這個 SysTick。進一步地,如果其它異常把它延遲得太久,就有可能會使 SysTick異常被懸起兩次。因此,對于單次處理時,還需要其它一些步驟來消滅二次觸發:

SysTickAlarm                ; SYSTICK exception handlerPUSH {LR}LDR R0, =0xE000E010     ; SYSTICK寄存器組的基地址MOV R1, #0STR R1, [R0]            ; 除能SysTick,因為只使用一次LDR R0, =0xE000ED04LDR R1, =0x02000000     ; 手工清除NVIC中的SysTick懸起位STR R1, [R0]...                     ; 執行所需的處理工作LDR R2, = SysTickFiredLDR R1, [R2]ORR R1, #1STR R1, [R2]            ; 設置軟件標志,與主程序同步,以執行任務POP {PC}                ; 異常返回

在服務例程的末尾處,通過設置 SysTickFired 標志,通知主程序定時已經到期,可以結束循環等待了。
?

3?SysTick在FreeRTOS中的應用

3.1 STM32Cube配置SysTick

筆者以STM32103RTB芯片作為平臺配置SysTick和FreeRTOS

1) 配置FreeRTOS的系統時鐘為SysTick

2)使能FreeRTOS

3.2 STM32HAL中sysTick接口

在STM32HAL庫中定義在core_cm3.h中,這部分代碼在實際項目應用中,不建議修改,用戶可以重新stm32f1xx_hal.c中和sysTick相關的應用接口。在這個文件中,和sysTick相關的應用接口被定義為__weak類型,意味著其可以被重寫。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/15552.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/15552.shtml
英文地址,請注明出處:http://en.pswp.cn/web/15552.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【代碼】結構體

哈嘍大家好&#xff0c;我是學霸小羊&#xff0c;今天講講結構體。 先看例題&#xff1a; 例1.老師給了小楊一份同學們的考試成績&#xff0c;包括語數英三科&#xff0c;老師讓小明按照總分排序&#xff0c;請你幫幫他吧&#xff01; 輸入數據&#xff1a; 第1行 學生總人…

在docker中運行SLAM十四講程序

《十四講》的示例程序依賴比較多&#xff0c;而且系統有點舊。可以在容器中運行。 拉取鏡像 docker pull ddhogan/slambook:v0.1這個docker對應的github&#xff1a;HomeLH/slambook2-docker 拉下來之后&#xff0c;假如是Windows系統&#xff0c;需要使用XLaunch用于提供X11…

面試大雜燴之kafka

面試這個領域最近環境不行&#xff0c;所以卷起來流量挺大 關于K8s 其實看我之前的博客&#xff0c;k8s剛有點苗頭的時候我就研究過&#xff0c;然后工作的時候間接接觸 也自己玩過 但是用的不多就忘記了&#xff0c;正苦于不知道寫什么&#xff0c;水一篇 用來面試應該是夠了…

C++ | Leetcode C++題解之第111題二叉樹的最小深度

題目&#xff1a; 題解&#xff1a; class Solution { public:int minDepth(TreeNode *root) {if (root nullptr) {return 0;}queue<pair<TreeNode *, int> > que;que.emplace(root, 1);while (!que.empty()) {TreeNode *node que.front().first;int depth que…

VC編譯sample_onnx_mnist提示無法打開輸入文件cudnn.lib

出現錯誤 LNK1181 無法打開輸入文件“C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\lib\x64\cudnn.lib” 解決辦法&#xff1a;下載cudnn&#xff0c;NVIDIA cuDNN | NVIDIA Developer 拷貝相應的文件到CUDA安裝的目錄下。 VC編譯libtorch提示無法打開輸入文件cu…

huggingface 筆記:PretrainModel

1 from_pretrained 從預訓練模型配置中實例化一個 PyTorch 預訓練模型默認情況下&#xff0c;模型使用 model.eval() 設置為評估模式&#xff08;Dropout 模塊被禁用&#xff09; 要訓練模型&#xff0c;應該首先使用 model.train() 將其設置回訓練模式 1.1 主要參數 pretra…

java 子類繼承父類

為什么需要繼承 我現在要有兩個類一個 一個是小學生&#xff0c;一個是大學生 代碼 小學生 package b; public class encapsulatio{public String name;public int age;public double score;public void setscore (double score) {this.scorescore;}public void testing() {S…

(三)MySQL 索引

歡迎訪問 什么是索引&#xff1f; 提高查詢效率的一種數據結構&#xff0c;索引是數據的目錄 索引的分類 按「數據結構」分類&#xff1a;Btree索引、Hash索引、Full-text索引。按「物理存儲」分類&#xff1a;聚簇索引、二級索引。按「字段特性」分類&#xff1a;主鍵索引…

Spring6 對 集成MyBatis 開發運用(附有詳細的操作步驟)

詳細實現操作步驟 具體實現內容&#xff1a;我們運用 Spring6 和 MyBatis 實現一個轉賬操作(該轉賬操作&#xff0c;進行一個事務上的控制&#xff0c;運用 MyBatis 執行 SQL 語句)。 第一步&#xff1a;準備數據庫表 使用t_act表&#xff08;賬戶表&#xff09; 連接數據庫的…

三個有意思的鏈表面試題的完成

上一篇博客我們已經完成了鏈表的所有內容&#xff0c;那么這一篇博客我們來看一下三個特別有意思的鏈表題目。 **第一個題目如下&#xff1a;**相信不少朋友看到這題目就已經暈了&#xff0c;那就簡單說明下這個題目&#xff0c;題目就是創建一個鏈表&#xff0c;其中每個節點…

深入探索Java中的流式編程:優雅地處理集合數據

Java流式編程&#xff08;Stream API&#xff09;是Java 8引入的一項重要特性&#xff0c;它為處理集合數據提供了一種更為優雅和函數式的方式。通過流式操作&#xff0c;開發者可以以更簡潔、更直觀的方式處理數據&#xff0c;從而提高代碼的可讀性和可維護性。本文將深入探討…

Android14 - 繪制系統 - 概覽

從Android 12開始&#xff0c;Android的繪制系統有結構性變化&#xff0c; 在繪制的生產消費者模式中&#xff0c;新增BLASTBufferQueue&#xff0c;客戶端進程自行進行queue的生產和消費&#xff0c;隨后通過Transation提交到SurfaceFlinger&#xff0c;如此可以使得各進程將緩…

【vue3+elementuiplus】el-select下拉框會自動觸發校驗規則

場景&#xff1a;編輯彈框省份字段下拉框必填&#xff0c;觸發方式change&#xff0c;有值第一次打開不會觸發校驗提示&#xff0c;關閉彈框再次打開觸發必填校驗提示&#xff0c;但是該字段有值 問題的原因是&#xff1a;在關閉彈層事件中&#xff0c;我做了resetfileds&…

SpringBoot + MybatisPlus

SpringBoot MybatisPlus 整合記錄 1. 硬件軟件基本信息2. 相關鏈接3. 通過idea快速生成一個Springboot項目4. 啟動報錯問題解決問題一&#xff1a;Springboot啟動的時候報錯提示 “沒有符合條件的Bean關于Mapper類型”問題二&#xff1a;啟動的時候提示需要一個Bean&#xff0…

電磁仿真--CST網格介紹

1. 簡介 網格會影響仿真的準確性和速度&#xff0c;花時間理解網格化過程是很重要的。 CST 中可用的數值方法包括FIT、TLM、FEM、MoM&#xff0c;使用不同類型的網格&#xff1a; FIT和TLM&#xff1a;六面體 FEM&#xff1a;四面體、平面 MoM&#xff1a;表面 CFD&#…

深入理解與防御跨站腳本攻擊(XSS):從搭建實驗環境到實戰演練的全面教程

跨站腳本攻擊&#xff08;XSS&#xff09;是一種常見的網絡攻擊手段&#xff0c;它允許攻擊者在受害者的瀏覽器中執行惡意腳本。以下是一個XSS攻擊的實操教程&#xff0c;包括搭建實驗環境、編寫測試程序代碼、挖掘和攻擊XSS漏洞的步驟。 搭建實驗環境 1. 安裝DVWA&#xff…

【408真題】2009-16

“接”是針對題目進行必要的分析&#xff0c;比較簡略&#xff1b; “化”是對題目中所涉及到的知識點進行詳細解釋&#xff1b; “發”是對此題型的解題套路總結&#xff0c;并結合歷年真題或者典型例題進行運用。 涉及到的知識全部來源于王道各科教材&#xff08;2025版&…

推薦一個快速開發接私活神器

文章目錄 前言一、項目介紹二、項目地址三、功能介紹四、頁面顯示登錄頁面菜單管理圖表展示定時任務管理用戶管理代碼生成 五、視頻講解總結 前言 大家好&#xff01;我是智航云科技&#xff0c;今天為大家分享一個快速開發接私活神器。 一、項目介紹 人人開源是一個提供多種…

SCSS配置教程

SCSS&#xff08;Sassy CSS&#xff09;是 Sass&#xff08;Syntactically Awesome Stylesheets&#xff09;的一種語法&#xff0c;它是一種 CSS 預處理器&#xff0c;允許你使用變量、嵌套規則、混合&#xff08;mixin&#xff09;、函數等高級功能來編寫 CSS&#xff0c;從而…

Golang | Leetcode Golang題解之第112題路徑總和

題目&#xff1a; 題解&#xff1a; func hasPathSum(root *TreeNode, sum int) bool {if root nil {return false}if root.Left nil && root.Right nil {return sum root.Val}return hasPathSum(root.Left, sum - root.Val) || hasPathSum(root.Right, sum - roo…