在HCS08系列MCU上用软件实现仪表步进电机的驱动
0赞
步进电机由于具有角位移和输入脉冲数成正比并且没有累积误差的特点,而被广泛地用作汽车仪表的显示部件。在多数情况下,人们会使用专用的驱动芯片来驱动步进电机,主控制器只需要给出方向控制信号和控制转动步数的脉冲就行了。另外,也有集成了步进电机驱动电路的MCU(微控制器),如Freescale的MC9S12HY系列,其使用方法也比较简单。然而,在很多较低端的汽车仪表,如微型车、农用车、三轮货车和摩托车的仪表上,人们为了降低成本,希望能够不用专用驱动芯片或相对较贵的带驱动电路的MCU,而是用普通的MCU直接去驱动步进电机。本文介绍了在Freescale的HCS08系列MCU上,如何用软件来实现对VID29系列步进电机的直接驱动。本文所附带的程序,已经在Freescale的LG32 Cluster RefereDesign演示板上运行验证过。
分步驱动和微步驱动
步进电机的驱动通常有分步方式和微步方式两种。分步方式的优点是驱动信号的幅度只有0和电源电压(5V)两种,与数字信号的低电平和高电平完全一一对应,因此只要使用MCU的普通数字I/O口(GPIO)就可以产生驱动信号,驱动程序也比较简单。但是由于分步方式下,定子线圈产生的气隙磁场的方向在每走一步的过程中都发生一个较大的跳变——对于VID29系列步进电机而言是60°的跳变,定子磁场从原来的方向跳变到下一个平衡位置的方向,转子则在磁力的作用下加速向下一个平衡位置转动,当它到达平衡位置的瞬间,速度达到最大值,而磁场力则变为零(只考虑切向力,不考虑径向力,因为径向力与转动无关。下同);然后,如果驱动信号没有变化的话,转子就会在惯性的作用下继续往前转动,偏离平衡位置,这时磁场力将会增大,而其方向却变成跟刚才相反,于是就使转子减速,当转子与平衡位置的偏离达到最大时,其速度减为零,然后在磁场力作用下往回加速转动;当转子转回平衡位置时,磁场力又变为零,而速度不为零,于是在惯性的作用下继续转动偏离平衡位置……如此反复,只要驱动信号还没有再次改变,转子就会象荡秋千一样在平衡位置附近来回振荡,并在摩擦力的作用下幅度逐渐减小。这种振荡还会产生一定的噪声,所以用分步方式驱动时,步进电机的噪声和抖动会比较大。
为了减小步进电机运行时的噪声和抖动,人们设法让定子线圈的磁场方向的跳变幅度变小,把一个分步一次的大跳变分成若干次较小的跳变来完成,于是就有了微步驱动方式,也叫细分驱动方式。
步进电机在转动时,因为转子、传动齿轮和负载的转动惯量,使它从一个位置转动到下一个位置(一个分步或微步)需要一定的时间。如果在转子转动到下一个位置之前,驱动信号就又往前走了一步的话,那么转子的磁场方向和定子线圈产生的气隙磁场方向之间的夹角就会超过一个分步或微步所对应的角度。只要转子的旋转速度跟不上驱动信号的变化速度,这个夹角就会越来越大,当夹角超过180°时,磁场对转子的作用力的方向就会变得跟原来的方向相反。结果就是转子所转过的角度和气隙磁场所转过的角度不相等了,也就是转子所转过的步数和驱动信号走过的步数不相等了,人们常把这种现象叫做“失步”。同样的,当要使步进电机从高速的旋转中停下来的时候,如果驱动信号的变化过快,转子就有可能在惯性的作用下继续旋转超过180°,从而也产生失步。另外,由于转子轴承、传动齿轮和负载上都有一定的摩擦阻力,因此电机在连续转动时的速度也是有限的,如果驱动信号的变化速度超过了电机能达到的最大转速的话,电机也会失步。
那么,如果让驱动信号一直保持较慢的变化速度,是不是就没有问题了呢?答案当然是否定的。这是因为步进电机作为仪表的显示部件,我们要求它能够将被测信号的变化实时地显示出来;而电机转动如果比较慢,那么仪表的显示就无法跟上被测信号的变化。
为了让步进电机既不会失步,又能转得尽可能快,那么就要让驱动信号
步进电机和MCU的硬件连接
在LG32 Cluster Reference Design中,MCU和步进电机之间的连接如图4所示。其中使用了一片74ACT125作为电流放大驱动,这是因为MC9S08LG32的I/O口输出的电流最大只有10mA,而VID29步进电机需要的驱动电流最大可达20mA。使用TPM模块的两个PWM输出通道驱动步进电机两个线圈的正极,两个普通I/O口驱动两个线圈的负极。TPM模块的两个通道也可以设置成普通I/O口,这样就可以根据需要使用微步方式驱动或者分步方式驱动。
本驱动程序为应用程序提供的接口函数有三个:
1.InitStepper:初始化函数,对驱动所用到的I/O口和定时器进行设置,并让步进电机转到初始位置——使仪表的指针指到零点的位置。
函数原型:void InitStepper(void);
参数:无;
返回值:无。
2.SetStepperTarget:设定步进电机的目标位置,也就是要让仪表的指针转到哪个位置(以相对于零点的角度来表示),整个转动的过程(如需要转多少步,往哪个方向转等)应用程序无需知道,而且应用程序可以指定任意目标位置。
函数原型:void SetStepperTarget(word wTargetDegree);
参数:word wTargetDegree,目标位置相对于零点的角度,其值是以(1/12)度(等于微步方式下的步距)为单位的;
返回值:无。
3.GetStepperCurrent:得到步进电机的当前位置。
函数原型:word GetStepperCurrent(void);
参数:无;
返回值:返回仪表的指针当前所指的位置(以相对于零点的角度来表示),其值也以(1/12)度(等于微步方式下的步距)为单位。
另外,在头文件Stepper.h中定义了选择驱动方式的宏,使用者修改宏定义就可以选择分步驱动方式或微步驱动方式,如下:
#define STEPPER_PARTIAL_MODE 0
#define STEPPER_MICRO_MODE !STEPPER_PARTIAL_MODE
如前所述,驱动信号的变化速度不能太快,每次变化后都必须保持一段时间不变,为了让驱动程序占用的CPU的处理时间更少,就需要用到一个定时器。除了上面的三个接口函数外,驱动程序的其余部分都在定时器的中断服务程序中运行。
在驱动程序中,用两个静态变量来保存步进电机的目标位置和当前位置,其值是到零点的步数。定时器中断由SetStepperTarget函数使能,在中断服务程序中根据目标位置和当前位置的差值来决定步进电机转动的方向和步数,然后根据选择的驱动方式执行相应的转动程序。
使用本文给出的驱动程序,用户的应用程序和驱动程序之间的接口非常简单,所有的控制步进电机的逻辑都封装在驱动程序中,而且驱动程序占用CPU的处理时间非常少。另外,本程序根据汽车仪表应用的特点对步进电机的转动速度进行了相应的控制,所以不管输入信号变化快慢,电机输出带动的指针都能快速、平稳地转动,以让人感觉很自然的方式将输入的物理量显示出来。
参考文献:
[1]王晓明.电动机的单片机控制[M].第2版.北京航空航天大学出版社,2007
[2]孙建忠,白凤仙.特种电机及其控制[M].中国水利水电出版社,2005
[3]张俊.匠人手记[M].北京航空航天大学出版社.2008
[4]三浦宏文.机电一体化实用手册[M]. 杨晓辉,译.科学出版社.2007
[5] S.AN3828:Stepper Motor Motion Control Driver for MC9S08LG32[R/OL].Rev.0,2.(2009). http://www.freescale.com/files/microcontrollers/doc/app_note/AN3828.pdf?fsrch=1
[6]Srivastava S. AN3817: Interfacing Stepper Motor with MC9S08LG32[R/OL].Rev.1,2.(2009) .http://www.freescale.com/files/microcontrollers/doc/app_note/AN3817.pdf?fsrch=1
[7]Ramirez F.AN3602: Driving a Stepper Motor Based on the MC9S08QD4 and Other 8-bit Families[R/OL].Rev.0,4.(2008). http://www.freescale.com/files/microcontrollers/doc/app_note/AN3602.pdf