16.3.2.2.3 SysTick初始化函數
列表3:代碼清單17?3 SysTick初始化函數
/*** @brief 啟動系統滴答計時器 SysTick* @param IT_frequency: 滴答計時器每秒的中斷次數* @retval 無*/voidSysTick_Init(uint32_t IT_frequency){/* SystemCoreClock 在這里默認為 200M* SystemCoreClock / 1000 1ms 中斷一次* SystemCoreClock / 100000 10us 中斷一次* SystemCoreClock / 1000000 1us 中斷一次*/IT_Period = SystemCoreClock / IT_frequency;uint32_t err = SysTick_Config (IT_Period);assert(err==0); //capture error}
SysTick_Init函數里面調用了SysTick_Config()這個固件庫函數,通過設置該固件庫函數的形參,就決定了系統定時器經過多少時間就產生一次中斷。
16.3.2.2.4 SysTick中斷時間的計算
SysTick定時器的計數器是向下遞減計數的,計數一次的時間TDEC=1/CLKICLK,當重裝載寄存器中的值VALUELOAD減到0的時候,產生中斷,可知中斷一次的時間TINT=VALUELOAD*TDEC=VALUE LOAD/CLKICLK,其中CLKICLK=200MHZ。
如果設置VALUELOAD為200,那中斷一次的時間TINT=200/200M=1us。不過1us的中斷沒啥意義,整個程序的重心都花在進出中斷上了,根本沒有時間處理其他的任務。
IT_Period = SystemCoreClock / IT_frequency; //IT_frequency 為中斷的頻率 (單位為Hz)SysTick_Config(IT_Period) //IT_Period 為中斷一次的時間 (單位為時鐘節拍數)
SysTick_Config()的形參我們配置為 IT_Period。例如,當IT_frequency為1000,IT_Period=SystemCoreClock/IT_frequency=200M/1000=200K,從剛剛分析我們知道這個形參的值最終是寫到重裝載寄存器LOAD中的,從而可知我們現在把SysTick定時器中斷一次的時間TINT=200k/200M=1ms。
16.3.2.2.5 SysTick定時時間的計算
當設置好中斷時間TINT后,我們可以設置一個變量t,用來記錄進入中斷的次數,那么變量t乘以中斷的時間TINT就可以計算出需要定時的時間。
16.3.2.2.6 SysTick定時函數
現在我們定義一個延時函數,類似官方的延時函數“R_BSP_SoftwareDelay”,形參為delay和unit,這兩個形參相乘就得出我們需要的延時時間 TSUM,因此進入中斷的次數 t=TSUM/TINT。
列表4:代碼清單17?4 SysTick延時函數
/*** @brief 延時程序* @param delay: 延時的單位時間* @param unit: 延時的單位* @retval 無*/voidSysTick_Delay(uint32_t delay, sys_delay_units_t unit){uint32_t SumTime = delay * unit; //計算總延時時間 (單位為時鐘節拍數)IT_nums = SumTime/IT_Period;while (IT_nums != 0);}
SysTick_Delay()中我們等待IT_nums為0,當IT_nums為0的時候表示延時時間到。變量 IT_nums在中斷函數中遞減,即SysTick每進一次中斷即TINT的時間IT_nums遞減一次。
16.3.2.2.7 sys_delay_units_t
列表5:代碼清單17?5 sys_delay_units_t
typedefenum{SYS_DELAY_UNITS_SECONDS = 200000000, ///< Requested delay amount?→is in secondsSYS_DELAY_UNITS_MILLISECONDS = 200000, ///< Requested delay amount?→is in millisecondsSYS_DELAY_UNITS_MICROSECONDS = 200///< Requested delay amount?→is in microseconds} sys_delay_units_t;
16.3.2.2.8 SysTick中斷服務函數
列表6:代碼清單17?6 SysTick中斷服務函數
/*** @brief SysTick 的中斷服務函數* @param 無* @retval 無*/externvoidSysTick_Handler(void); //需要先 extern 聲明一下避免編譯器警告voidSysTick_Handler(void){if (IT_nums != 0x00){IT_nums--;}}
16.3.2.2.9 hal_entry入口函數
列表7:
代碼清單17?7由main函數轉入的hal_entry函數
voidhal_entry(void){/* TODO: add your own code here */R_BSP_PinAccessEnable (); //啟用對 PFS 寄存器的訪問, 因為后面寫 IO 口都用BSP 內聯函數SysTick_Init(1000); //初始化系統時鐘, 設置中斷頻率為 1000Hzwhile (1){R_BSP_PinWrite (LED_G, BSP_IO_LEVEL_LOW); //點亮綠色 LEDSysTick_Delay(1, SYS_DELAY_UNITS_SECONDS); //延時 1sR_BSP_PinWrite (LED_G, BSP_IO_LEVEL_HIGH); //熄滅綠色 LEDSysTick_Delay(1, SYS_DELAY_UNITS_SECONDS); //延時 1s}/* Enter non-secure code */R_BSP_NonSecureEnter();}
主函數中初始化了SysTick,然后在一個while循環中以1s的頻率讓LED閃爍。

如您在使用瑞薩MCU/MPU產品中有任何問題,可識別下方二維碼或復制網址到瀏覽器中打開,進入瑞薩技術論壇尋找答案或獲取在線技術支持。
https://community-ja.renesas.com/zh/forums-groups/mcu-mpu/
未完待續
推薦閱讀
中斷的過程介紹——瑞薩RA系列FSP庫開發實戰指南(39)
實驗:按鍵外部中斷的軟件設計——瑞薩RA系列FSP庫開發實戰指南(40)
SysTick系統定時器——瑞薩RA系列FSP庫開發實戰指南(41)

