1. 引言
随着中国科技的发展,激光和激光加工作为一门高新技术,开始进入工业领域 [1] [2]。在激光控制设备中,振镜电机是激光扫描头的核心部件,振镜电机控制的优劣在一定程度上影响扫描轨迹精度。由于数字振镜具有低温漂、高分辨率、抗干扰能力强等优点,已经成为研究激光振镜扫描的主要方向,也是未来的研究方向 [3]。在对振镜电机进行闭环控制时,为取得优良的控制效果,通常需要更改控制器参数,并观察电机在运动过程中的相关数据,通过对比不同控制器参数条件下的电机运动状态,判断电机是否达到控制要求。
在目前的电机调试过程中,若想对某些参数进行调整,有三种方案:一是在程序中直接修改并重新编译,随后将程序下载进芯片中;二是通过电路板上预留的按键和显示屏进行修改;三是通过上位机对目标参数进行修改。
方案一比较直观,但对于FPGA而言,程序编译过程非常消耗时间,并非首选方式;方案二通过按键修改,并在显示屏上进行实时显示,非常直观,但限于显示屏的大小,所能显示的数据量较少,并且某些控制参数位数较长,显示到屏幕上比较麻烦;方案三通过上位机进行修改,能借助计算机显示器进行显示,并且能实时调试,不须重新编译,对于单次调整的数据量没有限制,可行性较高。
由于电机所处环境以及控制系统的限制,因此有必要加入上位机与FPGA电机控制器通信,FPGA芯片通过串口接收控制器参数进行参数调整,并通过通信程序将电机运动数据发送给上位机,上位机再将其以可视化图表的形式展现出来,从而判断控制器控制效果。本文主要介绍FPGA与上位机之间通信网络及通信协议的选择,重点论述FPGA与上位机之间的通信程序的开发实现。
2. 电机控制器系统组成
电机控制器由FPGA芯片、FLASH存储器、上位机接口电路、电机运动数据检测模块,电机驱动模块等几部分组成,硬件框图如图1所示。其中FPGA芯片接收上位机发送的理想位置,与采集到的电机实时位置进行比较,对电机进行反馈控制,本文采用串口实现电机控制器与上位机的通信。
FLASH存储模块在本设计中主要执行两项任务,第一项为作为外挂存储器参与代码编译器执行FPGA程序固化操作,存储电机控制程序代码;第二项为储存电机控制器的相关控制参数,在每次电机控制系统启动时,FPGA芯片会将FLASH存储器中存储的控制器参数值读出至RAM中,然后赋值给程序中的相关参数寄存器进行使用。当参数通过上位机进行更新后,也需要将更新的参数存储至FLASH存储器中进行永久保存 [4]。W25Q64芯片外围电路如图2所示。

Figure 1. Motor controller hardware block diagram
图1. 电机控制器硬件框图

Figure 2. Memory chip peripheral circuit diagram
图2. 存储器芯片外围电路图
3. 指令包格式
3.1. 总线的选择
在自动控制系统中,基于RS-232、RS-485总线的数据交换已经十分成熟,对于某些数据吞吐量较大的场合,还会用到数据传输速度更快的总线协议 [5] [6]。在我们电机控制系统中,电机参数较少,单次调整参数量较少,控制芯片主频较低,对信号传输距离、速率没有太高要求。所以相比于RS-485总线,RS-232总线更加方便,其硬件电路简单,所以选择RS-232总线进行数据传输 [7] [8]。RS-232物理层协议定义如表1所示。

Table 1. Physical Layer Definition of RS-232 protocol
表1. RS-232协议物理层协议定义
3.2. 指令包格式
在该设计中,上位机为电脑端串口软件,控制器参数的存储、更新、读取、显示指令以及获取电机运行数据指令都由上位机发出;下位机为FPGA电机控制器,根据所接收的上位机指令进行不同的操作。
上位机与下位机通过RS-232总线进行数据传输,RS-232总线一次最多只能传输一字节数据,而在电机控制控器中,相关参数的数据宽度一般都为四字节,在进行参数传输操作时,还需要在每个参数前加上对应的参数编码,所以发送方要将单个参数分多次传输,接收方在接收到所有参数后或在接收过程中,对分批次传输的参数进行合并处理,才能正确使用该参数,所有参数都将按照该方法进行传输。在传输电机运行数据时不需要加上编码,可直接分批次发送。
指令包由3个部分组成,其结构如表2所示。第一部分为起始码,起始码中包含起始位、调试模式和操作码,共占用5个字节,不同的操作码代表下位机将执行不同的操作,共有五种操作类型,如表3所示;不同的调试模式代表着下位机需要给上位机发送不同类型的电机运动数据。第二部分为数据场,是上位机与控制器之间发送的数据,其长度随操作码而异。第三部分是停止码,当数据或指令发送完成后,程序需通过辨别停止码进行终止操作。

