加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

步进电机驱动编后感

2020/07/02
147
阅读需 12 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

以下是鱼鹰当初完成公司第一个项目时写的总结,大家可以看看能否得到一些启发(或许会比较枯燥,毕竟这是鱼鹰自己的经验总结)。

这个步进电机说起来挺简单的,就是用户输入指令,让两个电机上下运动或者停止。并且运动范围通过红外对管限制,并且有步进电机的硬件驱动,我只要控制 IO 并且输出 PWM 脉冲就行。驱动每收到一个脉冲走动一步。

这是公司的第一个项目,因为使用对象是人,所以必须对一些输入进行参数检查。实际上该项目完成的时候,虽然有一些检查,但是却没有全部检查,所以还是会有可能出现 bug 现象。本来在第三次更新该驱动程序的时候,也准备将其改写的,但是我发现目前的水平实在有限,即使再改写,对于参数检查还是没有更好的方法去优化算法。所以在所有函数都重写的情况下唯有这部分代码保留下来了。

这个程序一共进行了三次更新,第一次花了一个星期将基本功能实现了。

当时采用计时的方式进行运行距离的控制。1 ms 中断,每次变量自加 1,这样通过时间乘以速度的方式就可以得到电机的运行距离了,而整个指令组的运行控制在主函数执行。

想法很正确,当时确实也运行起来了,但是后来测试人员告诉我,当设定运行时间很短暂的时候,电机不运行,想想也是,时间太短,并且指令运行的控制是在主函数的,必然有比较大的误差。

虽然第一次写这个程序的时候也想过通过对脉冲计数的方式来实现对电机的控制,这样只要知道我输出了多少个脉冲,就能确定运行了多大的距离。但是当时却不知道该如何获取脉冲数。因为之前只知道输出 PWM 波,根本没想过如何获取 PWM 的数量。

能想到的也就是改硬件了,就是再用一个定时器作为脉冲计数器,这样两个电机就需要两个定时器,包括输出 PWM 的一个定时器,共用三个……所以这个项目当时对于我来说有心无力了,只能将就,只能等以后了。

而且这个程序还有两个缺陷,就是两个电机速度不能单独控制,因为电机速度是通过单位时间内的脉冲数决定的,而输出 PWM 的两个引脚使用了同一个定时器。

而控制 PWM 周期的方式有两种,一种是修改定时器的基本时钟,另一个就是修改计数周期,但这两种方法实际上在一个定时器上都只有一个寄存器

另一个问题就是当时需要暂停功能,我没办法实现,因为我根本不知道程序运行到哪里了,又如何从原来的地方开始运行呢?

后来在看一个有五年工作经验的高手写的代码发现,我其实可以开启定时器的更新中断的,每输出一个脉冲,必然是要进入更新中断的,只要在更新中断完成计数即可。

还有高级定时器有一个寄存器是可以控制输出脉冲数的,这个另说。

因为这个问题一直在脑海,所以在看一篇文章的时候,虽然它不是说如何获取脉冲数,但是也给了我一个灵感,那就是可以同步开启一个定时器的,知道输出 PWM 频率,只要在输出 PWM 的同时开始另一个定时器,就能在控制时间的情况下精确的控制输出 PWM 数,虽然和之前的定时 1ms 计数类似,但精度更高,毕竟对于人来说,1ms 的误差精度虽然高,但是对于 1ms 输出几千个脉冲来说,误差不是一般的大。

这样一来,马上就开始了程序的更新,所以花了大概三天的时间完成了程序的修改,并且因为已经能对输出的脉冲数进行计数,对于之前要求的在到达红外对管的下限之后再运行电机的功能也就能实现了。

但是实际运行之后,设置向下向上的脉冲数相同的情况下,它是不能回到原点的位置。因为这个程序是在第一个程序上写的,第一次写的时候需求不明,考虑的不够完善,所以整个程序的结构比较混乱,对电机运行方向的判断上可能会有误差,所以在更新完成之后,就已经打算有机会再更新一次,这一次更新将推翻之前的程序结构,要考虑的更完善才行,这是自我提高。

所以从家里回来之后,我就开始考虑更新这个程序了,只是没想到花了这么久时间才完成。我也没想过在公司去完善这个程序,公司有公司的事,而且这个程序问题的主因还是自己能力不够,而且我需要更轻松的状态去慢慢考虑清楚,并尝试使用新方法去重新设计程序的结构。

有了前两个程序的基础,所以知道程序设计的时候该考虑哪些问题。

变量设计考虑:首先就是反映电机状态的变量必须保证紧随实际的状态,并且改变这个状态的位置只能是一个地方,而不能这个函数改一下,那个程序改一下,这样肯定会导致整个程序的混乱。

还有就是变量的作用要明确且单一,不要一个变量给它附加多种用途,这样也可能会程序混乱。

除此之外,还要考虑这个变量是否必须一直存在,还是说多个变量其实归纳为一个变量。

一个例子就是,输入用户指令后,有多个参数变量,并且要指示这条指令是否完成,这条指令的当前输出脉冲数等等。

