博客 / 詳情

返回

systick clock init 滴答時鐘

滴答時鐘初始化,定義us級延時
image
image

SysTick 屬於內核的外設,有關的寄存器定義和庫函數都在內核相關的庫文件core_cm4.h中。SysTick定時器的計數器是向下遞減計數的,隨時按照
SysTick->CTRL |= 0x05;這裏所選擇時基時鐘的計數頻率,當向下計數到0,時,SysTick->LOAD計數值會自動重裝載到寄存器上,繼續計數

點擊查看代碼

點擊查看代碼

#define RCC_PLL_SYSCLK  /*system clock*/
#define SYS_CLK			/*Define the us count value */

volatile uint32_t time_tick;

/*systick clock initialization */
void SYSTICK_CLOCK_init (void)
{
    uint32_t Reload_Value = (RCC_PLL_SYSCLK/1000) - 1;

    SysTick->LOAD = Reload_Value;

    SysTick->VAL = 0;

    // NVIC_SetPriority(SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);

    SysTick->CTRL |= 0x05; /*Select the system clock enable systick */

}
/*"Us-level delay" */
void delay_us(uint32_t nus)
{		
	uint32_t ticks;
	uint32_t told,tnow,tcnt=0;
	uint32_t reload=SysTick->LOAD;	
	/*Calculate the counting time period */
	ticks=nus*SYS_CLK; 						
	told=SysTick->VAL;        				
	while(1)
	{
		tnow=SysTick->VAL;	
		if(tnow!=told)
		{	    
			if(tnow<told)tcnt+=told-tnow;	
			else tcnt+=reload-tnow+told;	    
			told=tnow;
			if(tcnt>=ticks)break;			
		}  
	}
}
/*"Ms-level delay" */
void delay_ms(uint16_t nms)
{
	uint32_t i;
	for(i=0;i<nms;i++) delay_us(1000);
}
/*interrupt mode*/
void SysTick_Handler (void)
{
    time_tick++;
}

uint32_t get_time_tick (void)
{
    return time_tick;
}

void delay_ms_IT (uint32_t time)
{
    uint32_t time_old = get_time_tick();
    while (get_time_tick()-time_old < time);
}
/*interrupt mode*/

—————————————————————————————

函數中利用不斷查看SysTick->VAL寄存器的計數值,通過計算前後是否達到計數要求,滿足要定義的時間要求,理論上可達10ns級延時,但是感覺也沒啥用,另外不建議打開systck中斷,這個中斷通過時基定義1ms進入一次中斷,頻繁的進入退出中斷可能加大總線佔用,打開也無所謂,也不差這點,但是如只為了延時則關了好點

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.