profibus-dp现场总线智能节点的设计(1)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第30章PROFIBUS-DP 现场总线智能节点的设计
本章主要内容包括: 任务描述及设计方案 SPC3芯片简介 系统软硬件设计
随着当今工业的发展,其复杂化程度日益提高,在工业控制过程中需要对现场信号进行大量的采集,而且随数据的传递与转换以及对系统的控制精度、可靠性都提出了更新、更高的要求,因此产生了新型的现场总线控制系统FCS 。

一个现场总线控制系统中需要有很多现场总线智能仪表,本章基于西门子公司的智能化芯片SPC3设计了一款能把现场检测4~20mA 到的模拟信号转换为符合PROFIBUS-DP 传输协议的仪表,来作为PROFIBUS-DP 的现场总线网络中的一个智能节点使用。

30.1系统设计要求及设计思路
现场总线控制系统是一种权分散的、全数字化的、串行的总线控制系统。

现场仪表、执行器、阀门等提供的应是符合现场总线协议标准的信号。

在众多的现场总线中,PROFIBUS 以其优异的性能在工业控制系统中被广泛应用,因此有必要设计一个智能节点,以微控制器为核心,能够使现场控制器与底层传感器和执行器进行双向通信,来完成任务。

这一小节将介绍一个基于AT89S52单片机和SPC3的智能节点系统设计,系统的具体功能如下:
能够完成4-20mA 模拟信号到串行信号的转换; 能完成节点地址的设定;
可以实现检测数据的显示,数据交换过程的指示,超限警报等; UART 到PROFIBUS 总线的转换。

本文采用AT89S52片机和西门子的SPC3协议芯片来完成现场总线通信接口的设计,数据采集部分采用线性光电隔离器对模拟信号进行隔离,通过12位串行A/D 转换器MAX186将现场信号转换为数字信号后输入到单片机,单片机经过数字滤波后经SPC3发送到PROFIBUS-DP 总线上,单片机同时通过SPC3接收PROFIBUS-DP 主站指令和数据,将诊断数据发送给主站。

结构框图如图30-1所示。

图30-1 系统结构框图
现场信号
PROFIBUS-DP
30.2 PROFIBUS-DP现场总线及其通信协议简介
PROFIBUS(Process Fieldbus)是由西门子等公司开发的一种国际化的、开放的、不依赖于设备生产商的现场总线标准,先后成为德国和欧洲的现场总线标准(DIN19245和EN5017),并于2000年成为IEC61158国际现场总线标准之一,2001年成为我国机械行业标准JB/T10308.3-2001.
30.2.1 PROFIBUS现场总线简介
PROFIBUS现场总线是一个开放的、与制造商无关的、无知识产权保护的国际标准,任何人都可以获得这个标准并设计各自的软、硬件解决方案。

PROFIBUS包括三个兼容部分:PROFIBUS-FMS,PROFIBUS-DP和PROFIBUS-PA,它们分别适用于不同领域。

PROFIBUS-DP采用数字化、开放式通信,稳定可靠,使用PROFIBUS-DP可取代昂贵的24V或4~20mA的并行信号传输线,改变了传统控制系统中每个仪表都需要一条线连接到中央控制室的局面,大量节约了布线费用,同时也降低了中央控制室的造价。

目前,PROFIBUS-DP是在欧洲乃至全球应用最为广泛的现场总线之一,它的技术性能使其可以应用于全球的制造业、楼宇、过程自动化及电站自动化,使用该总线不但可以提高通信能力及系统运行的可靠性,大大节省系统安装时的布线费用和硬件费用,而且更加容易对系统进行管理和维护。

PROFIBUS-DP的基本功能和特征:
远距离高速传输。

PROFIBUS-DP的通信介质有两种:一种是采用屏蔽绞线,通信速率为9.6Kbit/s/1200m~12Mbit/s/100m,每段最多节点数为32;另一种是采用光纤,用于电磁兼容性要求高和长距离要求的场合。

51单片机典型应用开发范例大全
分布式结构。

各主站间令牌传递,主站与从站为主从传递,每段可达32个站,用于中继器连接段,最多可达126个站。

易于安装。

总线结构使得1个站点的安装、卸载不影响其他站点的正常工作。

诊断功能。

诊断功能能对故障进行快速定位,诊断信息在总线上传递并由主站采集。

灵活的配置。

1类主站可以完成调节控制功能,并通过循环和非循环的报文对现场的从站节点进行访问和控制;2类主站在需要时可以通过非循环报文同1类主站以及现场从站节点交换数据。

硬件支撑。

原则上,PROFIBUS-DP协议可以在任何具有内部或外部异步串行端口的微处理器上实现,但这种方法会引起对CPU资源的争夺和冲突,影响通信状态机制的实时控制,当传输速度超过500kbit/s传输技术时就需要使用专门的协议芯片,西门子公司的SPC3正是这种芯片。

总线存取协议。

各主站之间采用令牌传递方式,主站和从站之间采用主从方式。

