systick使用出错总结

在延时函数里,对一次计数结束进行判断时,出现了失误,导致延时时长出现异常。      

先说明函数设计想法,主要while结束判断条件设计,要保证计数器在工作计数到0结束。因此对SysTick->CTRL寄存器有两标志位要进行判断。

计数到0,[16]置1。重点是[16]读取后会清零,因此用一个temp变量进行一次读取,再分别判断标志位。


错误代码:                                                                                                                           

void delay_us(u32 us)
{
	u32 temp = 0;
	SysTick->LOAD = (u32)us * base_us; //设置重载值
	SysTick->VAL = 0x00; //计数值清零
	SysTick->CTRL = 0x01; //开始计时,无中断
	do
	{
		temp = SysTick->CTRL; //注意:[16]读后清零
	}
	while((temp & 0x01) && !(SysTick->CTRL & (1 << 16))); //此处while第二个条件不合理
	SysTick->VAL = 0x00; //计数值清零
	SysTick->CTRL = 0x00; //关闭计数
}
错误原因:在while第二个判断条件又使用了SysTick->CTRL即直接用寄存器内容进行对计数到0的判断。因为在之前已经temp = SysTick->CTRL;读取了一次,这时[16]已清零。已无判断意义,导致延时出现异常

正确代码:                                                                                                                             

void delay_us(u32 us)
{
	u32 temp = 0;
	SysTick->LOAD = (u32)us * base_us; //设置重载值
	SysTick->VAL = 0x00; //计数值清零
	SysTick->CTRL = 0x01; //开始计时,无中断
	do
	{
		temp = SysTick->CTRL; //注意:[16]读后清零
	}
	while((temp & 0x01) && !(temp & (1 << 16))); //用temp对寄存器的标志位进行判断,合理
	SysTick->VAL = 0x00; //计数值清零
	SysTick->CTRL = 0x00; //关闭计数
}



你可能感兴趣的:(arm开发,stm32f103)