在HCS08系列MCU上用软件实现仪表步进电机的驱动
时间:11-30
来源:互联网
点击:
转动速度控制
由于被测量的输入信号的变化是随机的,有时快有时慢,为了让仪表实时、直观地显示出输入信号的变化,驱动程序就必须对步进电机的转动速度进行适当的控制。可以说,一个汽车仪表做得好不好,很大程度上就看它对步进电机的转动控制得好不好。
通常,仪表对输入信号进行周期性的定时测量,因此对步进电机目标位置(指针位置)的设定也是每隔一段时间进行一次的。在程序中给这个间隔时间定义了一个宏,放在Stepper.h头文件中,以便根据应用程序的需要作修改,宏定义如下:
#define STEPPER_UPDATE_INTERVAL 256 //单位:毫秒,必须在(8,512)内
这里把指针位置的更新间隔时间限定在8到512毫秒之间是因为:
1. 仪表是用来给人看的,而人眼并不能看清变化非常快的东西,所以对指针位置更新得太快就没有实际意义,徒然增加CPU的处理负担而已。
2. 如下文将要提到的,本程序使用的定时器所能达到的最大中断间隔时间为512毫秒,为了简化定时器的中断服务程序,减小CPU的负荷,所以限定指针位置的更新间隔时间不要超过512毫秒。
为了让仪表的指针摆动得更加平稳、自然,最好能让电机在下一次设定目标位置前的那一刻刚好转动到本次设定的目标位置。为此就要计算出电机在这一段时间里的平均旋转速度,也就是每个分步或微步的平均间隔时间。当所需的平均速度较大时,如前所述,还需要对电机进行加减速的控制。
为了实现步进电机的转动速度控制,在定时器的每次中断里只让电机转动一个分步/微步,然后用一定的算法计算出这一步到下一步之间应当间隔的时间,以重新设置定时器的溢出时间。在本驱动程序中,定时器选用的是TPM2模块的通道0,对其相关的寄存器的设置说明如下:
初始化:
SCGC1_TPM2 = 1; //使能TPM2模块的时钟
TPM2MOD = 0; //设置TPM2的计数器为自由运行模式
TPM2SC = 0x0F; //选择总线时钟为时钟源,预分频系数为128
把预分频系数设置为128是为了让定时器的溢出时间能够尽可能大,减少中断对CPU造
成的负担。当总线时钟频率为16MHz时,此定时器能达到的最大中断间隔时间是512毫秒。
启动定时器:
TPM2C0V = TPM2CNT + 2;
TPM2C0SC = 0x50;
设置通道0为输出比较模式,比较一致时产生中断,但比较结果不输出到管脚上(相关管脚仍然由GPIO控制)。因为启动定时器时步进电机还没有开始转动,所以给比较值寄存器(TPM2C0V)设置的值是计数器(TPM2CNT)当前的值加2,即让它尽快地产生一次中断。然后在每次中断产生后,在中断服务程序里让步进电机转动一步,并给TPM2C0V设置一个新的值,即根据所需的间隔时间给TPM2C0V增加一定的数值。
为了对步进电机进行加减速控制,我们需要知道它启动时第一步所需的间隔时间和最大转速时每一步所需的间隔时间。步进电机启动时第一步所需的间隔时间的最小值(Tss)可以由下面的公式计算得到:
式中,d是步距,即每走一步输出轴转过的角度;fss是启动频率,即启动时允许的输出轴的最大转速,单位是(度/秒)。
从VID29系列步进电机的数据手册上可以查到,fss等于125(度/秒),在分步方式下d等于(1/3)度。代入上式,可以算出Tss等于(1/375)秒,约等于2667微秒。
在程序中定义MAX_PARTIAL_STEP_TIME为400,当在中断服务程序里把TPM2C0V的值增加400后,下一次比较中断产生的时间和本次中断之间的间隔就为3200微秒,大于Tss且还有一定的裕量。
步进电机达到最大转速时每一步所需的间隔时间(Tmm),计算公式如下:
式中,d仍是步距,fmm是最大驱动频率,即连续旋转时输出轴的最大转速,单位是(度/秒)。
从VID29系列步进电机的数据手册上查到fmm等于600(度/秒),算出Tmm约等于556微秒。在程序中定义MIN_PARTIAL_STEP_TIME为80,对应的间隔时间为640微秒,同样是大于Tmm且有一定的裕量。
对于微步方式,由于我们把每个分步细分成4个微步,所以相应的Tss和Tmm都是分步方式时的四分之一。
在程序中,设定步进电机的目标位置SetStepperTarget函数里根据目标位置与当前位置的差(wDiff) 计算出需要的平均转速, 也就是每一步的平均间隔时间(wAverageStepTime),根据平均间隔时间设置TPM2C0V的增量(wTimerIncrement),并启动定时器。在定时器的中断服务程序中驱动电机一步一步地向目标位置转动,当步进电机转动到目标位置后,让定时器停止工作。
另外,考虑到输入信号变化很快时,电机的转动速度可能跟不上信号的变化,从而在下一次测量完输入信号,对步进电机的目标位置再次进行设定时,电机还正在转动之中。这时,电机的转动速度有可能很快,在这种情况下如果重新启动定时器则有可能造成失步,因此SetStepperTarget程序根据电机当前的状态进行了分别的处理,其流程如图12所示。
在定时器的中断服务程序中,首先判断bBrakeFlag标志,如果不是0,则表示当前转动方向跟目标位置不一致,需要先减速到停止,然后再反向转动。当bBrakeFlag为0时,根据平均间隔时间决定何时让电机转动一个分步/微步,以及是否需要进行加减速。当平均间隔时间大于Tss时,电机每隔一个平均间隔时间转动一步,作匀速转动。而当平均间隔时间小于Tss时,则让电机第一步的间隔时间为Tss,然后逐渐减小,即做加速转动,直到达到需要的平均转速或电机允许的最高转速;到接近目标位置时,则让每一步的间隔时间逐渐加长,电机减速转动,并且使最后一步的间隔时间不小于Tss,以保证不会失步。
定时器中断服务程序的流程如图13所示。
由于被测量的输入信号的变化是随机的,有时快有时慢,为了让仪表实时、直观地显示出输入信号的变化,驱动程序就必须对步进电机的转动速度进行适当的控制。可以说,一个汽车仪表做得好不好,很大程度上就看它对步进电机的转动控制得好不好。
通常,仪表对输入信号进行周期性的定时测量,因此对步进电机目标位置(指针位置)的设定也是每隔一段时间进行一次的。在程序中给这个间隔时间定义了一个宏,放在Stepper.h头文件中,以便根据应用程序的需要作修改,宏定义如下:
#define STEPPER_UPDATE_INTERVAL 256 //单位:毫秒,必须在(8,512)内
这里把指针位置的更新间隔时间限定在8到512毫秒之间是因为:
1. 仪表是用来给人看的,而人眼并不能看清变化非常快的东西,所以对指针位置更新得太快就没有实际意义,徒然增加CPU的处理负担而已。
2. 如下文将要提到的,本程序使用的定时器所能达到的最大中断间隔时间为512毫秒,为了简化定时器的中断服务程序,减小CPU的负荷,所以限定指针位置的更新间隔时间不要超过512毫秒。
为了让仪表的指针摆动得更加平稳、自然,最好能让电机在下一次设定目标位置前的那一刻刚好转动到本次设定的目标位置。为此就要计算出电机在这一段时间里的平均旋转速度,也就是每个分步或微步的平均间隔时间。当所需的平均速度较大时,如前所述,还需要对电机进行加减速的控制。
为了实现步进电机的转动速度控制,在定时器的每次中断里只让电机转动一个分步/微步,然后用一定的算法计算出这一步到下一步之间应当间隔的时间,以重新设置定时器的溢出时间。在本驱动程序中,定时器选用的是TPM2模块的通道0,对其相关的寄存器的设置说明如下:
初始化:
SCGC1_TPM2 = 1; //使能TPM2模块的时钟
TPM2MOD = 0; //设置TPM2的计数器为自由运行模式
TPM2SC = 0x0F; //选择总线时钟为时钟源,预分频系数为128
把预分频系数设置为128是为了让定时器的溢出时间能够尽可能大,减少中断对CPU造
成的负担。当总线时钟频率为16MHz时,此定时器能达到的最大中断间隔时间是512毫秒。
启动定时器:
TPM2C0V = TPM2CNT + 2;
TPM2C0SC = 0x50;
设置通道0为输出比较模式,比较一致时产生中断,但比较结果不输出到管脚上(相关管脚仍然由GPIO控制)。因为启动定时器时步进电机还没有开始转动,所以给比较值寄存器(TPM2C0V)设置的值是计数器(TPM2CNT)当前的值加2,即让它尽快地产生一次中断。然后在每次中断产生后,在中断服务程序里让步进电机转动一步,并给TPM2C0V设置一个新的值,即根据所需的间隔时间给TPM2C0V增加一定的数值。
为了对步进电机进行加减速控制,我们需要知道它启动时第一步所需的间隔时间和最大转速时每一步所需的间隔时间。步进电机启动时第一步所需的间隔时间的最小值(Tss)可以由下面的公式计算得到:
式中,d是步距,即每走一步输出轴转过的角度;fss是启动频率,即启动时允许的输出轴的最大转速,单位是(度/秒)。
从VID29系列步进电机的数据手册上可以查到,fss等于125(度/秒),在分步方式下d等于(1/3)度。代入上式,可以算出Tss等于(1/375)秒,约等于2667微秒。
在程序中定义MAX_PARTIAL_STEP_TIME为400,当在中断服务程序里把TPM2C0V的值增加400后,下一次比较中断产生的时间和本次中断之间的间隔就为3200微秒,大于Tss且还有一定的裕量。
步进电机达到最大转速时每一步所需的间隔时间(Tmm),计算公式如下:
式中,d仍是步距,fmm是最大驱动频率,即连续旋转时输出轴的最大转速,单位是(度/秒)。
从VID29系列步进电机的数据手册上查到fmm等于600(度/秒),算出Tmm约等于556微秒。在程序中定义MIN_PARTIAL_STEP_TIME为80,对应的间隔时间为640微秒,同样是大于Tmm且有一定的裕量。
对于微步方式,由于我们把每个分步细分成4个微步,所以相应的Tss和Tmm都是分步方式时的四分之一。
在程序中,设定步进电机的目标位置SetStepperTarget函数里根据目标位置与当前位置的差(wDiff) 计算出需要的平均转速, 也就是每一步的平均间隔时间(wAverageStepTime),根据平均间隔时间设置TPM2C0V的增量(wTimerIncrement),并启动定时器。在定时器的中断服务程序中驱动电机一步一步地向目标位置转动,当步进电机转动到目标位置后,让定时器停止工作。
另外,考虑到输入信号变化很快时,电机的转动速度可能跟不上信号的变化,从而在下一次测量完输入信号,对步进电机的目标位置再次进行设定时,电机还正在转动之中。这时,电机的转动速度有可能很快,在这种情况下如果重新启动定时器则有可能造成失步,因此SetStepperTarget程序根据电机当前的状态进行了分别的处理,其流程如图12所示。
在定时器的中断服务程序中,首先判断bBrakeFlag标志,如果不是0,则表示当前转动方向跟目标位置不一致,需要先减速到停止,然后再反向转动。当bBrakeFlag为0时,根据平均间隔时间决定何时让电机转动一个分步/微步,以及是否需要进行加减速。当平均间隔时间大于Tss时,电机每隔一个平均间隔时间转动一步,作匀速转动。而当平均间隔时间小于Tss时,则让电机第一步的间隔时间为Tss,然后逐渐减小,即做加速转动,直到达到需要的平均转速或电机允许的最高转速;到接近目标位置时,则让每一步的间隔时间逐渐加长,电机减速转动,并且使最后一步的间隔时间不小于Tss,以保证不会失步。
定时器中断服务程序的流程如图13所示。
步进电机 电路 MCU Freescale 电流 电压 PWM 电阻 传感器 ADC 电感 总线 相关文章:
- 单芯片集成电路优化自适应转向大灯系统设计(07-03)
- 汽车仪表步进电机控制算法的仿真(02-15)
- 灵活的现代CPLD汽车数字仪表板(06-04)
- 基于步进电机控制技术的汽车辅助照明随动系统设计(01-25)
- 基于步进电机驱动器MC33991的车速表设计(11-14)
- 基于CAN总线的一体化步进电机驱动器的设计与实现(11-25)