一、 概述 1、 時鐘系統簡介 (1)STM32時鐘源分以下五類: - 高速內部時鐘(HSI):RC振蕩器,精度不高。
- 高速外部時鐘(HSE):可接石英/陶瓷諧振器或者接外部時鐘源。
- 低速內部時鐘(LSI):RC振蕩器,提供低功耗時鐘。應用如WDG。
- 低速外部時鐘(LSE):接外部低頻率石英晶體。應用如RTC。
- 常閉不帶復位:鎖相環倍環輸出(PLL):其時鐘輸入源可選擇為HSI/2、HSE或者HSE/2。倍頻倍數可調,但是其最大輸出頻率受限數值因芯片型號而異。
(2)系統時鐘SYSCLK可來源于:HSI振蕩器時鐘、HSE振蕩器時鐘、PLL時鐘。 2、SYTICK簡介 在STM32中,SysTick是內核CM4中的一個24位的遞減計數器,也稱系統嘀答定時器。SysTick的最大使命,就是定期地產生異常請求,作為系統的時基。操作系統需要這種“滴答”來推動任務和時間的管理。 SysTick在設定初值并開啟后,每經一個系統時鐘周期,計數值減1,計數到0時,將從重載寄存器中自動重新裝載定時初值并繼續計數,同時內部的COUNTFLAG標志位置1,觸發中斷(中斷允許情況下),中斷響應屬于NVIC異常,異常號為15,Systick中斷優先級可設置。 3、SYTICK寄存器控制 STM32內部有4個寄存器控制SysTick定時器。分別為:控制寄存器STK_CSR、重載寄存器STK_LOAD、當前值寄存器STK_VAL和校準值寄存器STK_CALRB。下面分別對這4個寄存器做詳細介紹。 (1)控制寄存器STK_CSR(地址:0xE000E010) 控制寄存器STK_CSR中有4個bit具有意義,其內容如圖4_0、表4_0所示: ENABLE(位0) | Systick使能位。 0:關閉Systick功能; 1:開啟Systick功能。 | TICKINT(位1) | Systick中斷使能位。 0:關閉Systick中斷; 1:開啟Systick中斷,systick倒數到零時產生systick異常中斷。 | CLKSOURCE(位2) | Systick時鐘源選擇位。 0:使用HCLK/8作為Systick時鐘(外部時鐘); 1:使用HCLK作為Systick時鐘(內核時鐘)。 | COUNTFLAG(位16) | Systick計數比較標志,如果在上次讀取本寄存器后,SysTick已經數到了0,則該位為1。如果讀取該位,該位將自動清零。 |
表4_0 控制寄存器STK_CSR的格式 (2)重載寄存器STK_LOAD(地址:0xE000E014)
143025v5daaeydz3zfa3k3.png (16.84 KB, 下載次數: 50)
下載附件
2018-3-7 15:56 上傳
圖4_1 重載寄存器STK_LOAD的格式 重載寄存器STK_LOAD為24位的寄存器(0:23有效),最大計數0xFFFFFF。SysTick定時器遞減至0時,重載寄存器中的值就會被重新裝載,繼續開始遞減計數。(3)當前值寄存器STK_VAL(地址:0xE000E018)
143318cxut9leohxrkllxc.png (17.51 KB, 下載次數: 38)
下載附件
2018-3-7 15:56 上傳
圖4_2 當前值寄存器STK_VAL的格式 當前值寄存器STK_VAL為24位的寄存器,讀取時返回當前計數的值,寫它則使之清零,同時還會清除在SysTick控制及狀態寄存器中的COUNTFLAG標志。(4)校準值寄存器STK_CALRB(地址:0xE000E01C)
143516wk188ag1li8ky248.png (18.01 KB, 下載次數: 41)
下載附件
2018-3-7 15:56 上傳
圖4_3 校準值值寄存器STK_CALRB的格式 NOREF | 0:HCLK可用;
1:HCLK不可用。 | SKEW | 0:校準值是準確的10ms;
1:校準值不是準確的10ms。 | TENMS | 該值是10ms定時的重裝值。其值取決于SKEW,它可以是精確的10ms,也可以是接近10ms的值。如果該值為0,則表示無法使用校準功能,這很可能是因為時鐘是系統的一個未知輸入或者時鐘可以動態調節。 |
表4_1寄存器STK_CALRB的格式 二、實驗原理
通過STM32的三個GPIO口驅動三色LED的三個通道;設定GPIO為推挽輸出;采用灌電流的方式與LED連接,輸出高電平LED滅,輸出低電平LED亮。通過系統定時器實現1s定時,每秒變換一次LED顏色。
143706mpngj3nowoo63a4e.png (25.03 KB, 下載次數: 59)
下載附件
2018-3-7 15:56 上傳
圖4_4 驅動示意圖 三、源代碼 1.主函數 - /*
- * Name : main
- * Description : ---
- * Author : ysloveivy.
- *
- * History
- * --------------------
- * Rev : 0.00
- * Date : 11/21/2015
- *
- * create.
- * --------------------
- */
- int main(void)
- {
- static int work_status = 0;
- led.initialize();
- systick.initialize();
- //每隔一秒三色燈進行交替循環閃爍
- while(1){
- if(systick.second_flag == 1){ //每隔一秒標志位置1,執行一次
- systick.second_flag = 0;
- work_status += 1;
- if(work_status > 2)work_status = 0;
- }
- switch (work_status){
- case 0 :
- LED_RED_ON;
- LED_GREEN_OFF;
- LED_BLUE_OFF;
- break;
- case 1 :
- LED_RED_OFF;
- LED_GREEN_ON;
- LED_BLUE_OFF;
- break;
- case 2:
- LED_RED_OFF;
- LED_GREEN_OFF;
- LED_BLUE_ON;
- break;
- default:
復制代碼 2.Systick初始化 以下是Systick初始化及中斷設置函數,主要實現定標志位的時1s,改變一次標志位,使用LED顯色狀態變換一次。 - /*
- * Name : initialize
- * Description : ---
- * Author : ysloveivy.
- *
- * History
- * -------------------
- * Rev : 0.00
- * Date : 11/21/2015
- *
- * create.
- * -------------------
- */
- static int initialize(void)
- {
- //定時1ms
- if(SysTick_Config(SystemCoreClock / 1000)){
- while(1);
- }
- return 0;
- }
- /*
- * Name : SysTick_Handler
- * Description : ---
- * Author : ysloveivy.
- * History
- * -------------------
- * Rev : 0.00
- * Date : 11/21/2015
- *
- * create.
- * -------------------
- */
- void SysTick_Handler(void)
- {
- static int counter = 0;
- if((counter ++ % 1000) == 0){ //每次中斷counter自加1,判斷是否整秒
- systick.second_flag = 1;
- }
- }
復制代碼 3.小知識 在上面有兩個重要的函數 1.SysTick_Confing(uint32_t ticks) 該函數的作用是初始化systick,時鐘為HCLK(CM3一般為72M,CM4一般為168M),并開啟中斷。 - __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
- {
- if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) //大于重載寄存器最大值0xFFFFFF
- {
- return (1UL); //重新加載值不可能,返回錯誤
- }
- SysTick->LOAD = (uint32_t)(ticks - 1UL); //計數范圍0到ticks-1
- NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
- //設置優先級
- SysTick->VAL = 0UL; //當前值初始化為0
- //接下來設置控制寄存器,以位與的方式實現三個控制位的設置。
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | //選擇時鐘源
- SysTick_CTRL_TICKINT_Msk | //開啟中斷
- SysTick_CTRL_ENABLE_Msk; //使能定時器
- return (0UL); //初始化成功返回
- }
復制代碼 回頭看看程序中的SysTick_Config(SystemCoreClock / 1000)語句,該函數中的SystemCoreClock為時鐘頻率已在庫函數中宏定義。如在iCore3雙核心板ARM的HCLK為168M(每秒168M次計數),則程序中SystemCoreClock / 1000即意味每1ms中斷一次。 2.void SysTick_Handler(void) 該函數是中斷函數,即每次SysTick中斷產生時運行一次函數,其在啟動文件中已有設置,在驅動文件中使用時無需再次聲明。
四、 實驗現象 iCore3的雙核心板上與ARM相連的三色LED(PCB上標示為ARM·LED),紅色、綠色、藍色每秒交替點亮。 五、 代碼包下載鏈接 |