为了更好地理解后面介绍的软件程序这里先介绍一类主站与从站的通信过程。

系统从上电到正常的数据交换工作状态的整个过程可以概括为以下四个阶段:
主站与从站的初始化。

上电后主站和从站进入Offline状态,执行自检。

当所需要的参数都被初始化后,主站开始监听总线令牌,从站开始等待主站对其设置参数。

总线上令牌环的建立。

在一定的时间内主站如果没有听到总线上有信号传输,就开始自己生成令牌并初始化令牌环,然后改主站做一次对全体可能主站地址的状态询问,根据收到的应答结果确定活动主站表。

主站与从站通信的初始化。

在主站和从站设备通信之前,主站必须设置DP从站的参数并配置从站通信接口。

主站通过请求从站的诊断数据来检查从站的准备情况。

如果从站报告它已经准备好接收数据,则从站参数数据并检查通信接口配置,收到从站的确认回答后,主站在请求从站的诊断数据已查明从站是否准备好进行用户数据交换。

只有这些工作完成后主
站才能开始循环的与从站交换数据。

用户的交换数据通信。

30.2.2 PROFIBUS-DP 通信模型
PROFIBUS-DP 使用了OSI 模型的第1、2层和用户接口,第3到第7层未用,这种精简的结构确保了高速数据传输。

物理层采用了RS-485标准,规定了传输介质和电气特性。

PROFIBUS-DP 的数据链路层称为现场总线数据链路层FDL ,包括总线介质访问控制MAC 以及现场总线链路控制FLC ,FLC 向上层提供服务存取点的管理和数据缓存。

第1层和第2层的现场总线管理FMA1/2完成待定总线参数的设定,它还完成这两层出错信息的上传。

PROFIBUS-DP 的用户层包括直接数据链路映射DDLM 、DP 基本功能、扩展功能以及设备运行行规。

DDLM 提供访问FDL 的接口,DP 设备行规是对用户数据含义的具体说明,规定了各种应用系统和设备的行为特征。

协议结构如图30-2所示。

PROFIBUS-DP 的物理层实现对称数据的传输,一个总线内的导线是屏蔽双绞电缆,段的两端各有一个中端器。

传输速率从9.6kibt/s 到12Mbit/s 可选,所选用的波特率适用于连接到总线上的所有设备,可实现半双工、异步、无间隙同步数据传输,采用NRZ (非归零)编码。

数据链路层(FDL )规定了总线存取控制、数据安全性以及传输协议和报文的处理,规定了数据帧格式。

FDL 向上一层提供的四种服务包括:发送数据需应答(SDA )、发送数据无需应答(SDN )、发送并请求数据需回答(SRD )、循环地发送并请求数据需回答(CSRD )。

用户想要FDL 提供服务,必须向FDL 申请,而FDL 执行后回想用户提交服务结果。

FDL 的用户除了可以申请FDL 服务之一外,还可以对FDL 以及物理层PHY 进行一些必要的管理,比如强制复位FDL 和PHY 、设定参数、读状态、读事件及进行配置等,在PROFIBUS-DP
用户层包括DDLM 和用户接口/用户等,
他们在通信中实现各种应用功能。

DDLM 是预先定义的直接数据链路映射程序,将所有的在用户接口中传送的功能都映射到第2层FDL 和FMA1/2服务。

它向第2层发送功能调用SSAP 、DSAP 和Serv-class 等必须的参数。

接收来自第2层的确认和指示并将它们传送给用户接口/用户。

通信模型如图30-3所示。

主站
从站
图30-3 PROFIBUS-DP 通信模型
30.3 智能从站专用通信接口芯片SPC3
SPC3是西门子公司用于开发PROFIBUS-DP从站的智能通信专用芯片,集成了完整的PROFIBUS-DP协议,可以独立完成全部PROFIBUS-DP通信功能。

30.3.1 SPC3技术特点
SPC3只继承了传数据输的部分功能,而没有集成模模拟功能(RS-485驱动器,因此后面的智能从站设计要专门设计通信接口电路)。

SPC3集成了1.5KB的双口RAM作为SPC3与程序的接口。

整个RAM被分为192段,每个8字节。

用户寻址是由内部微序列器MS通过基址指针来实现。

基址指针可位于存储器的任何阶段。

所以,任何缓存都必须位于段首。

如果SPC3工作在DP方式下,SPC3将自动完成所有的DP-SAPs的设置。

在数据缓存区生成各种报文(如参数数据和配置数据),为数据通信提供三个可变的缓存器,2个输入,1个输出。

通信经常用到变化的缓存器,因此不会发生任何资源问题。

SPC3为最佳诊断提供两个诊断缓存器,用户可存入刷新的诊断数据,在这一过程中,有一诊断缓存总是分配给SPC3。

总线接口是一个参数变化的位同步/异步接口,可使用任何Intel和Motorola处理器/微处理器。

用户可通过11位总地址直接访问1.5KB的双口Ram或参数存储器。