Table 2. Instruction packet structure
表2. 指令包结构
数据场由参数编码和参数两部分构成,如表4所示。其中,参数编码长度为1个字节,参数长度为4个字节,控制器中每个参数都会分配一个固定的参数编码,下位机在接收到数据时,会根据编码将参数赋值给对应寄存器,可防止参数之间的错误传递。
4. 基于FPGA的指令包协议实现
4.1. 指令包协议处理函数流程图
在该系统中,FPGA作为从机,编写接收、识别并处理上位机指令包代码。指令包处理模块的流程图如图3所示。当FPGA检测到串口接收标志位被拉高时,表明通过串口传输的数据已到达,状态机开始运转。程序会根据起始位从上位机发送的数据中辨别起始码、数据场和停止码,并根据起始码进行相应操作。

Figure 3. Flow chart of packet processing module
图3. 数据包处理模块流程图
4.2. 参数写入的功能实现
参数写入操作是指FPGA将从UART处接收的参数写入RAM进行暂存。当FPGA判断此次操作为参数写入时,会将UART收发模块接收到的上位机数据输出给RAM读写控制模块。RAM读写控制模块在接收到数据时,首先对数据进行解析,提取数据地址,并根据地址将数据存入对应地址的RAM中,即可实现参数写入功能。其流程如图4所示。
4.3. 参数读取的功能实现
参数读取操作是指 FPGA将参数从 FLASH芯片读出并写入RAM存储器进行暂存。当从机接收到参数读取指令时,会对FLASH芯片进行读数据操作,并将读出的数据输出给RAM读写控制模块。RAM读写控制模块在接收到数据时,先提取该数据的地址,再根据地址将数据写入RAM对应地址中,由于RAM存储速度比FLASH芯片的读取速度快,所以无需进行读等待或者缓冲操作。参数读取功能流程如图5所示。

Figure 4. Parameter write function flow chart
图4. 参数写入功能实现流程图

Figure 5. Parameter reading function flow chart
图5. 参数读取功能实现流程图
4.4. 参数存储的功能实现
参数存储操作是指将RAM存储器中的参数写入FLASH芯片进行永久存储。由于被控对象在调试过程中可能会多次更改参数,以观察不同参数带来的效果,并且由于FPGA内部没有非易失性存储器,所以要想保存本次操作数据,就必须将数据存入FLASH芯片中,以免系统掉电后被擦除。
当从机接收到参数读取指令时,会对片内RAM存储器进行读数据操作,并将读出的数据输出给FLASH读写控制模块。由于RAM读取速度快于FLASH芯片的写入速度,所以RAM需要等待FLASH读写控制模块发出读取指令才会进行下一次读取操作。参数存储功能流程如图6所示。

Figure 6. Parameter storage function implementation flow chart
图6. 参数存储功能实现流程图
4.5. 参数显示的功能实现
参数显示操作是指FPGA将参数从RAM读出并通过UART发送给上位机进行显示。当从机接收到参数显示指令时,会对片内RAM存储器进行读数据操作,并将读出的数据输出给UART收发模块。由于波特率设置不同,UART收发模块发送一个参数所消耗的时间不同,所以RAM需要等待UART收发模块发送完一个数据才会进行下一次读取操作。参数显示功能流程如图7所示。
4.6. 电机数据上传的功能实现
电机数据上传是指FPGA将电机的运行状态数据通过UART发往上位机进行显示,通过将电机运行数据以可视化图表来展现,判断电机调试效果优劣。而且在获取电机运行数据后,还可以对电机数据做更多分析,从多维度对电机的运行状态做出判断与评价。

