« 上一篇下一篇 »

一日记录

1、关于SisTick时钟

问题:我用定时器0开了一个5ms的中断,然后在中断里面做控制处理,却发现程序一直停在里面死循环,将相关代码逐条注释,后来发现是delay_us()延时函数的原因,而这个延时函数的实现是通过SisTick的中断来实现的,通过在中断里设一个变量,来决定什么时候停止延时,但程序就是在这里死循环了,原因就在于:SisTick的中断在初始化设置时已经设置为最低优先级,而我却一直潜意识的认为SisTick的中断是最高优先级,所以错了,因为SisTick的中断优先级过低,导致无法在定时器0中断里面进入SisTick中断,所以函数一直死循环了。

函数如下:

void delay_us(uint32_t tick)       /* Delay Function */ 
{
unsigned long systickcnt;
// 用一个变量来保存延时开始时刻SysTickCnt的值,以便与后来的值做差运算
systickcnt = SysTickCnt;
while( (SysTickCnt - systickcnt) < tick );
}







它需要读取一个差值来结束循环,而如果进不去中断,则差值永远为0,也就死循环了。下面是修改后的us延时:

void Delay_us(uint32_t nus)
{
SysTick->LOAD = nus * 72 - 1; //时间加载            
    SysTick->CTRL |= 0x01;      //开始倒数          
    while( !( SysTick->CTRL & (1<<16) ) );//等待时间到达     
    SysTick->CTRL &= ~0x01;       //关闭计数器  
}

它不需要进入中断,而只是来判断相关寄存器的状态位来确定延时是否结束,这样就不会导致在一个中断里面无法调用此延时的问题了。

2、关于电机PWM

由于电机的运转有正反两个方向,所以其PWM变量应为有符号型。注意,声明中也必须为有符号型,否则会出错!