处理器上电后,程序参数(站地址、控制位等)必须传送到参数寄存器和方式寄存器。

任何时候状态寄存器都能监视MAC状态。

各种事件(诊断和错误等)都能进入中断寄存器,通过屏蔽寄存器使能,然后通过响应寄存器响应。

SPC3有一个公共的中断输出。

看门狗定时器有3种状态,Band_Search、Band_Control、DP_Control。

微序列控制器(MS)控制整个处理过程。

程序参数(缓存器指针、缓存器长度、站地址等)和数据缓存器包含在内部1.5KB的双口RAM中。

在UART中,并行、串行数据相互转换,SPC3能自动调整波特,最大数据传输速率12Mbps;外部时钟接口24MHz或48MHz;5V直流供电。

30.3.2 SPC3的内部结构和引脚定义
SPC3的内部结构如图30-4所示,引脚说明如表30-1所示,其封装形式位44引脚的PQFP 封装。

表30-1 SPC3引脚的功能
30.3.3 SPC3的存储器组织
SPC3内部有1.5KB双口RAM,按功能主要分为处理器参数锁存器/寄存器、组织参数、用户缓存三大部分。

下面具体介绍每部分的具体功能。

1,SPC3的存储器分配
SPC3内部1.5KB双口RAM分配如表30-2所示。

表30-2 SPC3内存分配
内部锁存器/寄存器位于前22字节,用户可以读取或写入。

一些单元只读或只写,用户不能访问的内部工作单元也位于该区域。

参数锁存器/寄存器存储分配如表30-3和表30-4所示。

组织参数位于16H开始的单元,这些参数影响整个缓存区的使用。

另外,一般参数(站地址、标识符等)和状态信息(全局控制命令)都存储在这些单元中。

组织参数说明如表30-5所示。

用户缓存位于40H开始的单元,所有的缓存器都开始于每个段的首地址(SPC3的整个RAM被分为192个段,每段8个字节)。

表30-3 内部参数锁存器分配(读)
表30-5 组织参数说明
SPC3的寄存器很多,本例就使用到的部分寄存器的功能重点介绍。

读者应注意:对于一些寄存器,读和写时所对应的功能不同。

(1)方式寄存器0(地址06H、07H)和方式寄存器1(地址为08H或09H)
方式寄存器0是一个16位的寄存器,在离线状态下设置,当方式寄存器中所有的处理器参数、组织参数被装载后,SPC3才离开离线状态(方式寄存器1的START_SPC3=1);方式寄存器1是一个8位的寄存器,可以单独被设置,(Mode_Reg_S),也可以单独被清除(Mode_Reg_R),设置或清除时必须在位地址写入逻辑1.设置时地址为008H,清除时地址为09H。

方式寄存器0的Bit0~Bit13定义如表30-6所示,其余两位没有定义。

表30-6方式寄存器0
方式寄存器1的Bit0~Bit5定义如表30—7所示,其余两位没有定义。

(2)状态寄存器(只读,地址04H,05H)
状态寄存器反应SPC3当前的状态并且为只读,状态寄存器各位的定义如表30-8所示。

表30-8 状态寄存器
通过中断控制器通知处理器各种中断信息和错误事件。

中断控制器最多可存储16个中断事件。

中断事件传送到共同的中断输出。

中断控制器包括中断请求寄存器(IRR)、中断屏蔽寄存器(IMR)、中断寄存器(IR)和中断响应寄存器(IAR)。

中断事件存储在IRR中,个别事件通过IMR被屏蔽,IRR中的中断输入与中断屏蔽无关,在IMR没有被屏蔽的中断事件经过网络综合产生XINT中断,用户调试时可在IRR中设置各种中断。

中断处理器处理过的中断必须通过IAR(New_Prm_Data,New_DDB_Prm_Data,New_Cfg_Data除外)清除,在相应位上写入1即可清除。

如果前一个已经确认的中断正在等待时,IRR中又接受到一个新的中断请求,则此中断被保留。

接着处理器能使屏蔽,则确保IRR中没有以前的输入。

出于安全考虑,使能屏蔽之前必须清除IRR中的位。

退出中断程序前,处理器必须在方式寄存器中设置“end of interrupt-signal(EOI)=1”,此跳变使中断线失效,如果另一个中断仍保留着,则至少经过1us或1~2ms中断失效时间后,该中断输出将再次被激活,中断失效时间可以通过EOI_Timebase位设置,这样可以利用边沿触发的中断输入再次进入中断程序。

中断请求寄存器是一个16位的寄存器,可写、可读地址为00H、01H,各位的定义如表30-9所示。

其他的中断控制寄存器各位的定义如表30-10所示,New_Prm_Data,New_CFG_Data输入不能通过中断响应寄存器清除,只能通过用户确认后由状态机制来清除。

30.4 PROFIBUS-DP 现场总线智能节点的硬件设计
前面已经介绍了从站协议芯片SPC3由硬件来完成DP协议,要完成DP从站的构建除了SPC3外还需要微处理器等功能块,本设计采用A T89S52作为微处理器。

