问题如图:
如上图的最右边有一个很细的线,根据步进电机控制算法,理论上应该输出10个脉冲,而最后一个很细的脉冲就是多出来的一个脉冲。
1. 硬件问题,电路上的干扰;
2. Stm32单片机问题,定时器问题
3. 软件逻辑问题;(最后发现是这个原因)
由于软件逻辑是最容易看到的,所以就先从代码上去分析问题,逻辑如下:
根据上述流程图,软件逻辑上初步没分析出什么问题,所以就先针对1和2去调试。
硬件问题就去对比其它机器,测试了四台的设备,其中三台都存在杂波,有一台机器没有出现。初步有点怀疑是硬件问题。
然后又找了一块空板卡,只给它提供电源。测试出还是有杂波,根据电路分析,空板不存在干扰,硬件干扰也暂时无依据。所以排除这个猜想。
通过翻阅stm32参考手册,对照着寄存器描述,一一对应,更改配置查看输出效果。并没有改善,所以定时器的配置是对的。
通过多种手段都不能证明,单片机有问题。
1. 怀疑定时器中断开始,到停止定时器中间的代码逻辑有时间损耗;
2. 怀疑从接收到定时器溢出事件,到中断执行有时间损耗;
如上图,是两个不同示波器捕捉到的脉冲。蓝色脉宽为进入中断拉低电平,退出中断前拉高电平。所以中断内的逻辑执行时间约1us。怀疑1验证正确。
如上图,黄色线是PWM引脚输出脉冲,上升沿即是定时器产生溢出事件和中断的时刻,蓝色线下降沿是中断最开始出拉低引脚电平的时刻,所以从定时器溢出到进入中断中间大概有360ns。怀疑2验证正确。
至于后面黄色线拉低,蓝色线拉高有时间差,是因为先拉高蓝色线引脚,再关闭PWM;看右图是先关闭PWM后再拉高电平;说明关闭PWM的接口函数也消耗了一些时间。
最后由上面四个图,可以得出这最后一个杂波产生的原因就是开头两个怀疑的原因。
3.5 翻阅技术文档
通过翻阅《ARM Cortex-M3与Cortex-M4权威指南》和《stm32f4参考手册》有如下说明:
1.根据“权威指南”8.3节中断等待和异常处理优化,中的描述;中断从触发到执行,通常需要12个周期。当有一些特殊情况,会导致这个时间更长,如关闭中断。由于在cotex-M4中时钟周期等于机器周期,而指令周期一般是几个机器周期组成。根据主频180MHz,时钟周期=1/180MHz=5.555ns;
2.根据《stm32f4参考手册》,当产生couter溢出,会立即产生溢出事件和更新中断(如下图),所以溢出到中断的延时应该只有12周期。
最后得出结论:因为时钟周期5.555ns*12=66.66ns;根据示波器测试的结果,中断事件到中断执行的时间约是360ns。所以12周期应该是指令周期。
3.6 结论
产生杂波的原因:
1.定时器中断开始,到停止定时器中间的代码逻辑有时间损耗;
2.从接收到定时器溢出事件,到中断执行有时间损耗;
技术文档中的12个周期应该是指12个指令周期。
解决方案:
原先的定时器配置是将PWM起始电平设置成高电平,结束是低电平。所以最后一个杂波就是最后一个PWM的开始部分。如果将定时器的PWM配置成先低电平,后高电平,则就不会有这个问题了。效果如下图: