1 引言
随着Profibus总线技术在我国的进一步普及,基于Profibus-DP协议的总线产品在市场上占据了越来越多的份额。自行开发含DP接口的从站产品具有重要的现实意义,国内参与DP总线产品研究与开发的单位很多,然而能够自成体系的却鲜见报道。究其原因,主要是在开发过程中几个核心问题没有很好地解决。这些问题主要集中在对Profibus-DP中断机制的理解、SPC3固态程序的剖析、GSD文件的编制以及Profibus-DP网络的组态几个方面,本文将就这几个问题逐一进行讨论。
2 Profibus-DP的中断机制
2.1 中断机制
Profibus-DP协议中的中断控制是通过协议芯片SPC3内的中断控制器来实现的,当有指令报文到来或各种错误事件发生时,CPU会得到通知并进行相应的处理。该中断控制器可以管理预定义的16种中断事件,这些事件通过一个中断输出进行统一管理。该中断控制器不具备中断优先级,也不提供中断矢量。中断控制器内主要有4个寄存器:中断请求寄存器IRR(Interrupt Request Register),中断屏蔽寄存器 IMR(Interrupt Mask Register),中断寄存器IR(Interrupt Register)和中断确认寄存器 IAR(Interrupt Acknowledge Register)。该中断控制器内部的工作原理示意如图1。
所有等待处理的中断都存储在IRR寄存器内,个别的中断可以通过设置IMR寄存器来禁止。IRR寄存器的输入不受中断屏蔽的影响,未屏蔽的中断信号经过求和运算来触发X/INT中断。在调试DP从站时,可以在IRR寄存器种设置各种中断信号来进行调试。所有经微处理器处理的中断只能通过IAR寄存器删除,相应地,需要将相应的位置“1”。如果一个新的中断事件与先前的一个中断事件同时加在IRR寄存器的输入端,该新事件将被保持。如果处理器随后使能一个屏蔽的中断,它必须保证之前没有中断信号加在IRR寄存器的输入端。为了安全起见,在使能中断屏蔽前必须删除IRR寄存器中的相应位。
图1 Profibus-DP中断机制
2.2 中断相应
虽然在开发DP产品时无需对Profibus-DP的中断机制进行修改,但深入了解该中断机制对于剖析SPC3的固态程序具有重要的意义,因为该固态程序的框架就是基于Profibus-DP协议所定义的中断机制。在实际运行过程中,DP从站内的微处理器主要对协议芯片SPC3的以下几类中断事件做出响应。
(1) Diag_Fetched:诊断数据被主站取走,此时MCU应发出一个User_Diag_Read_Cmd命令(通过读RAM中的 User_Diag_Read_Cmd单元实现),将用户诊断缓冲器与MAC缓冲器互换,以将更新的用户诊断数据提供给MAC层,供主站在必要时取用;
(2) IndQ_Entry:新的事件信息进入指示队列,在中断处理时MCU应从指示队列中读出事件信息代码,根据不同的事件做出反应。比如发生监视定时器到时事件,就将程序从数据交换状态跳出,停止输入数据的发送;
(3) Go/Leave_Data_Exchange:进入或离开数据交换状态。此时MCU应读取SPC3的状态寄存器,得知具体是进入还是离开。若是进入数据交换状态,应当准备输入数据以便向主站发送;若是离开则停止输入数据的发送;
(4) New_Prm_Data:新的参数报文。MCU从用户参数缓冲器中读出参数数据, 然后对从站需要设置的参数进行设置,根据设置的结果是否正确向SPC3发出一个肯定的User_Prm_OK_Cmd或一个否定的User_Prm_Not_OK_Cmd命令,SPC3便会对此参数报文向主站作出肯定或否定的应答;
(5) New_Cfg_Data:新的组态报文。MCU从用户组态缓冲器中读出组态数据,然后根据组态信息设置从站,根据组态的结果是否正确向 SPC3发出一个肯定的User_Cfg_OK_Cmd或一个否定的User_Cfg_ Not_OK_Cmd命令,SPC3便会对此组态报文向主站作出肯定或否定的应答;
(6) Get_Cfg_Buffer_Change:读组态缓冲器改变,即用户读组态缓冲器与MAC读缓冲器互换。在中断处理时MCU应通过读 User_Cfg_Buffer_Ptr得到新的用户读组态缓冲器的指针,以将从站的组态信息写入新的用户读组态缓冲器中。此中断由 User_Get_Cfg_Read_Cmd命令对主站组态报文的User_Cfg_OK_Cmd肯定引起;
(7) Diag_Buffer_Changed:诊断缓冲器改变,即用户诊断缓冲器与MAC诊断缓冲器互换。在中断处理中MCU应通过读 User_Diag_Buffer_Ptr得到新的用户诊断缓冲器的指针,以将从站的诊断信息写入新的用户诊断缓冲器中,此中断由 User_Diag_Read_Cmd命令引起;
(8) DX_OUT:新的输出数据。此时应发出一个User_New_Dout_Cmd命令,并得到新的U缓冲器的指针,从而用户可以根据这个指针得到存入其中的新的输出数据,同时MCU应发出一个User_New_Din_Cmd,将U输入数据缓冲器变为N输入数据缓冲器,同时得到新的U缓冲器的指针,这样便将用户的输入数据发送给主站,并得到新的U缓冲器以准备新的输入数据。
所有的中断事件协调组合在一起,就构成了Profibus-DP的状态机,该状态机模型如图2:
图2 Profibus-DP状态机模型
3 SPC3固态程序的剖析
使用西门子公司提供的协议芯片SPC3可以较容易地设计Profibus-DP从站的硬件电路,相对而言从站的软件设计要相对复杂,而软件设计的关键是利用开发包中提供的SPC3协议芯片固态程序,因此解析该固态程序是另一个需要关注的问题。
3.1 SPC3固态程序流程
由于SPC3芯片内的寄存器是完全格式化的,固态程序可实现在SPC3内部寄存器与应用接口之间的连接,为用户提供了宏接口,使用固态程序可大大节省用户的开发的时间。SPC3固态程序包使得用户无须直接操作寄存器和计算存储空间。固态程序中包含的各程序模块有:
(1) 主程序SERSPC3.C,主要完成SPC3初始化,启动,外部信号处理,发送和接收数据和诊断;
(2) 中断模块INTSPC3.C,主要处理分配从站参数、组态数据检查和从站地址设定;
(3) 函数DPS2SPC3.C,这些函数根据组态数据计算输入输出数据长度,辅助缓冲区分配,缓冲区初始化,设置IO数据长度,各缓冲区更新函数等;
(4) 变量定义和宏接口DPS2USER.h,宏接口使用户能够方便地访问SPC3的各个寄存器。
SPC3在接收到由Profibus-DP主站传送的不同输出数据时,会产生输出标志位(位于中断请求字单元),CPU通过在应用循环中查询标志位来接收主站数据,对于实时性要求严格的系统,则应采用中断方式进行输出数据的处理。主程序首先利用开发包中的DPS2对SPC3进行初始化,允许外部中断INT0,设置INT0为高优先级及开中断,然后启动SPC3,通过SPC3进行主站和从站的数据交换以及处理诊断。SPC3固态程序的流程示意如图 3:
图3 SPC3固态程序流程图
3.2 SPC3初始化子程序
在SPC3正常工作之前,首先需要进行初始化,以配置需要的寄存器,包括设置协议芯片的中断允许,写入从站识别号和地址,设置SPC3方式寄存器,设置诊断缓冲区,参数缓冲区,配置缓冲区,地址缓冲区,初始化长度,并根据以上初始值得出各个缓冲区的指针和辅助缓冲区的指针。根据传输的数据长度,确定输出缓冲区,输入缓冲区及指针。
初始化程序用以实现以下各项功能:
(1) SPC3硬件复位:应用程序用RESET复位SPC3,初始化内部RAM及复位微处理器;
(2) 编译器设置:针对选用的微处理器选用合适的编译器,用#define DPS2_SPC3激活DPS2接口;
(3) 设置SPC3中断屏蔽寄存器:宏DPS2_SET_IND( )激活SPC3中断触发,包括从站地址改变,组态数据检查,参数检查中断;
(4) SPC3内部看门狗设置:用户看门狗用于确保在微处理器出现故障时,SPC3能在DPS2_SET_USER_WD_VALUE(X)设定的时间内进行数据通信后,时间完后则离开数据交换通信状态,只要微处理器没有问题,则需不断地用DPS2_RESET_USER_WD重新触发看门狗电路;
(5) 设备标识码设置:在启动过程中,应用程序读取标识码,并将其传送到SPC3芯片中;
(6) 设置响应时间:如果某些应用需要,用户可以通过DPS2_SET_MINTSDR(X)为SPC3设置最小的从站响应时间;
(7) 缓冲区初始化设置:用户必须确定DPS2_BUFINIT结构体中定义的各个用于信息交换的缓冲区的长度,这些缓冲区长度决定了SPC3 中各个数据缓冲区的长度,这些缓冲区占用SPC3双口RAM的空间,因此不能超过缓冲区总长度。用宏SPC3_INIT( )或 Dps2_buf_init( )函数将DPS2_BUFINIT初始化后的结构体指针作为参数,根据结构体中的数据在SPC3的RAM中分配各缓冲区,检查各个缓冲区的最大长度,并返回缓冲区初始化后的测试信息;
(8) 波特率控制设置:用DPS2_SET_BAUD_CNTRL( )宏,可以设置波特率控制模式。在此监视定时值过后,如果没有有效的信息被接收,SPC3将启动波特率搜索BAUT RATE RESEARCH功能。如果定时监视器被启用,且DP从站检查到DP主站有故障,则本地输出数据被删除或进入规定的安全状态。监视定时器的时基为10ms,其时间范围为10ms~650s。
3.3 接收主站输出数据子程序
Profibus-DP主站和SPC3通过默认的服务访问点交换数据,在此过程中SPC3需要完成的任务主要包括以下3步:
(1) SPC3将输出数据写入D缓冲区中,且交换D和N缓冲区中的数据;
(2) 产生DX-Out中断;
(3) 用户通过交换N和U缓冲区中的数据,从U缓冲区中获取输出数据。
第1步由SPC3自动完成,用DPS2_POLL_IND_ DX_OUT( )读SPC3的中断请求寄存器查询中断事件。当为真时,表示 SPC3接收到Write_Read_Data报文,并使N缓冲区中的输出数据有效。用宏DPS2_OUTPUT_UPDATE( )更新输出缓冲区,即将N缓冲区中的数据送到U缓冲区中。输出数据中并不包括输出数据的长度,但必须和DPS2_SET_IO_DATA_LEN( )定义的数据长度一致,当长度不一致时,从站将会返回到等待参数赋值状态,输出数据缓冲区的长度在初始化部分程序中。
该部分程序核心代码如下:
if (DPS2_POLL_IND_DX_OUT( ))
{ DPS2_CON_IND_DX_OUT( );
user_output_buffer_ptr = DPS2_OUTPUT_UPDATE( );
for (i=0; i<user_io_data_len_ptr->outp_data_len; i++)
{
(*((io_byte_ptr)+i))=(*(((UBYTE SPC3_PTR_ATTR*) user_output_buffer_ptr) + i)); } }
3.4 发送从站输入数据子程序
在输入数据发送前,用户主程序首先要宏DPS2_GET_DIN_BUF_PTR( )取得输入缓冲区的指针,用宏 DPS2_INPUT_UPDATE( )用户可以重复地将输入数据从用户端传送到DPS2,并取得可用的输入缓冲区指针,用于接收新的输入数据。输入数据中并不包括输入数据的长度,但输入数据必须和DPS2_SET_IO_DATA_LEN( )定义的长度一致。
处理输入数据,将输入数据从外设写入缓冲区核心程序段如下:
for (i=0; i<user_io_data_len_ptr->inp_data_len; i++)
{
*(((UBYTE SPC3_PTR_ATTR*) user_input_buffer_ptr) + i) = *((io_byte_ptr) + i);
}
user_input_buffer_ptr = DPS2_INPUT_UPDATE( );
3.5 诊断数据发送子程序
主站和SPC3通过服务访问点SAP60处理诊断数据,SPC3需要完成的任务主要包括以下几点:
(1) 用户将外部诊断数据保存在diag_buffer中;
(2) 由NEW_DIAG_CMD启动诊断数据的传送;
(3) 用"Diag_buffer_changed"确认诊断数据已传送;
(4) 设置Diag_Flag,下一个读写周期将由高优先权响应新的诊断请求。
诊断用户在外部诊断数据输入之前,需要用宏DPS2_GET_DIAG_BUF_PTR( )取得可用的用户诊断数据缓冲区指针,可将用户诊断信息和状态信息写入到此缓冲区中从第7个字节开始的存储空间中,前6个字节为总线标准指定的的诊断头。用DPS2_SET_DIAG_LEN( )宏指定诊断数据的长度,诊断缓冲区长度范围为6~244字节,此诊断数据长度包括6个字节固定诊断数据和从第7个字节开始的外部用户诊断数据。设定诊断数据长度宏必须在接收到可用的诊断缓冲区指针以后,才能被调用。
用宏DPS2_DIAG_UPDATE( ),可以将新的外部诊断数据传给SPC3中的用户诊断缓冲区,并返回一个新的诊断数据缓冲区指针。 SPC3接收到New_Diag_Cmd诊断发送请求后,SPC3将用户诊断缓冲区的数据送到诊断发送缓冲区,并使原用户诊断缓冲区为可用状态。由于 SPC3的发送诊断缓冲区在数据发送完成后,不会自动变成有效状态,用DPS2_POLL_IND_DIAG_BUFFER_CHANGED( )查询到诊断缓冲区的数据发送完成后,用户需要置诊断缓冲区可用标志位。如果没有外部诊断数据传送, 或在诊断数据被传出前被删除,SPC3用6字节的从站诊断数据响应来自Profibus-DP主站的诊断请求, 这6字节的诊断数据包括3个字节的从站状态数据,发诊断请求的主站地址,从站设备标识号。
诊断处理程序核心程序段如下:
if (DPS2_POLL_IND_DIAG_BUFFER_CHANGED( ) )
{ DPS2_CON_IND_DIAG_BUFFER_CHANGED( );
user_diag_buffer_ptr = DPS2_GET_DIAG_BUF_PTR( );
user_diag_flag = TRUE; }
4 现场设备GSD文件的编制
为了实现Profibus-DP现场设备的快速组态,必须提供该产品可靠的电子设备数据单。Profibus-DP设备的特性均在电子设备数据单中具体说明,电子设备数据单也称为电子设备数据库文件GSD。标准化的GSD数据将通信扩大到操作员控制级,使用基于GSD的组态工具可将不同厂商生产的设备集成在同一总线系统中,即简便又可靠。GSD文件大体上可以分为三部分:
4.1 一般规范
该部分包括生产厂商和设备的名称,硬件和软件的版本状况,支持的波特率,可能的监视时间间隔以及总线插头的信号分配;
4.2 DP主站有关的规范
该部分包括只适用于DP主站的各项参数(如连接从站的最多台数或上装和下装能力),该部分对从站没有规定;
4.3 DP从站有关的规范
该部分包括与从站有关的一切规范(如输入/输出通道的数量和类型、中断测试的规范以及输入/输出数据一致性的信息)。
GSD文件是由若干个行组成,每行都用一个关键字开头,包括关键字及参数(无符号数或字符串)两部分。GSD文件中的关键字可以是标准关键字(在 PROFIBUS标准中定义)或自定义关键字,标准关键字可以被PROFIBUS的任何组态工具所识别,而自定义的关键字只能被特定的组态工具识别。 GSD文件主要用于向组态工具提供从站的组态数据。
GSD文件标准规定中定义了标识不同功能的关键字以供组态软件识别,一个实现16路开关量输出的DP从站模块的GSD文件示意如下(仅列举了最重要的参数,其它一些参数的定义可依参考文献2定义):
#Profibus-DP
;支持Profibus-DP协议
Model_Name=“16_DO” ;从站设备名称
Ident_Number=0x18
;从站设备识别号(认证时得到)
Protocol_Ident=0 ;仅支持DP协议
12M_Supp=1 ;支持12M的波特率
Max_Tsdr_12M=800
;12M波特率时最长响应时间为800μs
Max_Diag_Data_Len=8
;最大用户诊断数据长度
Unit_Diag_Bit(0)=“external device not present”
;诊断位0表示的诊断信息
Unit_Diag_Bit(1)= “external device detects fault”
;诊断位1表示的诊断信息
Module=“Module1”0x23
;定义16路开关量输出模块
EndModule ;模块定义结束符
类似地,用户可以根据设备厂商提供的设备相关参数编制GSD文件。GSD文件将数据通信网络扩大到操作员控制级,基于GSD文件的组态软件提供了友好的用户界面。
5 Profibus-DP网络组态
调试与检验Profibus-DP产品前必须组建总线网络,并进行网络组态。通常的组态方法有两种:一种是使用COMPROFIBUS组态软件组态,该方法较为简便但只能实现简单的应用,适用于初级用户或开发从站产品时使用;另一种是使用STEP7软件进行组态,组态过程较为复杂但能够实现较为复杂的应用,组态本身也成为用户程序中的一部分。在实际应用中,应针对不同的需求选择合适的组态方法。鉴于篇幅限制,本文只讨论常用的STEP7组态方法。
5.1 网络硬件组态
组态一个基本的Profibus-DP网络所需的模块包括:电源(PS307/10A),CPU(S7-300系列),CP342-5(Profibus-DP主/从站接口模块),IM365(数据输入/输出模块,供多机架系统使用),中央机架(供安装各模块用)。硬件连接完成后需要安装自行编制的GSD文件,在菜单条中,选择OPTIONS→INSTALL NEW*.GSE FILES即可。
在组态硬件前必须首选建立一个STEP7项目,为了建立一个新的STEP7项目,首选应打开SIMATIC Manager,然后执行如下步骤:
(1) 在菜单条中,选择FILE-New…打开对话框以便建立一个新的项目;
(2) 选择“New Projet”按钮,为这个新的项目设定“存储位置(路径)”;
(3) 登录新项目的名称(如,S7-Profibus-DP),用“OK”确认并退出。
回到SIMATIC Manager的主菜单。S7-Profibus-DP对象文件夹的建立已经自动地生成了MPI对象。在项目屏幕的右半边可以看到此MPI(多点接口)对象。每次建立一个新项目,STEP7就自动地生成一个MPI对象。MPI是CPU标准的编程和通信接口。
返回到名称为S7-Profibus-DP项目的屏幕主菜单,选择对象Profibus并右击打开快捷菜单。选择OPEN OBJECT调用图形组态工具Net Pro。在屏幕的上部选择Profibus子网络,右击打开快捷菜单,选择命令OBJECT PROPERTIES…在 “Properties-Profibus”对话框中打开“Network Settings”标签。此时可以为Profibus子网络设置所有有关的网络参数。
此时需要设置的参数主要有:传输速率(transmission rate),总线行规(profile)和总线参数(bus parameters),其余的参数采用默认设置即可。所选用的传输速率将适用于整个Profibus子网络,因此在Profibus子网络上使用的所有站都必须支持所选用的波特率, 波特率可以在9.6kbit/s~ 12,000kbit/s之间选择。波特率1500k bit/s推荐作为缺省设置;总线行规为不同的Profibus应用提供基准(缺省设定)。每个总线行规包含一个Profibus总线参数集, 这些参数由STEP7程序计算和设定,并考虑到特殊的配置、行规和波特率,这些总线参数对整个总线和连接在此Profibus子网络中的所有节点都适用;所有总线参数值均以 tBIT(位运行时间)表示,tBIT与波特率有关,二者间的关系可以列于附表:
附表 位运行时间与波特率关系
5.2 组建Profibus-DP网络
利用STEP7软件来建立Profibus-DP网络也十分方便,主要包括以下步骤:
(1) 进入Hardware组态环境,将使用的各个模块用鼠标拖拉的方式添加到机架相应的位置处;
(2) 建立Profibus-DP网络,设定主站,并将各从站挂接到网络上;
(3) 设置各主从站的地址;
(4) 若一个机架容纳不了所有的模块,应相应地增加机架数目;
(5) 选择Station菜单下的Save and Compile命令,若无错误,就可以利用Download命令将硬件组态下载到PLC中。
利用CPU314、PS307/10A、IM365(SEND/RECEIVE)和CP342-2组态得到的Profibus-DP网络示意如图4。
图4 Profibus-DP网络组态示意
在设定各站地址时应注意有些类型的DP从站不提供用于设置Profibus地址的硬件开关,它们的总线地址是用2类DP主站功能 Set_Slave_Add来指定的。由于它是集成的MPI在线接口,故STEP7组态软件能够处理此编址功能,这种地址分配的方法仅适用于支持 Set_Slave_Add功能的DP从站设备。此外,从站设备的缺省地址由制造商设定为126。在欧洲标准EN 50170中,此地址已经被保留而不能由Profibus-DP用户使用,但如果此从站是新的从制造商那里直接得来的设备,仍然可以见到此缺省值。
6 结束语
开发Profibus-DP从站的硬件设计比较简单,相对复杂的是其软件设计和联机调试。笔者在DP从站开发过程中发现,很多情况下从站未能正常工作均是由于GSD文件编写有问题或网络组态错误造成的。本文针对这些问题进行了探讨,并结合实例给出了解决方案,具有一定的参考价值。在开发DP从站产品的过程中,必须对这些问题给予十分关注。