其中SPC3独立完成DP从站写一部分的工作,在开始DP通信时,SPC3将会自动的设置所有的DP_SAPA(DP的服务存取点):
Default SAP:Write_Read_Data,用于数据的读写;
SAp53:SET_DDB_Parameter,DBB参数设置报文选择;
SAP55:Set_Slave_Address,允许DP2类主站分配一个新的总线地址给一个DP从站;SAp56:Read_Inputs:读取输入数据;
Sap57:Read_Outruts,读取输出数据;
Sap58:Global_Control,DP主站使用此控制命令将他的运行状态告知各DP从站,并可将Sync和Freeze命令发送给从站,实现输入数据和输出数据的同步。

Sap59:Get_Config,用来读取DP从站的当前组态数据。

Sap60:Slaves_Diaguosis,在启动期间或循环的用户数据交换期间,读取DP从站的诊断信息。

Sap61:Set_Param,设置参数。

Sap62:Check_Config检查组态。

DP主站在启动、数据传送阶段使用这两个功能发送参数集给DP从站。

所有的数据交换通过服务访问点SAp处理。

各种保文信息呈现在用户面前的是1.5KB内存中不同缓冲器的内部数据,用户可以通过总线接口访问这些内部数据。

因此微处理器不用参与处理器服务缓存点,主要任务就是根据SPC3产生的中断,对SPC3接收到的主站发出的输出数据转存、处理,组织要通过SPC3发给主站的数据,并根据要求组织外部诊断等,微处理器将主战输出到从站的数据从SPC3存储区取出进行处理;级那个主站屋窑的数据存储到SPC3相应的数据缓存器中,为通信输入到DP主站做好准备。

该智能从站的硬件电路主要包括微处理器AT89S52与SPC3的接口电路、SPC3与RS485的接口电路数据采集电路、供电源电路几部分。

30.4.1 AT89S52与SPC3的接口电路
A T89S52与SPC3的接口电路如图30-5所示。

对AT89S52而言,SPC3相当于它扩展的一个外部RAM。

根据选择的CPU,SPC3应工作在INTEL方式下因此XCS和MODE都接高电平。

A T89S52的P0口(低8为地址和数据的分时复用)接SPC3的DB0~DB7(低8为地址和数据的分时复用),可以产生数据和低8位的地址总线,p2.0~2.3接SPC3的AB0~AB3的作为高4位地址AB8~AB11,P2.5~P2.7接74LS138译码器的输入端,译码器的输出端Y1接SPC3的AB4作为地址线AB12,SPC3的AB5、6、7经过1K的电阻接地(即地址线AB13~AB15为0),由此可以得出SPC3的内部1.5K的RAm地址为2000H~25FFH,单片机通过访问外部RAm的方法来访问SPC3的寄存器。

SPC3的内部译码器电路如图30-6所示。

图30-5CPU与SPC3的接口电路
图30-6 SPC3的内部译码器
SPC3的CLK接有源晶振的FOUT,FOUT输出24MHZ的时钟脉冲信号,SPC3的DIVIDER 引脚接高电平,内部分频器对时钟脉冲信号2分频,产生12MHZ的分频信号为AT89S52提供时钟信号,节省了电路的费用。

注意:SPC3的引脚具体定义请参考表30-1.也请读者自己写出方式寄存器、状态寄存器、中断管理寄存器的地址。

30.4.2 SPC3与RS485的接口电路
SPC与RS485的接口电路如图30-7所示。

PROFIBUS-DP接口数据通过RS-485传输,而SPC3是UART口,因此应设计SPC3与RS485的接口电路。

RS-485驱动器一端通过光电隔离器与协议芯片SPC3相连,另一端通过9针D型插头与总线相连,9针D型插头是PROFIBUS-DP总线网络专用链接器,具体信号排列与含义如表30-7.RS-485驱动器选择SN75ALS176来满足高速数据通信,采用光电隔离器6N137来增加系统的抗干扰性。

图30-7 SPC3与RS485的接口电路
数据采集电路如下图30-8所示。

系统采集0/4~20ma标准信号,通过250欧精密电阻将其转化为0/1~5V电压,为了提高系统的抗干扰性,经模拟隔离后的信号进入A/D转换器MAX186进行模数变换,变换后的数字信号经过6N137数字隔离后进入单片机,其中SCLK,CS,DIN,DOUT信号分别跟单片机的P1.0、P1.1、P1.2、P1.3模拟SPI总线时序,以便控制串行A/D转换器数据采集任务。

图30-8 数据采集电路
30.4.4 供电电源电路
除了上述主要电路外还有供电电路,在智能节电的设计中,供电电源一般为+24V,而智
能节点内部需要+5V电源,因此需要将+24V经过DC/DC变换产生所需电源。

图30-9所示为将+24V变为+ 5V的DC/DC变换电路。

