SysTick定时器,也叫滴答定时器或者系统定时器。
SysTick-系统定时器是属于CM3内核中的一个外设,内嵌在NVIC中。系统定时器是一个24位的向下递减的计数器,计数器每计数一次的时间为1/SYSCLK,一般我们设置系统时钟SYSCLK等于72MHz。当重装载数值寄存器的值递减到0的时候,系统定时器就产生一次中断,以此循环往复。
因为SysTick是属于CM3内核的外设,所以所有基于CM3内核的单片机都具有这个系统定时器,这是的软件在CM3单片机中可以很容易被移植。系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。
- Systick定时器是一个比较简单的定时器,常用于延时或者计时,也可以用作实时系统的心跳时钟。节省通用定时器的资源。
- 只要不把Systick定时器关闭,它就会循环往复计时,在睡眠模式下也能工作。
- Systick中断的优先级也可以设置。
4个Systick寄存器
SysTick库函数
SysTick中断服务函数
void SysTick_Handler(void);
库函数中SysTick的定义以及其寄存器对应地址的映射如下:
//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;
Delay延时函数
相比于51单片机直接生成的延时函数,STM32的延时函数就比较复杂了,但是可以直接cv
#include "stm32f10x.h"
#include "Delay.h"
static uint8_t us = 0;
static uint16_t ms = 0;
void Delay_Init(uint8_t MHz) //72MHz
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //8分频,72M/8=9M
us = MHz/8; //1us计数9个
ms = (uint16_t)us*1000; //1ms计数9000个
}
/*说明
2的24次方 = 3个2的8次方 = 256*256*256 = 16777216 (24位递减计数器计数个数)
16777216/9000 = 1864.135 (能计时1864ms,最多计时1.864s)
注意最大定时时间为1.864s
*/
/**
* @brief 毫秒级延时
* @param xms 延时时长,参数最大写1864
* @retval 无
*/
void Delay_ms(uint32_t xms)
{
uint32_t temp;
SysTick ->LOAD = (uint32_t)ms*xms; //重载值
SysTick ->VAL = 0;
SysTick ->CTRL |= SysTick_CTRL_ENABLE_Msk;//软件方式开启计数器,使能
//开启计数器另一种写法 SysTick ->CTRL = 0x01;
do{
temp = SysTick ->CTRL;
}while( (temp & 0x01) && !(temp & (1<<16)) ); //COUNTFLAG = 1,就代表计数完毕
//(temp & 0x01) 检查计数器是否开启
SysTick ->VAL = 0;
SysTick ->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
//关闭计数器另一种写法 SysTick ->CTRL = 0x00;
}
/**
* @brief 微秒级延时
* @param ums 延时时长
* @retval 无
*/
void Delay_us(uint32_t xus)
{
uint32_t temp;
SysTick ->LOAD = us*xus;
SysTick ->VAL = 0;
SysTick ->CTRL |= SysTick_CTRL_ENABLE_Msk;
do{
temp = SysTick ->CTRL;
}while( (temp & 0x01) && !(temp & (1<<16)) );
SysTick ->VAL = 0;
SysTick ->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
void Delay_s(uint32_t xs)
{
while(xs--)
{
Delay_ms(1000);
}
}
在使用延时函数前,记得初始化延时函数
Delay_Init(72); //初始化延时函数
另一版本……也可以直接用
/**
* @brief 微秒级延时
* @param xus 延时时长,范围:0~233015
* @retval 无
*/
void Delay_us(uint32_t xus)
{
SysTick->LOAD = 72 * xus; //设置定时器重装值
SysTick->VAL = 0x00; //清空当前计数值
SysTick->CTRL = 0x00000005; //设置时钟源为HCLK,启动定时器
while(!(SysTick->CTRL & 0x00010000)); //等待计数到0
SysTick->CTRL = 0x00000004; //关闭定时器
}
/**
* @brief 毫秒级延时
* @param xms 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_ms(uint32_t xms)
{
while(xms--)
{
Delay_us(1000);
}
}
/**
* @brief 秒级延时
* @param xs 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_s(uint32_t xs)
{
while(xs--)
{
Delay_ms(1000);
}
}
这个就不需要初始化等,直接用即可
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)