DNP3.0在基于DSP的FTU中的实现
根据DNP3.0的层次结构定义三个结构体——链路层DL_LAYER、传输层T_LAYER和应用层APP_LAYER,每个结构体再按照DNP3.0中相应层规定的字段去逐个定义相应的成员即可。如链路层包括报头和n个数据块,报头又包括起始字、长度、控制字节等字段,控制字节按比特位又包括功能码、方向位和帧计数位等。链路层结构定义为:
(1)DL层控制字
typedef struct{
WORD b0-3_FuncCode:4,/*功能码*/
b4_FCV:1 /*帧计数有效位*/
b5_FCB:1, /*帧计数位*/
b6_PRM:l /*主站标志位*/
b7_DIR:1; /*方向位*/
}DL_CONTROL;
(2)DL层报头
typedef struct{
DWORD dwStart; /*起始字*/
WORD wLength; /*长度*/
DL_CONTROL DLCtrl; /*控制字*/
DWORD dwDest; /*目的地址*/
DWORD dwSource; /*源地址*/
DWORD dwCRC; /*校验码*/
}DL_HEADER;
(3)DL层数据块
typedef struct{
WORD awUserData[l6] /*用户数据*/
DWORD dwCRC; /*校验码*/
}DL_DATABLOCK;
3.3 流程图
DNP3.0已经详细规定了协议的层次结构及每一层的功能,程序的层次结构只要与其一致就会非常清晰,编程时只需遵照这些层次间的数据流向编写相应的函数即可。物理层对应串口收发中断子程序,链路层、传输层和应用层在接收与发送时各有一套函数去处理,以对应串口的全双工工作方式。其中,链路层接收处理流程如图3所示。javascript:window.open(this.src);" style="cursor:pointer;"/>
3.4 ASP的相关程序
3.4.1 ASP的寄存器定义
ioport unsigned portFFF4;
#define ADTR portFFF4 /*收发寄存器*/
ioport unsigned portFFF5;
#define ASPCR poaFFF5 /*控制寄存器*/
ioport unsigned portFFF6;
#define IOSR poaFFF6 /*I/O状态寄存器*/
ioport unsigned portFFF7;
#define BRD portFFF7 /*波特率发生器*/
3.4.2 初始化ASP
void InitASP(){ /*初始化异步串口*/
ASPCR=0xE080; /*RIM=1L:允许接收中断,
STB=0:一位停止位*/
IOSR=0xl800; /*THRE=1:ADTR空*/
BRD=0x0020; /*20MHz/38400bps*/
}
3.4.3 异步串口呻断服务子程序
void interrupt aspint(){
if((IOSR & 0x0l00)==0x0l00){
Recv();} /*有接收数据*/
if((IOSR & 0x0400)==0x0400){
……;} /*帧错误处理*/
if((IOSR & 0x0800)==0x0800){
Send();} /*可以发送数据*/
*IFR=0x20; /*清中断标志*/;
asm("clrc INTM") /开中断*/;
}
由于采用F206的片内串口作为通信工具,充分利用了DSP的片内集成外设,不仅使得通信模块可靠性较高,而且接口方法简单,ASP的控制和读写通过几个寄存器就可完成,非常方便。采用本文所介绍的方法编写的以DNP3.0为规约的通信子程序流程清晰,符合模块化的要求。自现场投入试运行以来,整个通信模块工作稳定可靠,能迅速响应主站请求,主动上报数据,及时准确。但是随着现场总线技术的发展,FTU还应具备至少一个现场总线接口(如CAN总线接口)。这样不光通信质量有保证,还可以简化通信规约(只保留一个应用层即可),这应该是FTU通信方式的一个发展方向。