日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

systick定时器 延时计时

發(fā)布時間:2025/4/16 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 systick定时器 延时计时 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

可以直接看定時器二代
systick定時器是屬于cortex M內(nèi)核的外設(shè),專門為RTOS的系統(tǒng)時鐘節(jié)拍設(shè)計的。systick是cortex M內(nèi)核自帶的,因此和debug調(diào)試接口一樣,與單片機型號和廠商無關(guān),只要是cortex M內(nèi)核的單片機,都擁有這個24位的systick定時器。

systick定時器是一個24位遞減計時器,用戶至于要掌握CMSIS包中的SysTick_Config 函數(shù)進行初始化即可。

/** \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)函數(shù)通過參數(shù)ticks設(shè)置中斷間隔,如果要設(shè)置1ms的中斷間隔,則ticks = 系統(tǒng)時鐘/1000. 設(shè)置Systick中斷服務(wù)函數(shù)默認優(yōu)先級最低,可以通過如下函數(shù)修改中斷優(yōu)先級。

// //優(yōu)先級配置 搶占優(yōu)先級1 子優(yōu)先級2 越小優(yōu)先級越高 搶占優(yōu)先級可打斷別的中斷NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),1,2));

初始化完成后,systick在設(shè)置的中斷間隔到來時觸發(fā)中斷,進入中斷服務(wù)函數(shù)

/*** @brief systick中斷服務(wù)函數(shù)** @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 一個系統(tǒng)時間結(jié)構(gòu)體*/ 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_H

bsp_systick.c

/*!* @file bsp_systick.c** @brief systick驅(qū)動文件** @author 不咸不要錢** @note 無** @version 無** @date 2019/10/18 星期五*/ #include "bsp_systick.h"#define EACH_PER_MS 25 /*!<每隔 25 ms 中斷一次 systick 定時器是24位向下計數(shù)的定時器 最大裝載值16777215 */ /** * @brief 一個時間結(jié)構(gòu)體* @note 內(nèi)部調(diào)用*/ struct time{uint32_t fac_us; /*!<us分頻系數(shù) */uint32_t fac_ms; /*!<ms分頻系數(shù) */volatile uint32_t millisecond; /*!<當前ms值 */uint8_t ms_per_tick; /*!<每隔多少ms中斷一次 */}timer;/*!* @brief systime 初始化** @param 無** @return 無** @note 默認優(yōu)先級最低 可以修改** @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中斷// //優(yōu)先級配置 搶占優(yōu)先級1 子優(yōu)先級2 越小優(yōu)先級越高 搶占優(yōu)先級可打斷別的中斷 // NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),1,0)); }/*!* @brief systime 中斷服務(wù)函數(shù)** @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 延時函數(shù)** @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 延時函數(shù)** @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);}}/** 創(chuàng)建一個systck實例 */ systime_t systime = {systime_init,systime_get_current_time_us,systime_get_current_time_ms,systime_delay_us,systime_delay_ms };

總結(jié)

以上是生活随笔為你收集整理的systick定时器 延时计时的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。