完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
滴答定时器(SysTick)的作用:
1、作为操作系统时基 2、作为精确延时函数时基(delay函数) 滴答定时器是一个 24 位的倒计数定时器,当计到 0 时,将从 RELOAD 寄存器中自动重装载定时器初值,只要不把它在 SysTick 控制寄存器以及状态寄存器中的使能位清零,就将永久不息。 Cortex‐M3/4 在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断。 编号为 1-15 的对应系统异常,大于等于 16 的则全是外部中断。 有 3 个固定优先级的系统异常:复位,NMI 以及硬 fault,它们的优先级是不可编程的,它们的优先级号是负数,从而高于所有其它异常。 其它异常的优先级则都是可编程的(但不能编程为负数)做成芯片后,支持的中断源数目常常不到 240 个,并且优先级的位数也由芯片厂商最终决定。但是16个异常一般都是拥有的,这16个异常都有共同的特性,比如它们的位操作是一样的,这增加了同一内核不同芯片之间代码的可移植性。 SysTick寄存器:(可通过M3/4权威指南查看) SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。 在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。 有4个寄存器控制SysTick定时器: 库函数里面的结构体: typedef struct { __IO uint32_t CTRL; /*!《 Offset: 0x000 (R/W) SysTick Control and Status Register */ __IO uint32_t LOAD; /*!《 Offset: 0x004 (R/W) SysTick Reload Value Register */ __IO uint32_t VAL; /*!《 Offset: 0x008 (R/W) SysTick Current Value Register */ __I uint32_t CALIB; /*!《 Offset: 0x00C (R/ ) SysTick Calibration Register */ } SysTick_Type; 看后面的注释知道四个结构体成员对应上面四个寄存器。 SysTick定时器除了能服务于操作系统之外,还能用于其它目的:如作为一个闹铃,用于测量时间(delay延时函数)等。 要注意的是,当处理器在调试期间被喊停(halt)时,则SysTick定时器亦将暂停运作。 是个定时器都需要时钟来源,从时钟树来看,SysTick定时器的时钟是AHB/8(也就是HCLK/8)。如果我们外部晶振为 8M,然后倍频到 168M,那么 SysTick 的时钟即为 21Mhz。也就是 SysTick 的计数器 VAL (定时器的CURRENT寄存器)每减 1,就代表时间过了 1/21us ——在21Mhz的频率跳动时,每跳1次所用的时间,1/21us称它为时基:1/(21x10^6hz)=1/21us。(这就是为什么后面程序里面fac_us=SYSCLK/8的原因,在这里SYSCLK=168,所以fac_us=21) 具体代码: //SYSTICK的时钟固定为AHB时钟的1/8 //SYSCLK:系统时钟频率 void delay_init(u8 SYSCLK) { /*定义SysTick的时钟来源,可以是HCLK或者是HCLK/8*/ SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); /*SYSCLK是传进来的参数,这里是STM32F4,所以SYSCLK是168*/ /*HCLK/8定时器时基为1/21us,所以1us跳21次,这就是SYSCLK/8的原因*/ fac_us=SYSCLK/8; //fac_us其实就是定时1us了,这里是一个值21 fac_ms=(u16)fac_us*1000; //代表每个ms需要的systick时钟数 } 那么我们看看us的延时函数: //延时nus //nus为要延时的us数。 //注意:nus的值,不要大于798915us(最大值即2^24/fac_us@fac_us=21) void delay_us(u32 nus) { u32 temp; SysTick-》LOAD=nus*fac_us; //时间加载fac_us=21,每个us跳21次 SysTick-》VAL=0x00; //清空计数器 SysTick-》CTRL|=SysTick_CTRL_ENABLE_Msk ; //SysTick定时器使能,开始倒数,SysTick_CTRL_ENABLE_Msk=1 do { /*判断SysTick的控制及状态寄存器(CTRL)第16位是否置1(置1代表倒计数结束) temp&0x01这个语句是判断SysTick是否已经使能(其实可以省略这个语句) !(temp&(1《《16)判断CTRL寄存器16位是否置1,置1取反后为0则跳出循环 */ temp=SysTick-》CTRL; //把CTRL寄存器的值赋给temp }while((temp&0x01)&&!(temp&(1《《16))); //等待时间到达 SysTick-》CTRL&=~SysTick_CTRL_ENABLE_Msk; //ysTick定时器使能位清零,关闭计数器 SysTick-》VAL =0X00; //清空计数器 } 注释已经在代码中了,十分详细。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1632 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1559 浏览 1 评论
985 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
688 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1605 浏览 2 评论
1869浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
653浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
523浏览 3评论
540浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
510浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 16:09 , Processed in 0.904586 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号