Figure 7. Parameter display function flow chart
图7. 参数显示功能实现流程图
由于电机运行速度快,远大于UART传输速度,所以在获取电机运行速度时,需要先将电机数据传递给FIFO进行缓冲,等到数据缓冲完毕,再将FIFO中的数据一个个通过UART发往上位机 [9]。电机数据上传功能流程如图8所示。

Figure 8. Motor data upload function flow chart
图8. 电机数据上传功能实现流程图
5. FPGA利用指令包实现对设备的控制
程序会根据起始位从上位机发送的数据中辨别起始码、数据场和停止码,并根据起始码进行相应操作。振镜电机控制装置采用RS-232总线与电脑上位机进行通信,将上位机作为主机,电机控制器的FPGA芯片作为通信从机,两者之间通过RS-232协议传递指令包,从机通过对指令包进行解析,做出相应动作,从而实现主机对从机的控制。
5.1. FPGA指令包协议控制设备处理函数
FPGA在接收到上位机传下来的数据后,需要先提取本次指令包中的操作码,根据操作码判断此次进行何种操作。由于上位机根据波特率定时向下发送数据,所以下位机在接收到第一个数据后,距离第二个数据的到来仍有一段时间,而这段空闲时间足够FPGA对接收到的数据进行解析,从中确定起始位、调试模式和操作码。
本文定义操作码寄存器为:cmd_type[8:0]. FPGA在接收到上位机传输的数据后,执行的操作码提取函数如下:
always@(posedge clk_20m or negedge rst_n) // 时钟高电平
begin // 程序开始
if(rst_n == 1'b0) // 判断是否复位
cmd_type <= 8'h00; // 操作码赋初值
else if(rx_flag_buf && (rx_data_buf[39:32] == 8'h00)) // 判断是否为起始位
cmd_type <= rx_data_buf[7:0]; // 提取操作码
else if(reset !== 3'b000 || uart_ctrl_done ) // 指令执行结束,操作码置位
cmd_type <= 8'h00; // 操作码赋初值
else // 以上皆不符合判断
cmd_type <= cmd_type; // 保持操作码
end // 程序结束
5.2. 上位机发送指令实现对设备的控制和信息的采集
上位机发送参数的写入、读取、存储和显示指令,FPGA接收指令后,或将上位机向下传输的数据进行暂存或永久存入FLASH芯片,或将FLASH芯片中的数据发往上位机进行显示。上位机发送获取电机运行状态指令,当FPGA收到指令后采集电机当下一段时间内的运行数据,然后传输给上位机软件进行显示。
6. 实验结果与分析
本实验测试平台为数字振镜控制实验板,采用的控制主板的控制主芯片型号为XilinxSpartan-6 xc6slx45,实验平台照片如图9所示。
在ISE14.7软件环境下,给FPGA芯片发送电机控制器控制命令,通过ChipScope逻辑分析仪在线抓取寄存器值,操作码寄存器赋值过程如图10所示。接收到上位机发下来的数据后,程序在判断为数据起始位时,随即对操作码进行了赋值。该过程消耗时间短,不影响后续数据的正常处理,保证了后续数据到来时,能够通过操作码进行数据流向的选择或进行数据处理,表明通过上位机指令包进行设备控制的可行性及高灵活性。

Figure 10. Operation code register assignment procedure
图10. 操作码寄存器赋值过程
如果此次操作是执行参数写入功能,在操作码赋值过程结束后,FPGA会根据所得操作码对后续参数进行暂存处理。如图11所示为部分参数传输过程示意图。由于后续参数是依次传输给FPGA的,按照理论,参数处理量上限为无穷大,但限于FPGA片内寄存器大小以及外挂存储器容量,参数存储存在上限,但相比其他参数调整方案,已经具有了极大优势。如果此次操作为电机状态上传功能,与参数写入功能相似,只需通过上位机发送对应命令,就能通过状态机将FIFO中缓冲的参数通过串口依次发送给上位机,操作灵活方便。

Figure 11. Parameter transmission process diagram
图11. 参数传输过程示意图
7. 结论
本文通过在FPGA芯片上运行从机通信程序,以电脑上位机软件作为主机,通过上位机发送指令对电机控制系统进行远程控制和电机运行状态信息的采集。经过产品开发研究与测试,验证了基于RS-232通信网络传输自定义数据包实现上位机和FPGA通信的可行性,并在项目中进行了实际应用,达到了预期的效果。