图30-9 供电电源电路
30.5 PROFIBUS-DP 现场总线智能节点的软件设计
本里从智能节点的软件设计采用模块化设计方法,在程序设计中用到了大量的宏,读者在阅读时要注意这些宏的定义。

30.5.1 软件设计概述
从站的开发程序主要包括SPC3接口通信程序和数据采集程序,重点是SPC3的接口通信程序,它包括SPC3的初始化和SPC3中断服务程序。

具体模块包括:
主程序模块是整个系统管理核心,组织其他模块配合完成整个系统色数据采集和通信任务。

缓存器设置模块主要根据主站发给从站的参数报文、组态报文完成SPC3内部各缓存器的大小和及地址的理想化配置。

中断处理模块主要处理SPC3的中断请求,包括参数报文中断处理,新全局控制命令中断处理,新组态报文中断处理、看门狗超时中断处理、;用户时钟中断处理、波特率中断处理、离线中断处理等。

数据采集模块主要完成数据采集和数据处理。

看门狗程序完成程序监控。

串行通信模块完成串行通信程序,实现数据远传。

由于SPC3集成了完整的PROFIBUS-DP协议,因此AT89S52不用参与处理PROFIBUS-DP 状态转换,AT89S52的主要任务就是进行数据采集与处理,根据SPC3产生的中断,对SPC3接收到的主站命令书记进行转存,处理要通过SPC3发给主站的数据,并根据要求组织外部诊断等。

系统的主程序流程图如图30-10所示。

系统上电后进入主程序,首先对单片机和通信协议芯片进行初始化,重点是对SPC3进行初始化,以配置各个寄存器,包括设置SPC3允许的中断,写入从站标识号和地址,设计方式寄存器、诊断缓冲区、参数缓冲区、配置缓冲区及各缓冲区的初始长度,并根据以上初始值求出各输入输出缓冲区的指针及辅助缓冲区的起始地址和范围。

完成对单片机和SPC3的初始化后,启动SPC3,然后判断是否有主站输出数据,处理器输出数据,然后完成数据采集,然后写入缓存,向主站发送现场数据,此时要进行外部诊断的监控,如果有外部诊断,就向主站发送诊断信息。

如果主程序在执行过程中有DP中断发生,系统就进入中断处理程序。

SPC3的初始化程序主要配置各个寄存器,动态的、最优的分配SPC3缓存使SPC3的有限缓存得到合理的利用。

通过配置SPC3的各个寄存器,从而设SPC3的工作方式以及确定输入输出、诊断等缓冲器的大小和基址指针。

SPC3的初始化程序流程图如图30-11所示。

SPC3中断处理程序用于处理SPC3发生的各种事件,这些事件包括新的参数报文事件、全局控制命令报文事件、进入或退出数据交换状态事件、新的配置报文事件、新的地址设置报文事件。

本文采用外部中断INT0输入,其中断服务子程序的入口地址为0003H,定义了中断函数voiddps2_ind(void)interrupt0。

中断处理程序流程图如图30-12所示。

采用125位串行A/D转换器完成数模转换,并利用单片机AT89S52的P1接口来完成数据采集任务,并对采集到的数据进行了中值滤波。

经过数字滤波后传送到PROFIBUS-DP现场总线网络上去。

系统在向网络发送数据前,通过宏DPS2_INPUT_UPDATE()取得当前新的输入缓冲区的基地址,将采集到的现场数据通过SPC3发送给PROFIBUS-DP总线网络上的主站节点。

数据接收程序通过宏DPS@_POLL_IND_DX_OUT()检测到松弛3接收到主站输出数据后,向主站发送确认信息,同时取得输出缓冲区大小和基地址,然后将受到的数据存入系统外存,以备下一步使用。

30.5.2 模块程序的介绍
本例智能节点程序设计较为复杂,因此仅仅就一些重要的模块程序作出介绍。

1.top.h:SPC3 内部存储结构的结构体数据类型定义和宏定义程序。

为了写程序的方便,用top.h模块程序定义了数据结构和大量的宏。

