STM32和時鐘相關的硬體模組包括了sys_tick, TIM, 還有RTC模組,而sys_tick 這個是arm公司設計的硬體的模組,這個sys_tick 是CPU的外設,所以這個模組無論是ST公司,還是NXP,ST也好,只要你是cortex-4 的cpu 都會有這一個模組。而且在CPU的物理的地址都是一樣的。
下面這張是ARM cortext-4 的CPU的 memory map,所有的cortex-4 核心的微控制器都會遵循這個地址空間範圍,ST ,TI NXP 都是這個地址空間,這也是arm公司規定的 ,這個不細說了,注意一下sys_tick 是arm cortex4 CPU的peripheral
sys_tick的硬體框圖
三個紅色暫存器 1 紅色框框。
工作原理就是先給預設暫存器設定一個值,比如4000; Ctrl 暫存器enable設定1的時候,就這個4000 轉載到 current 暫存器,兩個都是4000了,然後紅色數字1的 clk 每來一個脈衝,current寄存寄存就減一, 直到數值到0,一旦到0,又重新把預設暫存器中的值4000複製到current暫存器中, 如果發現ctrl 寄存中中斷控制是使能的。就通知NVIC systick 減到0了,要產生中斷告訴CPU。
然後就會跳到SysTick_Handler中去做你要做的事情,通常帶OS(如FreeRTOS,RT-thread)的話
收到這個中斷就會呼叫一下任務排程器。去找優先順序高的任務執行,這是systick的一個應用。另外一個用的比較多就是延時函式。
所以程式碼也簡單:
紅色框框的就是 中斷的一個應用方式,藍山框框的就是延時的一種方式,延時的實現原理就是去查詢當前的count 值,然後到1ns的count 就結束。
硬體邏輯也簡單,之前看過riscv的sys_tick和這個cortext-m4 的邏輯是一樣的。
看完了arm 的定時器,再來看看 stm32的定時器,STM32的定時有好幾種,做延時一樣的功能就是basic_timer.
綠色的,和紅色的框框同arm的一樣, 一個是預製暫存器,另一個是當前count暫存器,一個就是放要記到多少的一個值,另一個是當前的計數器的值,另外比cortex4多了一個PSC的暫存器,這個是給時鐘分頻用的。比如系統時鐘太高了,可以給到timer的時鐘在原來的基礎上除2,除4等
stm32 timer的定時器暫存器多了綠色框框的幾個,當是紅色的和cortex4是一樣的,程式碼也簡單,但軟體是和systick 的實現邏輯不一樣了,來看看程式碼
26行。 APB1的clock 是40Mhz,當按40分頻是就是1ns,也就說從APB1到TIM6的時間就是40Mhz/40 ==1Mhz了,所以每來一個clock 就是1ns. 所以void tim6_delay_ns(count) count 就是想要計數的ns數,當然不能超過暫存器最大16位資料。
最後打無論是systick,TIM 都是每隔1m的列印一串字元。
後來看了一下RTC,是用來計數時間日期之類的,和這定時器關係不大, RTC以後專門看。
NO CMISS,NO HAL, NO Libray. 全自己擼程式碼, 又重複造了三個輪子。 systick , tim6, NVIC 中斷,下次繼續造。
程式碼路徑 https://gitee.com/android_life/stm32_freertos_opensource/tree/master/bareos/systick_tim_test