1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
|
相关推荐
1个回答
|
|
SysTick定时器
SysTick定时器,是一个简单的定时器,对于CM3、CM4内核的芯片都有SysTick定时器。SysTick 是一个 24 位的倒计数定时器,当计数到 0 时,将从RELOAD 寄存器中自动重装载定时初值,开始新一轮计数。只要不把它在 SysTick 控制及状态寄存器中的使能位清除(不把Systick定时器关掉),就永不停息。SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。例如,为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统;或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。 作用: Systick定时器常用来做延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。比如:UCOS中,分时复用,需要一个最小的时间戳,一般在STM32+UCOS系统中,都采用Systick做UCOS的心跳时钟。 Systick寄存器:
对于STM32,外部时钟源是HCLK(AHB总线时钟的1/8)内核时钟是HCLK时钟。 配置函数:Systick_CLKSourceConfig(); Systick重装载数值寄存器-LOAD(24位) 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(系统时钟),中断时间间隔1ms,SysTick_Config()这个函数是设置两次中断之间的时间。 { while (1); } while(1) { Delay(200);//200ms … } } SysTick_Config函数: SysTick_Config的参数,其实就是一个时钟次数,叫systick重装定时器的值。意思就是我要多少个1/fosc 时间后中断一下。根据学过的物理中的时间与频率的公式:fosc=1/T T=1/fosc ,fosc为Systick的频率。如果STSystick时钟频率为:72MHz,每次的时间为:T=1/72MHz。1秒钟为:1/(每次的时间)=1/(1/72MHz)=72 000 000次。1MHz是:1000 000。反过来讲。SysTick_Config(72000)代表:72000*(1/72MHz)=1/1000=1(ms)。即定时为1ms。如果需要1S则可以通一设置一个全局变量,然后定初值得为1000,这样每个systick中断一次,这个全局变量减1,减到0,即systick中断1000次,时间为:1ms1000=1S。从而实现1S的定时。 因为SysTick定时器是:24位的,最大定时时间为:2的24次方(1/72MHz)的时间,这里Systick频率为:72MHz的情况下。 delay_init()函数: static u8 fac_us=0;//us延时倍乘数 static u16 fac_ms=0;//ms延时倍乘数,在ucos下,代表每个节拍的ms数 void delay_init() { #if SYSTEM_SUPPORT_OS //如果需要支持OS. u32 reload; #endif SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//选择外部时钟 HCLK/8 fac_us=SystemCoreClock/8000000;//为系统时钟的1/8 相当于72000000/8000000等于九 //一次是1/systick的时钟频率就是1/9 us,fac_us相当于1us,这里的将9赋值给他是给寄存器LOAD计数用的,从9到1就是1us #if SYSTEM_SUPPORT_OS //如果需要支持OS. reload=SystemCoreClock/8000000;//每秒钟的计数次数 单位为M reload*=1000000/delay_ostickspersec;//根据delay_ostickspersec设定溢出时间 //reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右 fac_ms=1000/delay_ostickspersec;//代表OS可以延时的最少单位 SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;//开启SYSTICK中断 SysTick->LOAD=reload; //每1/delay_ostickspersec秒中断一次 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK #else fac_ms=(u16)fac_us*1000;//非OS下,代表每个ms需要的systick时钟数 #endif } void delay_us()函数: void delay_us(u32 nus) { u32 temp; SysTick->LOAD=nus*fac_us; //时间加载 SysTick->VAL=0x00; //清空计数器 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数 do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 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 { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } T=1/1KHZ=1ms=1微秒=1/1000秒 T=1/1MHZ=1us=1微秒=1/1000000秒 10MHz=1/10us=0.1us 20MHz=1/20us=0.05us 50MHz=1/50us=0.02us 1GHz=1ns=1纳秒=1/1000000000秒 1MHZ=1000KHZ=1000000HZ 1GHZ=1000MHZ |
|
|
|
只有小组成员才能发言,加入小组>>
3314 浏览 9 评论
2995 浏览 16 评论
3494 浏览 1 评论
9059 浏览 16 评论
4088 浏览 18 评论
1178浏览 3评论
605浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
599浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 04:35 , Processed in 0.998502 second(s), Total 50, Slave 41 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号