Enum SPC3_INIT_RET{SPC3_INIT_OK,SPC3_INITF_LESS_MEM,
SPC3_INITF_NOFF,DPS2_INITF_DIN_DOUT_LEN,DPS2_INITF_DIAG_LEN,D
PS2_INITF_PRM_LEN,DPS2_INITF_CFG_LEN,DPS2_INITF_SSA_LEN,FDL_I NITF_IVP,FDL_INITF_SCNT};
typedef struct{
/*--SPC3内部寄存器的定义--*/
union{
/*0x00:中断请求寄存器*/
UWORD w;
UBYTE b[2];
}int_req;
/*0x02:中断寄存器(读),中断响应寄存器(写)*/
Union{
Union{
UWORD w;
UBYTE b[2];
}com;
Union{
UWORD w;
UBYTE b[2];
}ack;
}int_reg;
Union{
/*0x04:状态寄存器(读),中断屏蔽寄存器(写)*/
UWORD mask;
UBYTE status[2];
}is_reg;
/*0x06:方式寄存器0*/
UWORD mode_reg0;
Union{
/*--union xl is for R/W*/
Struct{/*数据输出区域*/
UBYTE din_buffer_sm; /*0x08*/
UBYTE new_din_buf_cmd; /*0x09*/
UBYTE dout_buffer_sm; /*0x0a*/
UBYTE next_dout_buf_cmd; /*0x0b*/
}r;
Struct{/*数据写入区域*/
UBYTE mode_reg1_s; /*0x08*/
UBYTE mode_reg1_r; /*0X09*/
UBYTE wd_baud_ctrl_val; /*0x0a*/
UBYTE mintsdr_val; /*0x0b*/
}w;
}xl;
UBYTE diag_buffer_sm; /*0x0c*/
UBYTE new_diag_buffer_cmd; /*0x0d*/
UBYTE user_prm_data_ok; /*0x0e*/
UBYTE user_prm_data_nok; /*0x0f*/
UBYTE user_cfg_data_ok; /*0x10*/
UBYTE user_cfg_data_nok; /*0x11*/
UBYTE user_ddb_prm_data_ok; /*0x12*/
UBYTE user_ddb_prm_data_nok; /*0x13*/
UBYTE ssa_buffer_free_cmd; /*0x14*/
UBYTE reserved_15; /*0x15*/
/*--组织参数定义--*/
UBYTE r_ts_adr; /*0x16*/
UBYTE r_fdl_sap_list_ptr; /*0x17*/
UWORD r_user_wd_value; /*0x18*/
UBYTE r_len_dout_buf; /*0x1a*/
UBYTE r_dout_buf_ptr[3]; /*0x1b*/
UBYTE r_len_din_buf; /*0x1e*/
UBYTE r_din_buf_ptr[3]; /*0x1f*/
UBYTE r_len_ddbout_buf; /*0x22*/
UBYTE r_ddbout_buf_ptr; /*0x23*/
UBYTE r_len_diag_buf[2]; /*0x24*/
UBYTE r_diag_buf_ptr[2]; /*0x26*/
UBYTE r_len_cntrl_buf[2]; /*0x28*/
UBYTE r_aux_buf_sel; /*0x2a*/
UBYTE r_aux_buf_ptr[2]; /*0x2b*/
UBYTE r_len_ssa_buf; /*0x2d*/
UBYTE r_ssa_buf_ptr; /*0x2e*/
UBYTE r_len_prm_buf; /*0x2f*/
UBYTE r_prm_buf_ptr; /*0x30*/
UBYTE r_len_cfg_buf; /*0x32*/
UBYTE r_len_read_cfg_buf; /*0x33*/
UBYTE r_read_cfg_buf_ptr; /*0x34*/
UBYTE r_len_ddb_prm_buf; /*0x35*/
UBYTE r_ddb_prm_buf_ptr; /*0x36*/
UBYTE r_score_exp; /*0x37*/
UBYTE r_score_error; /*0x38*/
UBYTE r_real_no_add_change; /*0x39*/
UBYTE r_ident_low; /*0x3a*/
UBYTE r_ident_high; /*0x3b*/
UBYTE r_gc_command; /*0x3c*/
UBYTE r_len_spec_prm_buf; /*0x3d*/
UBYTE reserved_3e_3f; /*0x3e-0x3f*/
}SPC3;
#define
SPC3_SET_HW_MODE(MODE)spc3.mode_reg0=((MODE)|DP_MODE&(~EN_FDL_DDB));
#define SPC3_SET_IND(INDS)spc3.is_reg.mask=~(INDS);
#define SPC3_SET_STATION_ADDRESS(ADDRESS)spc3.r_ts_adr=ADDRESS;
#define SPC3_SET_MINTSDR(MINTSDR)spc3.xl.w.mintsdr_val=MINTSDR;
#define SPC3_START()spc3.xl.w.mode_reg1_s=START_SPC3;
#define SPC3_GO_OFFLINE()spc3.xl.w.mode_reg1_s=GO_OFFLINE_SPC3;
#define
SPC3_INIT(DPS2_IBUF_PTR)dps2_buf_init(&er,DPS2_IBUF_PTR,TRUE,_USE_SPEC _PRM_BUF_);
#define DPS2_SET_IDENT_NUMBER_LOW(NR)spc3.r_ident_low=NR;
#define DPS2_SET_IDENT_NUMBER_HIGH(NR)spc3.r_ident_high=NR;
#define DPS2_SET_ADD_CHG_DISABLE()spc3.r_real_no_add_change=0xff;
#define DPS2_SET_ADD_CHG_ENABLE()spc3.r_real_no_add_change=0x0;
#define
DPS2_USER_LEA VE_MASTER()spc3.xl.w.mode._regl_s=-40-USER_LEA VE_MASTER;
#define SPC3_GET_INDICATION().w;
#define
SPC3_GET_IND_MAC_RESET()(spc3.int_.b[_IML]&MAC_RESET_EX_B);
#define
SPC3_GET_IND_BAUDRA TE_DETECT()(spc3.int_.b[_IML]&BAUDRATE_DETECT _B);
#define
SPC3_GET_IND_USER_TIMER_CLOCK()(spc3.int_.b[_IML]&USER_TIMER_CLOC K_B);
#define
DPS2_GET_IND_GO_LEA VE_DATA_EX()(spc3.int_.b[_IML]&GO_LEAVE_DATA_E X_B);
#define
DPS2_GET_IND_WD_DP_MODE_TIMEOUT()(spc3.int_.b[_IML]&WD_DP_MODE_ TIMEOUT_B);
#define
DPS2_GET_IND_NEW_GC_COMMAND()(spc3.int_.b[_IMH]&NEW_GC_COMMAN D_B);
#define
DPS2_GET_IND_NEW_SSA_DATA()(spc3.int_.b[_IMH]&NEW_SSA_DATA_B);
#define
DPS2_GET_IND_NEW_CFG_DA TA()(spc3.int_.b[_IMH]&NEW_CFG_DA TA_B);
#define
DPS2_GET_IND_NEW_PRM_DATA()(spc3.int_.b[_IMH]&NEW_SSA_PRM_B);
#define
DPS2_GET_IND_DIAG_BUFFER_CHANGED()(spc3.int_.b[_IMH]&DIAG_BUFFER_ CHANGED_B);
#define DPS2_GET_IND_DX_OUT()(spc3.int_.b[_IMH]&DX_OUT_B);
#define SPC3_IND_COFIRM(CON)spc3.int_reg.ack.w=(CON);
#define
SPC3_CON_IND_MAC_RESET()spc3.int_reg.ack.b[_IML]=(UBYTE)MAC_RESET_B;
SPC3_CON_IND_BAUDRATE_DETECT()spc3.int_reg.ack.b[_IML]=(UBYTE)BAUDRATE_D ETECT_B;
#define
SPC3_CON_IND_USER_TIMER_CLOCK()spc3.int_reg.ack.b[_IML]=(UBYTE)USER_TIMER _CLOCK_B;
#define
DPS2_CON_IND_GO_LEA VE_DATA_EX()spc3.int_reg.ack.b[_IML]-41-=(UBYTE)GO_LEA V E_DA TA_EX_B;
#define
DPS2_CON_IND_WD_DP_MODE_TIMEOUT()spc3.int_reg.ack.b[_IML]=(UBYTE)WD_DP_ MODE_TIMEOUT_B;
#define
DPS2_CON_IND_NEW_GC_COMMAND()spc3.int_reg.ack.b[_IMH]=(UBYTE)NEW_GC_CO MMAND_B;
#define
DPS2_CON_IND_NEW_SSA_DA TA()spc3.int_reg.ack.b[_IMH]=(UBYTE)NEW_SSA_DATA_ B;
#define
DPS2_CON_IND_DIAG_BUFFER_CHANGED()spc3.int_reg.ack.b[_IMH]=(UBYTE)DIAG_B UFFER_CHANGED_B;
#define DPS2_CON_IND_DX_OUT()spc3.int_reg.ack.b[_IMH]=(UBYTE)DX_OUT_B;
#define SPC3_SET_EOI()spc3.xl.w.mode_regl_s=EOI_SPC3;
#define SPC3_POLL_INDICATION()spc3.int_req.w;
#define SPC3_POLL_IND_MAC_RESET()(spc3.int_req.b[_IML]&MAC_RESET_B);
#define
SPC3_POLL_IND_BAUDRATE_DETECT()(spc3.int_req.b[_IML]&BAUDRATE_DETECT_B) ;
#define
SPC3_POLL_IND_USER_TIMER_CLOCK()(spc3.int_req.b[_IML]&USER_TIMER_CLOCK_ B);
#define
DPS2_POLL_IND_GO_LEA VE_DA TA_EX()(spc3.int_req.b[_IML]&GO_LEA VE_DATA_EX_ B);
#define
DPS2_POLL_IND_WD_DP_MODE_TIMEOUT()(spc3.int_req.b[_IML]&WD_DP_MODE_TI MEOUT_B);
#define
DPS2_POLL_IND_NEW_GC_COMMAND()(spc3.int_req.b[_IMH]&NEW_GC_COMMAND_ B);
#define
DPS2_POLL_IND_NEW_CFG_DATA()(spc3.int_req.b[_IMH]&NEW_CFG_DA TA_B);
#define
DPS2_POLL_IND_NEW_PRM_DA TA()(spc3.int_req.b[_IMH]&NEW_PRM_DATA_B);
DPS2_POLL_IND_DIAG_BUFFER_CHANGED()(spc3.int_req.b[_IMH]&DIAG_BUFFER_CH ANGED_B);
#define DPS2_POLL_IND_DX_OUT()(spc3.int_req.b[_IMH]&DX_OUT_B);
#define DPS2_GET_CFG_LEN()spc3.r_len_cfg_buf;
#define
DPS2_GET_CFG_BUF_PTR()((voidSPC3_PTR_ATTR*)((SPC3_PTR)&spc3+(SPC3_OFFS)(((( UWORD)spc3.r_cfg_buf_ptr)<<3))));
#define DPS2_SET_CFG_DATA_OK()dps2_cfg_data_ok();
#define DPS2_SET_CFG_DATA_UPDATE()dps2_cfg_data_update();
#define DPS2_SET_CFG_DATA_NOT_OK()dps2_cfg_data_not_ok();
#define DPS2_SET_READ_CFG_LEN(LEN)spc3.r_len_read_cfg_buf=LEN;
#define
DPS2_GET_READ_CFG_BUF_PTR()((voidSPC3_PTR_ATTR*)((SPC3_OFFS)((((UWORD)sp c3.r_read_cfg_buf_ptr)<<3))+(SPC3_PTR)&spc3));
#define DPS2_GET_PRM_LEN()spc3.r_len_prm_buf;
#define
DPS2_GET_PRM_BUF_PTR()((voidSPC3_PTR_ATTR*)((SPC3_OFFS)((((UWORD)spc3.r_pr m_buf_ptr)<<3))+(SPC3_PTR)&spc3));
#define DPS2_SET_PRM_DATA_OK()er_prm_data_ok;
#define DPS2_SET_PRM_DATA_NOT_OK()er_prm_data_nok;
2.main(): 主程序
主程序是整个系统管理中心,组织其他模块配合完成整个系统的数据采集和通信任务。

