STM32中精确延时函数的实现
扫描二维码
随时随地手机看文章
时钟树
SYSTICK原理
Systick定时器的四个寄存器:
/** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTickmemory 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->CTRL寄存器:
CLKSOURCE-时钟源[2]: select the clock soruce, 0 : AHB / 8, 1 : AHB.
0:STCLK=外部时钟源HCLK(AHB总线时钟)/8=72M/8 = 9M
1:FCLK=内核时钟=72M
FCLK:空闲运行时钟
SysTick-> LOAD寄存器:
SysTick-> VAL寄存器:
#include "delay.h"static u8 fac_us=0; //us延时倍乘数static u16 fac_ms=0; //ms延时倍乘数//初始化延迟函数//SYSTICK的时钟固定为HCLK时钟的1/8,即SYSTICK=SYSCLK/8//SYSCLK:系统时钟void delay_init(){SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8fac_us=SystemCoreClock/8000000; //SYSTICK时钟为9M(即8分频)时,fac_us=9,即SysTick倒数9个数,耗时1usfac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数}//查询SysTick->CTRL寄存器bit0是否为1,当为1时,说明倒计时时间到;//整个延时方法中,不进入SysTick中断;//延时nus//nus为要延时的us数.void delay_us(u32 nus){u32 temp;SysTick->LOAD=nus*fac_us; //延时时间加载SysTick->VAL=0x00; //清空计数器SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数//do while 判断就是 systick 使能(bit0)位为 1 且(bit16)为1的时候等待结束do{temp=SysTick->CTRL;}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器SysTick->VAL =0X00; //清空计数器}//延时nms//注意nms的范围//SysTick->LOAD为24位寄存器,所以,最大延时为://nms<=0xffffff*8*1000/SYSCLK//SYSCLK单位为Hz,nms单位为ms//对72M条件下,nms<=1864void 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; //清空计数器}
参考资料:
【正点原子】MiniSTM32开发板资料
喜欢请关注微信公众号:程序员小哈
有啥想玩的模块,留言给我,咱们一起玩
免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!