其实对于一个执行器来说,只要将最基本的用户指令保存即可,根本不需要附加其他的,即使有附加,也是在执行的过程存在,也就是说这个命令组的其它附加信息其实只要共用一个变量即可,因为当前运行的只能是一条指令,只要在运行下一条指令时将上一条指令信息清除(可以清除一个标志,作为整条指令信息清除的标志,比如将下行指令标志改为无指令状态即可)并重新初始化就可以继续为下一条指令服务了。
时间同步:就是每次开始处理数据的时候都统一在定时器更新中断执行(前提是这个数据处理必须能在中断时间内处理完成),这样每处理一次,都是在定时器重新计数的情况下,而不会出现这里刚处理完数据,那里就中断数据处理产生一个脉冲的情况,这样必然可能出现脉冲计数不准的情况。

而且在进行数据处理的时候,对关键数据的处理可以采用关闭全局中断和停止定时器的方式来确保数据处理的完整性。

启动操作、结束操作:就是一个完整动作的执行其实只有启动和停止而已,在将所有数据处理完之后就可以进行启动操作,在该动作完成之后只要处理身后事即可,这个身后事包括停止上一个动作的所有影响,以防出现下一个动作还未启动而上一个动作继续执行的情况。

当然还有一种情况就是在启动该动作之后,有可能出现意外情况,而需要将该动作停止,所以需要定时监视。但是定时监视有一个缺陷,就是你不能及时查看异常。所以如果硬件允许的话,可以采用硬件中断来监视。

走一步看一步:在硬件条件不允许的情况下可以采用走一步看一步的方法。就是每输出一个脉冲(之后停止定时器),然后看有没有到限制位置,如果没到,就继续走,如果到了,就停止该动作。这样看起来效率挺低的,可实际上,单片机的速度很快,对于我们人来说,我们根本感觉不到它是边走边看的,你看到的只有一个完整动作执行的现象。

暂停动作:之前提到如何暂停动作,并且重新执行问题,之前想的是从程序本身考虑(离开代码执行,然后重新返回该代码位置重新执行,有点像操作系统切换任务的情况)。

其实我只要停止这个动作的执行并且不破坏这个动作的相关的变量即可,我根本不需要知道它执行到了哪个 PC 地址。比如电机的执行靠 PWM 输出,相关变量的变化是在中断执行的,我只要停止了定时器,就一了百了了。既停止了 PWM 输出(停止动作),又不会让它继续执行相关变量的操作,这样一旦重新启动定时器,变量继续变化,PWM 继续输出,变量条件达到即可像没事一样继续执行停止操作并完成身后事。

所有动作暂停一下:这里所谓的动作暂停不是外部现象的暂停,而是内部的。

并且这个动作应该是内部控制情况下才可以暂停,否则如果是外部控制的情况下暂停内部运行,必然会因为响应不及时丢失重要东西。这里因为电机运行动作全靠自身输出 PWM 来控制的,所以暂停几十毫秒在外界看来没什么影响,也看不出来。

那为什么要暂停呢?比如你要在中断串口输出一个信息,如果采用查询的方式输出的话,必然需要十几毫秒才能输出完成,而这个时间远大于你的中断时间,所以必然会错过下一次中断的执行,导致外部已经输出了一个 PWM,而相关变量计数器没有计数的情况。所以这个时候就可以通过停止定时器的方式来停止动作的执行,这样定时器的寄存器计数器就不会继续累加了,也不会产生脉冲。当输出完之后就可以继续开启定时器。

那为什么不采用关闭全局中断的方式呢?你要知道的是,你关闭全局中断只是屏蔽了中断,而不能阻止中断的发生,只是说,中断发生后,因为你的屏蔽,导致该中断处理程序的延后执行而已。

之前说过两个电机不能独立设置速度的问题,主要就是因为两个引脚共用同一个定时器,后来在偶然情况下想到其实引脚有一个复用功能的,有可能一个引脚是其他定时器的复用输出引脚呢?或许是对于问题的执着,我幸运的发现真的有一个引脚是高级定时器的一个复用 PWM 输出引脚,这样我就不用采用模拟的方式输出 PWM 波了。

到此,当初所有的功能需求完成了。越努力越幸运或许真是如此!

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
PMR205AB6100M033R30 1 Evox Rifa / KEMET Film Capacitor, Paper, 250V, 20% +Tol, 20% -Tol, 0.1uF, 7320,
$2.09 查看
FTSH-105-01-L-DV-K-A 1 Samtec Inc Board Connector, 10 Contact(s), 2 Row(s), Male, Straight, 0.05 inch Pitch, Surface Mount Terminal, Locking, ROHS COMPLIANT

ECAD模型

下载ECAD模型
$3.48 查看
MAC97A6,412 1 WeEn Semiconductor Co Ltd 4 Quadrant Logic Level TRIAC, 400V V(DRM), 0.6A I(T)RMS, TO-92, PLASTIC, SC-43A, 3 PIN

ECAD模型

下载ECAD模型
$0.32 查看

相关推荐

电子产业图谱

六年开发经验,丰富的KEIL调试经验,STM32使用经验,C语言运用经验。