EPICS aSub记录使用实例

本实例描述了在数据库中如何使用aSub记录

本实验中使用了三个k型热电偶,一个3路k型热电偶变送器以及一个串口服务器:

 温度变送器参数:

 串口服务器:

1) 用makeBaseApp.pl构建IOC应用程序的目录结构:

[blctrl@localhost tempcollect]$ ls
bin  configure  db  dbd  iocBoot  lib  Makefile  tempcollectApp

2) 在configure/RELEASE文件中增加以下内容,指定要使用的模块:

SUPPORT=/usr/local/EPICS/synApps/support

ASYN=$(SUPPORT)/asyn
MODBUS=$(SUPPORT)/modbus

3)在程序源文件目录src中增加一个名为convert_t.c的C源程序文件和一个对应的convert.dbd文件,内容分别如下:

convert_t.c内容如下:

// 此C源文件是用于将aSub记录中分别从INPA,INPB,INPC读取一个整数
// 经过运算后,分别从OUTA,OUTB和OUTC输出链接输出
#include <stdio.h>
#include <dbDefs.h>
#include <registryFunction.h>
#include <aSubRecord.h>
#include <epicsExport.h>


static long convert_t(aSubRecord *prec) {
        long i, *a;
        double * b;

        a = (long *)prec->a;
        b = (double *)prec->vala;

        for (i=0; i<prec->noa; i++) {
            b[i] = 0.1 * a[i];
        }
        //printf("%d-%f\n", a,b);

        a = (long *)prec->b;
        b = (double *)prec->valb;

        for (i=0; i<prec->nob; i++) {
            b[i] = 0.1 * a[i];
        }

        //printf("%d-%f\n", a,b);
        a = (long *)prec->c;
        b = (double *)prec->valc;

        for (i=0; i<prec->noc; i++) {
            b[i] = 0.1 * a[i];
        }
        //printf("%d-%f\n", a,b);

        return 0; /* process output links */
}

convert.dbd内容如下:

function(convert_t)

将以上内容以及所需要dbd文件和库文件指定到相同路径下Makefile文件中:

...
tempcollect_DBD += asyn.dbd
tempcollect_DBD += drvAsynIPPort.dbd
tempcollect_DBD += modbus.dbd
tempcollect_DBD +=  convert_t.dbd

# Add all the support libraries needed by this IOC
tempcollect_LIBS += asyn
tempcollect_LIBS += modbus


tempcollect_SRCS +=  convert_t.c
...

4) 在Db路径下增加一个数据库longinInt32.template模板文件和convert.db文件:

longinInt32.template内容如下,其作用是从modbus协议设备读取寄存器输入:

# longin record template for register inputs
record(longin,"$(P)$(R)") {
    field(DTYP,"asynInt32")
    field(INP,"@asyn($(PORT) $(OFFSET))$(DATA_TYPE)")
    field(SCAN, "$(SCAN)")
}

convert.db文件内容如下,其作用是进行数据转换:

# 此记录是进行数据转换,转换过程将调用编写的convert_t函数
record(aSub, "$(P)Convert") {
  field(DESC, "Convert Raw To Temp")
  field(SCAN, ".5 second")
  field(SNAM, "convert_t")
  field(FLNK, "$(P)ForwardValue.PROC")
  field(EFLG, "ON CHANGE")
  field(INPA, "$(P)$(T)1")
  field(INPB, "$(P)$(T)2")
  field(INPC, "$(P)$(T)3")
  field(FTA, "LONG")
  field(FTB, "LONG")
  field(FTC, "LONG")
  field(OUTA, "$(P)$(M)1")
  field(OUTB, "$(P)$(M)2")
  field(OUTC, "$(P)$(M)3")
}

# 用于设置Event记录提交的事件号
record(longin, $(P)Event)
{
  field(INP, "1")
  field(PINI,"1")
}

# 运行时将提交指定事件
record(event, "$(P)ForwardValue") {
  field(DESC, "Forward All Value")
  field(INP, "$(P)Event")
  field(SCAN, "Passive")
  field(PINI, "NO")
  field(VAL, "1")
}

# 如果遇到提交的事件为1,则运行
record(ai, "$(P)$(M)1") {
  field(SCAN, "Event")
  field(EVNT, "1")
}

# 如果遇到提交的事件为1,则运行
record(ai, "$(P)$(M)2") {
  field(SCAN, "Event")
  field(EVNT, "1")
}

# 如果遇到提交的事件为1,则运行
record(ai, "$(P)$(M)3") {
  field(SCAN, "Event")
  field(EVNT, "1")
}

将以上两个文件,添加到同级目录中的Makefile中:

...
DB += longinInt32.template
DB += convert.db
...

5) 回到这个IOC的顶层目录,执行Make,进行程序编译。

6)进入到启动文件所在目录,编辑一个模板替代文件temperature.substitutions以及st.cmd启动文件

temperature.substitutions内容如下:

file "../../db/longinInt32.template" { pattern
{P,                             R,              PORT,           OFFSET,         DATA_TYPE,      SCAN}
{ZSTEMPERATURE:                 TEMP1           AI_In_Word,     0,              INT16, "I/O Intr"}
{ZSTEMPERATURE:                 TEMP2           AI_In_Word,     1,              INT16, "I/O Intr"}
{ZSTEMPERATURE:                 TEMP3           AI_In_Word,     2,              INT16, "I/O Intr"}
}

st.cmd内容如下:

#!../../bin/linux-x86_64/tempcollect

#- You may have to change tempcollect to something else
#- everywhere it appears in this file

< envPaths

cd "${TOP}"

## Register all support components
dbLoadDatabase "dbd/tempcollect.dbd"
tempcollect_registerRecordDeviceDriver pdbbase
## 这里的Modbus温度温度变送设备的IP地址192.168.3.111和端口号26
## 设置端口名为temperature
drvAsynIPPortConfigure("temperature", "192.168.3.111:26",0,0,1)

## 此设备使用标准的RTU
modbusInterposeConfig("temperature", 1 ,2000, 0)


# 读保持寄存器,从地址0开始读取3个字
drvModbusAsynConfigure("AI_In_Word",  "temperature",1, 3, 0, 3, 0, 500, "temperature")

## 装载数据库实例
dbLoadRecords("db/convert.db","P=ZSTEMPERATURE:,T=TEMP,M=RT")

cd "${TOP}/iocBoot/${IOC}"
## 装载数据库实例
dbLoadTemplate("temperature.substitutions")
iocInit

7) 在启动目录中启动这个IOC程序,并且查看加载的记录:

../../bin/linux-x86_64/tempcollect st.cmd

epics> dbl
ZSTEMPERATURE:ForwardValue
ZSTEMPERATURE:Event
ZSTEMPERATURE:TEMP1
ZSTEMPERATURE:TEMP2
ZSTEMPERATURE:TEMP3
ZSTEMPERATURE:Convert
ZSTEMPERATURE:RT1
ZSTEMPERATURE:RT2
ZSTEMPERATURE:RT3

8) 用CSS Pheobus做一个图形界面:

猜你喜欢

转载自blog.csdn.net/yuyuyuliang00/article/details/130383961
今日推荐