非RTOS 的delay功能实现 时钟使用SystemInit()初始化(3.5版本库函数)
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */
#include "delay.h" static uint16_t factor_us; //根据系统时钟,延时1uS的计数值 static uint16_t factor_ms; //根据系统时钟,延时1mS的计数值 //--------------------------------------------------------------------------- //函数功能:延时函数初始化 //描述: // 1.SYSCLOCK:系统时钟 // 2. // 执行周期: //日期:2017/10/22 11:53:11 //--------------------------------------------------------------------------- void DelayInit(void) { SysTick->CTRL &= 0xfffffffb; //清除BIT2 ,0 外部时钟源(STCLK) 1 内核时钟(FCLK) factor_us = SystemCoreClock/8000000; //系统时钟8分频 factor_ms = factor_us*1000; } //--------------------------------------------------------------------------- //函数功能:延时函数微秒级 //描述: // 1.SYSCLOCK:系统时钟 // 2. // 执行周期: //日期:2017/10/22 11:53:11 //--------------------------------------------------------------------------- void delay_us(uint16_t delay_us_cnt) { uint32_t SysTick_CTRL_buf_us; SysTick->LOAD = delay_us_cnt * factor_us; //装载重载计数器初始值 SysTick->VAL = 0; //清零计数器初始值 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //使能systick 定时器 //开始计时 do { SysTick_CTRL_buf_us = SysTick->CTRL ; }while( (SysTick_CTRL_buf_us&0x01) && ( !(SysTick_CTRL_buf_us&(1<<16)) ) ); SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //关闭计数器 SysTick->VAL = 0; //清空计数器 } //--------------------------------------------------------------------------- //函数功能:延时函数微秒级 //描述: // 1.SYSCLOCK:系统时钟 // 2. // 执行周期: //日期:2017/10/22 11:53:11 //--------------------------------------------------------------------------- void delay_ms(uint16_t delay_ms_cnt) { uint32_t SysTick_CTRL_buf_ms; SysTick->LOAD = delay_ms_cnt * factor_ms; //装载重载计数器初始值 SysTick->VAL = 0; //清零计数器初始值 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //使能systick 定时器 //开始计时 do { SysTick_CTRL_buf_ms = SysTick->CTRL ; }while( (SysTick_CTRL_buf_ms&0x01) && ( !(SysTick_CTRL_buf_ms&(1<<16)) ) ); SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //关闭计数器 SysTick->VAL = 0; //清空计数器 }
SysTick的库函数部分,来自Core_cm3.h
/** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick memory mapped structure for SysTick @{ */ typedef struct { __IO uint32_t CTRL; /*!< Offset: 0x00 SysTick Control and Status Register *///控制与状态寄存器 __IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register *///重装值寄存器 __IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register *///当前值寄存器 __I uint32_t CALIB; /*!< Offset: 0x0C SysTick Calibration Register *///校准寄存器 } SysTick_Type; /* SysTick Control / Status Register Definitions */ #define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ #define SysTick_CTRL_COUNTFLAG_Msk (1ul << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ #define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ #define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ #define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ #define SysTick_CTRL_TICKINT_Msk (1ul << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ #define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ #define SysTick_CTRL_ENABLE_Msk (1ul << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ #define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ //最大装载值24字节 /* SysTick Current Register Definitions */ #define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ #define SysTick_VAL_CURRENT_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ //最大装载值24字节 /* SysTick Calibration Register Definitions */ #define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ #define SysTick_CALIB_NOREF_Msk (1ul << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ #define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ #define SysTick_CALIB_SKEW_Msk (1ul << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ #define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ #define SysTick_CALIB_TENMS_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ /*@}*/ /* end of group CMSIS_CM3_SysTick */
SysTick寄存器地址定义
#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010) /*!< SysTick Base Address */ #define SysTick ((SysTick_Type *) SysTick_BASE) /*!< SysTick configuration struct */
SysTick function 函数
/* ################################## SysTick function ############################################ */ #if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0) /** * @brief Initialize and start the SysTick counter and its interrupt. * * @param ticks number of ticks between two interrupts * @return 1 = failed, 0 = successful * * Initialise the system tick timer and its interrupt and start the * system tick timer / counter in free running mode to generate * periodical interrupts. */ 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 */ } #endif
MISC.h宏定义时钟来源及分频
#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB) #define SysTick_CLKSource_HCLK ((uint32_t)0x00000004) #define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \ ((SOURCE) == SysTick_CLKSource_HCLK_Div8))
Systick的时钟来源有两个:HCLK 或者HCLK的8分频
SysTick 中断
中断向量定义在startup_stm32f10x_hd.s文件 line77
DCD SysTick_Handler ; SysTick Handler
中断函数定义在stm32f10x_it.c lin135
/** * @brief This function handles SysTick Handler. * @param None * @retval None */ void SysTick_Handler(void) { }