#include<reg52.h>
/*************************************函数声明***********************/
void init_spc3(void); //初始化SPC3程序
V oid data_rec(void); //数据接收程序
V oid data_send(void); //数据发送程序
Int new_prm_handle(void); //新的参数报文中断处理程序
V oid new_cfg_handle(void); //新的组态报文中的乱处理程序
V oid max186(void); //数据采集程序
V oid int()(void); //INT0中断服务子程序
/***************************************主程序**********************/
V oid main()
{
Init_spc3() //spc3的初始化程序
EX0=1; //允许外部中断0中断
EA=1; //开总中断
Data_rec(); //检测并接受主站发送数据
Max186(); //数据采集程序
Data_send(); //采集到的数据往主站发送
While(1){} //等待外部中断0中断
}
3.int0():外部中断0中断服务程序
该程序主要处理SPC3的中断请求,包括新参数报文中断处理、新组态报文中断处理、新全局报文命令中断处理、WD超时中断处理、用户时钟中断处理、波特率中断处理、离线中断处理等。

下面介绍两个比较重要的报文处理程序。

(1)new_pfm_handle():新的参数报文中断处理
SPC3评估参数校该报文前7个字节,参数报文从第8字节开始,如果读出为0XAA,表示系统出错;如果正确,可以将第8字节以后的信息用做诊断信息发送给主站,以确认从站处于激活状态。

