基于VS2019 MFC下程控keysight精准电压表

        在测试过程中 不可避免的要用到高精度电压表,如果要搭建自动测试环境,则需要对电压表进行程控;本文对工作中用到的keysight 34420A进行了远程控制,供大家参考。

        实现程控时,需要用到VISA库和SCPI命令,这个大家可以参考各自的手册。另外,至于控制语句可以阅读 每个仪器的手册,均有远程控制 编程介绍。


        keysight 34420A支持GPIB 和 ASRL接口,所以笔者在调试过程中使用了GPIB 接口。

由于笔者调试的环境是多线程并发测试,所以使用了多台34420A仪器,首先对仪器进行了地址编址,用以区分。

CString DM_instr_list[] = { _T("::1::"), //HEWLETT-PACKARD,34420A,0,10.0-5.0-3.0
                            _T("::2::"), //HEWLETT-PACKARD,34420A,0,10.0-5.0-3.0
                            _T("::3::"), //HEWLETT-PACKARD,34420A,0,10.0-5.0-3.0
                            _T("::4::"), //HEWLETT-PACKARD,34420A,0,10.0-5.0-3.0
                            _T("NULL")
                        };

一  扫描设备

int scanDMMeasureDev()
{
    ViStatus status;
    ViSession defaultRM, instr;
    ViFindList fList;
    ViChar desc[VI_FIND_BUFLEN];
    ViUInt32 numInstrs;
    //ViUInt16 iManf, iModel;
    int nIdx = 0;

    m_nOpenedNum = 0;
    for (int nn = 0; nn < DM_MAX_NUM; nn++)
    {
        viSession[nn] = 0;
    }

    status = viOpenDefaultRM(&defaultRM);
    if (status < VI_SUCCESS) {
        /* Error initializing VISA ... exiting */
        return status;
    }

    rm = defaultRM;

    /* Find all instruments in the system */
    status = viFindRsrc(defaultRM, "[GPIB]?*INSTR", &fList, &numInstrs, desc);
    if (status < VI_SUCCESS) {
        /* Error finding resources ... exiting */
        viClose(defaultRM);
        return status;
    }

    printf("find src: %s \n", desc);

    /* Open a session to each and determine if it matches */
    while (numInstrs--) {
        status = viOpen(defaultRM, desc, VI_NULL, VI_NULL, &instr);
        if (status < VI_SUCCESS) {
            viFindNext(fList, desc);
            continue;
        }
        printf("open : %s \n", desc);
        status = viSetAttribute(instr, VI_ATTR_TERMCHAR_EN, true);
        /* Set the timeout for message-based communication*/
        status = viSetAttribute(instr, VI_ATTR_TMO_VALUE, 5000);

        printf("set Attribute: %s \n", desc);
      
        /* We have a match, return the session without closing it */
        CString strTmp(desc);
        printf("find a device: %s \n", desc);
        int listnum = 0;
        while (DM_instr_list[listnum].CompareNoCase(_T("NULL")) != 0)
        {
            listnum++;
        }

        int i;
        for (i = 0; i < listnum; i++)
        {
            if (strTmp.Find(DM_instr_list[i]) >= 0)
            {
                printf("find a DM device! %s\n", desc);
                viSession[i] = instr;
                v34470A = instr;
                m_nOpenedNum++;
                break;
            }
        }

        //已打开的设备保存句柄,加入打开设备列表,不需要关闭。
        //viClose(instr);
        viFindNext(fList, desc);
    }

    viClose(fList);
    if (m_nOpenedNum > 0)
    {
        return m_nOpenedNum;
    }
    else
    {
        AfxMessageBox(_T("DM not in device list!"));
        /* No match was found, return an error */
        viClose(defaultRM);
        return VI_ERROR_RSRC_NFOUND;
    }
}

扫描时根据地址保存句柄,用于对应线程使用34420A句柄。

二、电压源初始化及设置

int initDMMeasuremode(ViSession v34470A)
{
        double PLC = 10;
        int idn_size = 200; // Set this variable to the maximum size of the array.
        char* idn = new char[idn_size];
        ViBoolean termDefaultv34470A = VI_TRUE;

        viSetAttribute(v34470A, VI_ATTR_TERMCHAR_EN, termDefaultv34470A);
        viQueryf(v34470A, "*IDN?\n", "%#t", &idn_size, idn);
        CString strDev(idn);
        if (strDev.Find(_T("34420A")) >= 0)
            PLC = 20;
        else
            PLC = 100;

        viPrintf(v34470A, "*CLS\n");
        viPrintf(v34470A, "*ESE %@1d\n", 1);
        viPrintf(v34470A, "*SRE %@1d\n", 32);
        viPrintf(v34470A, ":CONFigure:VOLTage:DC\n");
        viPrintf(v34470A, ":SENSe:VOLTage:DC:NPLCycles %@3lf\n", PLC);
        viPrintf(v34470A, ":SAMPle:COUNt %@1d\n", _SAMPLE_COUNT_);
        viSetAttribute(v34470A, VI_ATTR_TMO_VALUE, 10000);

        printf("Digit Multimeter: %s \n", idn);

        delete[] idn;

        return 0;
}
设置采样平滑次数 及 触发时间。

三、电压源采数

double getDMData(ViSession session)
{
    int readings_size = _SAMPLE_COUNT_; // Set this variable to the maximum size of the array.
    double* readings = new double[readings_size];
    double ret_val = 0;

    viPrintf(session, ":INITiate:IMMediate\n");
    viPrintf(session, "*OPC\n");
    viQueryf(session, ":FETCh?\n", "%,#lf", &readings_size, readings);

    for (int i = 0; i < readings_size; i++)
    {
        ret_val += readings[i];
    }
    ret_val = ret_val / readings_size;

    delete[] readings;

    return ret_val;
}

根据采样平滑次数,获取数据,并做平均。

四、电压源Close

void DMClose(ViSession session)
{
    viClose(session);
}

void DMCloseAll()
{
    int nDMnum = m_nOpenedNum;
    int nn = DM_MAX_NUM;
    while (nDMnum--)
    {
        while (--nn >= 0)
        {
            v34470A = viSession[nn];
            if (v34470A == 0)
                continue;
            else
                break;
        }

        DMClose(v34470A);
    }

    DMClose(rm);
}

上述就是对电压源的控制软件的编写,已经调试通过,可以完全控制电压源并正确读取电压值。

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值