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变量应为有符号型。注意,声明中也必须为有符号型,否则会出错!