张付祥,刘振宇
ZHANG Fu-xiang,LIU Zhen-yu
(河北科技大学 机械电子工程学院,石家庄 050018)
机电一体化系统中有很多情况需要对多台电机进行控制[1],步进电机控制系统一般基于单片机或者是PC机,由于资源的限制很难实现复杂的步进控制[2]。传统上基于PC机的步进电机控制系统的核心是步进电机控制卡,很难实现多通道步进电机的驱动控制[3],实现多轴控制则需PMAC卡等[4]多轴运动控制卡,但控制系统实现成本较高。能够实现多通道步进电机驱动的控制器控制可靠,且能够方便的通过现场总线组建大型的控制系统[5]。
1.1 多通道步进电机控制器原理
多电机控制器针对接受脉冲信号控制的步进电机,与微处理器采用SPI总线的方式传送数据,通常可以搭建成图1所示的多通道步进电机控制系统。
系统工作时,具有SPI的微处理器通过其I/O口片选FPGA,多电机控制器处于工作状态。微处理器通过SPI向FPGA发送电机控制指令,FPGA根据控制指令产生电机方向控制的电平信号和电机速度控制的脉冲信号。控制信号通过FPGA的输出端口发送到相应的步进电机驱动器,从而完成对多个电机的控制。这里以一片EPF10K10A实现对8个步进电机的控制为例介绍多电机控制器设计及驱动的实现方法。
1.2 FPGA的硬件线路
基于FPGA的电机控制器的硬件建立后,需要对FPGA的管脚进行定义。除去FPGA和系统相关的管脚,需要定义和电机控制有关的管脚。其中f0~f7为可控脉冲频率输出,实现电机的速度控制;dir0~dir7为电机方向输出,实现电机的方向控制;MOSI为SPI接口主设备对从设备的数据输入;SCLK为SPI接口的时钟输入;F2M为外部有源晶振提供的频率为2MHz的输入脉冲;CS为片选输入。
1.3 多通道步进电机控制器设计
使用VerilogHDL语言,采用自顶向下的设计方法,从系统级开始,把系统划分为两个基本的单元,最顶层模块为SPI_Motor,SPI_Motor模块根据功能再进一步细化为SPI_Core模块和Counter模块,系统构成如图2所示。
系统上电FPGA进行部分初始化,在得到片选信号时,SPI_Core模块开始接收数据,SPI口一次传送一个字节的数据,SPI_Core模块每接收到一个字节的数据就进行一次串并转换,电机的控制信号是由两个字节所组成的,需要在数据转化过程中进行判断一条命令是否转换完毕,如果转换完毕,则通知Counter模块进行数据接收。Counter模块在系统上电后开始工作,根据寄存器的初始值进行工作,当接收到转化后的控制命令时,根据控制命令中所包含的地址信息把数据传送到相应的寄存器中。方向寄存器中的每一位都有一个输出,直接跟电机驱动板上的方向端相连,方向寄存器的变化会直接导致相应电机的转向变化。电机使能寄存器和分频计数器相互配合工作,当电机使能寄存器设定工作电机时,相应的电机分频计数器才会工作,分频计数器在没有得到允许工作的命令之前进行初始化,得到命令后则根据计数器中的分频值进行分频。
图2 电机控制系统模块构成图
Counter模块的功能是控制8个电机在给定的方向以一定的速度转动,由8个定时器,一个译码器和一个可控分频器组成。方向控制通过内部寄存器Dir实现。可控分频器的分频系数寄存器为9位,初始值为1_0100_1101,对2MHz进行668分频,得到定时器寄存器的基准时钟2994HZ。定时器寄存器为12位,其存储的最小值规定为0000_0000_0000,最大值为1111_1111_1111,如果输入频率为2994Hz,则输出的最大频率为1497Hz,最小为0.36Hz。并且对每个定时器都有一个使能控制位,从而实现电机转动的启动与停止。
Counter模块可输出电机控制频率为:
式中 n1——分频系数;
n2——定时器寄存器的数值。
系统中电机驱动器的最大输入脉冲频率取1500Hz,因此n1在0-324之间变化,n2在315-4095之间变化。
SPI_Core模块由一个串并转换任务和数据传输控制器组成。SPI_Core模块接收MOSI上的数据,进行串并转换,并将转换后的数据传送给Counter模块。串并转换任务采用有限状态机来实现,它将MOSI端口输入的串行数据转化成并行数据。状态编码采用的是独热编码,数据传输控制器实现对给定的寄存器传输数据,其中ADD_ Encode实现数据传输对象的编码,其具体编码如表1所示。
表1 内部寄存器编码表
2.1 SPI总线的驱动
以S3C2410微处理器为例介绍SPI总线的驱动方法,SPI模块初始化的过程为:
1)通过SPI波特率寄存器(SPPREn)设置SPI总线的波特率;
2)设置SPI控制寄存器(SPCONn)选择合适的SPI模式;
3)通过往SPI数据寄存器(SPTDATn)中写10次0xFF来初始化挂载在SPI总线上的设备;
4)设置GPIO引脚,当引脚低电平时片选挂载在SPI总线上的相应设备。
驱动程序中用到的SPI寄存器有rSPCON0、rSPSTA0、rSPPIN0、rSPPRE0、rSPTDAT0和rSPRDAT0,端口寄存器有rGPECON、rGPEUP、rGPGCON、rGPGUP和rGPGDAT。SPI总线的驱动由初始化函数Init_SPI()实现,采用伪码编写函数如下:
Set rSPPRE0
Set SPCON0
For i=1 TO 10
Set rSPTDAT0,0xff
Set rGPECON
Set rGPEUP
Set rGPHCON
Set rGPHUP
SPI总线传输数据采用轮询方式,轮询函数spi_poll_done()的伪码如下:
while do
rSPSTA0&0x01
SPI总线的数据传输函数spi_tx_date()的伪码如下:
spi_poll_done();
Set rSPTDAT0,data
spi_poll_done();
2.2 FPGA的驱动
系统采用1个FPGA完成8个电机速度控制,通过motor_data_send()函数完成,其实现伪码如下:
Set rGPHDAT,CS
For i=0 TO 1
spi_tx_data(TXdata[i])
Set rGPHDAT,unCS
FPGA的驱动程序模块运行时对FPGA的状态进行初始化,以保证电机不会误动作,其函数为Init_Motor()的伪码如下:
FPGA的设备文件结构中的系统调用方法包括write、open和realease,FPGA的系统调用方法缺少read方法,其中write方法motor_wr()实现的伪码如下:
Set dbuf,kmalloc(sizeof(unsigned char),GFP_ KERNEL)
copy_from_user(buf,dbuf,1)
Set ADnTXdata[0],dbuf[0]
kfree(dbuf)
open方法motor_open()和close方法motor_ close()为空函数,FPGA的设备驱动程序卸载函数motor_exit()的实现方法和一般的字符设备的实现方法一样。FPGA的设备驱动程序加载函数motor_ init()比一般字符设备的加载函数要多一个电机的初始化,由函数Init_Motor()完成。
为了开发应用程序,使用Linux C语言开发了多通道步进电机控制用的API函数MotorGoto(),其伪码如下:
Set fd,open("/dev/motor",O_RDWR)
Set Start[0],0
Set Start[1],Tenable
write(fd,Start,2)
Set Dir[0],0x10
Set Dir[1],Dir
write(fd,Dir,2)
Convert n and f to H and L
Set Out[0],H
Set Out[1],L
write(fd,Out,2)
write(fd,Start,2)
close(fd)
电机控制器实验中,设定可控分频寄存器对外部2MHz的输入脉冲进行2分频作为内部8个定时器的基准脉冲,通过改变n2的值从而改变电机控制器的输出频率。对8个步进电机进行控制,电机控制器的输出频率从150Hz开始按50Hz递增一直增至1500Hz。实验结果8个电机控制器的输出频率曲线基本重合在一起,电机控制器的频率输出端口具有良好的一致性,说明电机控制器具有很好的精确性和可靠性。
用FPGA开发具有SPI接口的多通道步进电机控制器占用较少的微处理器I/O资源,硬件联接简单、软件易于实现,程序运行效率高,可广泛应用于需要对多个步进电机进行控制的场合,可广泛应用于机器人、数控机床及其它嵌入式的系统。
[1]许瑞华,何俊华基于NextMoveES运动控制卡的步进电机群控系统[J].微计算机信息,2006,22(1-2):9-10.
[2]黄赞,姚耀文.步进电机伺服系统设计与可视化仿真的实现[J].组合机床与自动化加工技术,2005,30(3):59-62.
[3]赵勇.基于Ethernet的多通道步进电机控制系统[J].电力系统自动化,2005,25(10):71-73.
[4]李淑萍,张筱云.基于PMAC的开放式数控系统研究[J].微电机,2009,42(7):65-68.
[5]王改华,王江卫,刘楚湘,等.基于DeviceNet现场总线的电机控制系统设计[J].工业控制计算机,2008,(10):94-96.