#include”top.h”
if(DPS2_GET_IND_NEW_PRM_DATA())
{
UBYTE SPC3_PTR_ATTR*prm_ptr;
UBYTE param_data_len,prm_result;
UBYTE it;
prm_result=DPS2_PRM_FINISHED;
do
{
prm_ptrresult=DPS2_GET_PRM_BUF_PTR();
param_data_len=DPS2_GET_PRM_LEN();
if (param_data_len>7)
{
/*如果参数报文的第8个第9个字节都为AAH,则认为出错*/
If((*(prm_ptr+8)==0xAA)&&(*(prm_ptr+9)==0xAA))
prm_result=DPS2_SET_PRM_DATA_NOT_OK();
/*否则,把第8个字节以后的数据送入参数测试数据缓冲区,准备发给主站*/
Else
{
For(ii=0;ii<param_data_len&&ii<10;ii++)
Prm_tst_buf[ii]*(prm_ptr+ii+7);
Prm_result=DPS2_SET_PRM_DATA_OK()
}
}
/*如果参数报文长度小于等于7,设置参数数据正确*/
Else
Prm_sesult=DPS2_SET_PRM_DATA_OK();
}
While(prm_result==DPS2_PRM_CONFLICT);
Store_mintsdr=*(prm_ptr+3);
}
(2)new_cfg_handle():新的组态报文中断处理
PROFIBUS-DP主站通过DP服务访问点SAP62访问从站,用户只需处理产生的NEW_CFG_DATA中断以检查来自主站的组态数据是否可用,并将检查结果返回给SPC3。

如果组态数据正确,SPC3进入数据交换状态。

用宏DPS2_GET_CFG_LEN()和
DPS2_GET_CFG_BUF_PTR()获得当前组态数据的长度(本系统为两字节)和指针,组态缓冲区初始化为10个字节。

组态缓冲区中的数据首先与在初始化程序中第一个写入到读组态。

相关文档
最新文档