在HAL库中,SysTick滴答定时器分析

/*SysTick是24位,倒数定时器

    */
 

在HAL库中,SysTick滴答定时器分析

/*SysTick是24位,倒数定时器

	*/

/*在HAL库中SysTick结构

	*/
typedef struct
{
  __IOM uint32_t CTRL;     /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
  __IOM uint32_t LOAD;     /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
  __IOM uint32_t VAL;      /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
  __IM  uint32_t CALIB;    /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
} SysTick_Type;


//在HAL库中使用它精准计时两种方式

/*****************************************
1.外部时钟

	*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);//配置为外部时钟
#define Clock_Source 216 //216是经倍频(PLL)后的时钟大小,单位为M
#define unsigned int u32
void delay_us(u32 nus)
{		
	u32 ticks;            /**VAL每次减1需要 1/Clock_Source 微秒
	
							*/
	u32 told,tnow;
	u32 tcnt=0;								//记录VAL次数
	u32 reload=SysTick->LOAD;				//重装载值2^23  	 
	ticks=nus*Clock_Source; 				//
	told=SysTick->VAL;        				//定时器VAL初始值
	while(1)
	{
		tnow=SysTick->VAL;	                 //获取当前值
		if(tnow!=told)
		{	    
			if(tnow<told)tcnt+=told-tnow;	/**		|reload
													|
													|told
												|
													|tnow
													|
													∨	
														**/
			else tcnt+=reload-tnow+told;	    
			told=tnow;
			if(tcnt>=ticks)break;			/**		|reload
													|
													|tnow
													|
													|told
													|
													∨	
														**/
		}  
	}
}
 
//延时ms
void delay_ms(u16 nms)
{
	u32 i;
	for(i=0;i<nms;i++) delay_us(1000);
}

/****************************************
2.内部时钟

	*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);//配置为内部时钟
tcnt=told-tnow+tcnt;

tcnt=reload-tnow+told+tcnt;

在while循环中,程序每次循环时间,累次相加,从而达到精准延时
发布了50 篇原创文章 · 获赞 3 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_41865104/article/details/103775203
今日推荐