西宁建设网站软件,滕州外贸软件公司,wordpress仿google,网站一级导航怎么做SysTick定时器 SysTick定时器#xff0c;是一个简单的定时器#xff0c;对于CM3、CM4内核的芯片都有SysTick定时器。SysTick 是一个 24 位的倒计数定时器#xff0c;当计数到 0 时#xff0c;将从RELOAD 寄存器中自动重装载定时初值#xff0c;开始新一轮计数。只要不把它…SysTick定时器 SysTick定时器是一个简单的定时器对于CM3、CM4内核的芯片都有SysTick定时器。SysTick 是一个 24 位的倒计数定时器当计数到 0 时将从RELOAD 寄存器中自动重装载定时初值开始新一轮计数。只要不把它在 SysTick 控制及状态寄存器中的使能位清除不把Systick定时器关掉就永不停息。SysTick定时器被捆绑在NVIC中用于产生SYSTICK异常异常号15。在以前大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断作为整个系统的时基。例如为多个任务许以不同数目的时间片确保没有一个任务能霸占系统或者把每个定时器周期的某个时间范围赐予特定的任务等还有操作系统提供的各种定时功能都与这个滴答定时器有关。因此需要一个定时器来产生周期性的中断而且最好还让用户程序不能随意访问它的寄存器以维持操作系统“心跳”的节律。
作用
Systick定时器常用来做延时或者实时系统的心跳时钟。这样可以节省MCU资源不用浪费一个定时器。比如UCOS中分时复用需要一个最小的时间戳一般在STM32UCOS系统中都采用Systick做UCOS的心跳时钟。
Systick寄存器
CLRL寄存器Systick控制和状态寄存器LOAD寄存器Systick自动重装载寄存器VAL寄存器Systick当前值寄存器CALIB寄存器Systick校准值寄存器
Systick控制和状态寄存器-CTRL 对于STM32外部时钟源是HCLKAHB总线时钟的1/8内核时钟是HCLK时钟。 配置函数Systick_CLKSourceConfig();
Systick重装载数值寄存器-LOAD24位 Systick当前值定时器-VAL Systick校准寄存器-CAL 固件库中的Systick相关函数 SysTick_CLCSourConfig()//Systick时钟源选择在misc.c文件中。 SysTick_config(uint32_t ticks)//初始化systick时钟为HCLK并开启中断在core_cm3/core_cm4文件中。
Systick中断服务函数 void SysTick_Handler(void);
用中断的方式实现delay延时比较耗费资源
static __IO uint32_t TimingDelay;
void Delay(__IO uint32_t nTime)
{ TimingDelay nTime;while(TimingDelay ! 0);
}
void SysTick_Handler(void)
{if (TimingDelay ! 0x00) { TimingDelay--;}
}int main(void){ …if (SysTick_Config(SystemCoreClock / 1000)) //systick时钟为HCLK系统时钟中断时间间隔1msSysTick_Config这个函数是设置两次中断之间的时间。{while (1);}while(1){ Delay(200);//200ms… }
}SysTick_Config函数
SysTick_Config的参数其实就是一个时钟次数叫systick重装定时器的值。意思就是我要多少个1/fosc 时间后中断一下。根据学过的物理中的时间与频率的公式fosc1/T T1/fosc ,fosc为Systick的频率。如果STSystick时钟频率为72MHz每次的时间为T1/72MHz。1秒钟为1/每次的时间)1/(1/72MHz)72 000 000次。1MHz是1000 000。反过来讲。SysTick_Config(72000)代表72000*1/72MHz)1/10001ms)。即定时为1ms。如果需要1S则可以通一设置一个全局变量然后定初值得为1000这样每个systick中断一次这个全局变量减1减到0,即systick中断1000次时间为1ms10001S。从而实现1S的定时。 因为SysTick定时器是24位的最大定时时间为2的24次方(1/72MHz)的时间这里Systick频率为72MHz的情况下。
delay_init函数
static u8 fac_us0;//us延时倍乘数
static u16 fac_ms0;//ms延时倍乘数,在ucos下,代表每个节拍的ms数
void delay_init()
{
#if SYSTEM_SUPPORT_OS //如果需要支持OS.u32 reload;
#endifSysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//选择外部时钟 HCLK/8fac_usSystemCoreClock/8000000;//为系统时钟的1/8 相当于72000000/8000000等于九//一次是1/systick的时钟频率就是1/9 us,fac_us相当于1us这里的将9赋值给他是给寄存器LOAD计数用的从9到1就是1us
#if SYSTEM_SUPPORT_OS //如果需要支持OS.reloadSystemCoreClock/8000000;//每秒钟的计数次数 单位为M reload*1000000/delay_ostickspersec;//根据delay_ostickspersec设定溢出时间//reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右 fac_ms1000/delay_ostickspersec;//代表OS可以延时的最少单位 SysTick-CTRL|SysTick_CTRL_TICKINT_Msk;//开启SYSTICK中断SysTick-LOADreload; //每1/delay_ostickspersec秒中断一次 SysTick-CTRL|SysTick_CTRL_ENABLE_Msk; //开启SYSTICK #elsefac_ms(u16)fac_us*1000;//非OS下,代表每个ms需要的systick时钟数
#endif
} void delay_us()函数
void delay_us(u32 nus)
{ u32 temp; SysTick-LOADnus*fac_us; //时间加载 SysTick-VAL0x00; //清空计数器SysTick-CTRL|SysTick_CTRL_ENABLE_Msk ; //开始倒数 do{tempSysTick-CTRL;}while((temp0x01)!(temp(116))); //等待时间到达 SysTick-CTRL~SysTick_CTRL_ENABLE_Msk; //关闭计数器SysTick-VAL 0X00; //清空计数器
}void delay_ms函数
void delay_ms(u16 nms)
{ u32 temp; SysTick-LOAD(u32)nms*fac_ms; //时间加载(SysTick-LOAD为24bit)SysTick-VAL 0x00; //清空计数器SysTick-CTRL|SysTick_CTRL_ENABLE_Msk ; //开始倒数 do{tempSysTick-CTRL;}while((temp0x01)!(temp(116))); //等待时间到达 SysTick-CTRL~SysTick_CTRL_ENABLE_Msk; //关闭计数器SysTick-VAL 0X00; //清空计数器
} T1/1KHZ1ms1微秒1/1000秒T1/1MHZ1us1微秒1/1000000秒10MHz1/10us0.1us20MHz1/20us0.05us50MHz1/50us0.02us1GHz1ns1纳秒1/1000000000秒1MHZ1000KHZ1000000HZ1GHZ1000MHZ