systick定时器 延时计时
生活随笔
收集整理的這篇文章主要介紹了
systick定时器 延时计时
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
可以直接看定時器二代
systick定時器是屬于cortex M內核的外設,專門為RTOS的系統時鐘節拍設計的。systick是cortex M內核自帶的,因此和debug調試接口一樣,與單片機型號和廠商無關,只要是cortex M內核的單片機,都擁有這個24位的systick定時器。
systick定時器是一個24位遞減計時器,用戶至于要掌握CMSIS包中的SysTick_Config 函數進行初始化即可。
/** \brief System Tick ConfigurationThis function initialises the system tick timer and its interrupt and start the system tick timer.Counter is in free running mode to generate periodical interrupts.\param [in] ticks Number of ticks between two interrupts\return 0 Function succeeded\return 1 Function failed*/static __INLINE uint32_t SysTick_Config(uint32_t ticks){if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */NVIC_SetPriority (SysTick_IRQn, (1 << __NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */SysTick->VAL = 0; /* Load the SysTick Counter Value */SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |SysTick_CTRL_TICKINT_Msk |SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */return (0); /* Function successful */}SysTick_Config(uint32_t ticks)函數通過參數ticks設置中斷間隔,如果要設置1ms的中斷間隔,則ticks = 系統時鐘/1000. 設置Systick中斷服務函數默認優先級最低,可以通過如下函數修改中斷優先級。
// //優先級配置 搶占優先級1 子優先級2 越小優先級越高 搶占優先級可打斷別的中斷NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),1,2));初始化完成后,systick在設置的中斷間隔到來時觸發中斷,進入中斷服務函數
/*** @brief systick中斷服務函數** @param ** @return ** @note ** @example ** @date 2019/6/10 星期一*/ void SysTick_Handler(void) {}完整代碼 bsp_systick.h
#ifndef __BSP_SYSTICK_H #define __BSP_SYSTICK_H #include "stdint.h"/** * @brief 一個系統時間結構體*/ typedef struct { void (* init) (void); uint32_t (* get_time_us) (void);uint32_t (* get_time_ms) (void);void (* delay_us)(uint32_t);void (* delay_ms)(uint32_t); }systime_t;/** 聲明 systime */ extern systime_t systime;#endif //__BSP_SYSTICK_Hbsp_systick.c
/*!* @file bsp_systick.c** @brief systick驅動文件** @author 不咸不要錢** @note 無** @version 無** @date 2019/10/18 星期五*/ #include "bsp_systick.h"#define EACH_PER_MS 25 /*!<每隔 25 ms 中斷一次 systick 定時器是24位向下計數的定時器 最大裝載值16777215 */ /** * @brief 一個時間結構體* @note 內部調用*/ struct time{uint32_t fac_us; /*!<us分頻系數 */uint32_t fac_ms; /*!<ms分頻系數 */volatile uint32_t millisecond; /*!<當前ms值 */uint8_t ms_per_tick; /*!<每隔多少ms中斷一次 */}timer;/*!* @brief systime 初始化** @param 無** @return 無** @note 默認優先級最低 可以修改** @see systime.init(); //初始化 ** @date 2019/6/10 星期一*/ void systime_init(void) {timer.fac_us = SystemCoreClock / 1000000;timer.fac_ms = SystemCoreClock / 1000;timer.ms_per_tick = EACH_PER_MS;timer.millisecond = 100;SysTick_Config((SystemCoreClock / 1000) * timer.ms_per_tick ); //開啟systick中斷// //優先級配置 搶占優先級1 子優先級2 越小優先級越高 搶占優先級可打斷別的中斷 // NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),1,0)); }/*!* @brief systime 中斷服務函數** @param 無** @return 無** @note 無** @see 無** @date 2019/6/10 星期一*/ void SysTick_Handler(void) {timer.millisecond += timer.ms_per_tick; }/*!* @brief 獲取當前時間** @param 無** @return 當前ms值** @note 無** @see system.get_time_ms(); //獲取當前ms值 ** @date 2019/6/10 星期一*/ uint32_t systime_get_current_time_ms(void) {register uint32_t val, ms;do{ms = timer.millisecond;val = SysTick->VAL; }while(ms != timer.millisecond);return ms - val/timer.fac_ms; }/*!* @brief 獲取當前時間** @param 無** @return 當前us值** @note 無** @see system.get_time_us(); //獲取當前ms值 ** @date 2019/6/10 星期一*/ uint32_t systime_get_current_time_us(void) {register uint32_t val, ms;do{ms = timer.millisecond;val = SysTick->VAL;}while(ms != timer.millisecond);return (uint32_t)((uint32_t)(ms * 1000) - val / timer.fac_us); }/*!* @brief systime 延時函數** @param us :延時時間** @return 無** @note 最大延時不要超過 4292s** @see system.delay_us(1000); //延時1ms** @date 2019/6/10 星期一*/ void systime_delay_us(uint32_t us) {uint32_t now = systime.get_time_us();uint32_t end_time = now + us - 3;while( systime.get_time_us() <= end_time){;} }/*!* @brief 延時函數** @param ms : 延時時間** @return 無** @note 無 ** @see system.delay_ms(1000); //延時1s ** @date 2019/6/10 星期一*/ void systime_delay_ms(uint32_t ms) {while(ms--){systime.delay_us(1000);}}/** 創建一個systck實例 */ systime_t systime = {systime_init,systime_get_current_time_us,systime_get_current_time_ms,systime_delay_us,systime_delay_ms };總結
以上是生活随笔為你收集整理的systick定时器 延时计时的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 单片机按键FIFO
- 下一篇: IMXRT 分散加载文件 修改OCRAM