NI-VISA 安装教程和IEEE-488通信(VS)

一、下载

波音747航班:https://www.ni.com/zh-cn/support/downloads/drivers/download.ni-visa.html#329456

选择合适的版本下载

 

二、安装

安装之前请关闭防火墙和其他杀毒软件等;

按照流程一路next即可。

 

三、.lib、.dll、.h文件位置

64位WIN10系统为例,.lib文件和.h文件在“C:\Program Files\IVI Foundation\VISA\Win64”目录下的include和lib_x64目录下,.dll文件在“C:\Windows\System32”和“C:\Windows\SysWOW64”中

 

四、案例

1】ComPort.h

#pragma once

#include <string>
#include <atlconv.h>
#include <map>

//包含VISA头文件和库文件
#include "visa.h"   

 #ifdef COMMUNICATION_EXPORTS
 #define COMMUNICATION_API __declspec(dllexport)
 #else
 #define COMMUNICATION_API __declspec(dllimport)
 #endif

//通信基类
class COMMUNICATION_API CComPort
{
protected:
	//通信口是否已打开
	bool m_bIsOpened;
	//通信接口的互斥锁
    CRITICAL_SECTION m_csComm;

public:
	CComPort(void);
	virtual ~CComPort(void);

public:
	//打开通信端口
	virtual bool Open(std::string strParam) = 0;

	//关闭通信端口
	virtual void Close(void) = 0;

	//发送数据
	virtual int Send(const unsigned char *cData, int nLen) = 0;

	//接收数据
	virtual int Recv(unsigned char *cData, int nLen) = 0;

	//重新打开通信口
	virtual bool ReOpen(void) = 0;

	//通信口可能同时只能供一个线程调用,使用时请求锁
	virtual bool TryToLock(bool bMode = true);

	//线程使用完串口后,为通信口实例释放锁
	virtual void ReleaseLock(void);

	//通信口是够已经打开
	virtual bool IsOpened(void) { return m_bIsOpened; }
};

2】ComPort.cpp

#include "stdafx.h"
#include "ComPort.h"


CComPort::CComPort(void)
{
	m_bIsOpened = false;
	InitializeCriticalSection(&m_csComm); 
}


CComPort::~CComPort(void)
{
	DeleteCriticalSection(&m_csComm);
}

//通信口可能同时只能供一个线程调用,使用时请求锁
bool CComPort::TryToLock(bool bMode)
{
	EnterCriticalSection(&m_csComm);
	return true;
}

//线程使用完串口后,为通信口实例释放锁
void CComPort::ReleaseLock(void)
{
	LeaveCriticalSection(&m_csComm);
}

 

3】IEEE488Port.h

#pragma once
#include "comport.h"


class CComIEEE488Fun
{
public:
	//校验位类型和int的对应
	static std::map<std::string, int> cComParityMap;
};

//IEEE-488通信类
class COMMUNICATION_API CIEEE488Port :
	public CComPort
{
private:
	//IEEE-488通信口地址
	char *m_pStrIEEEAddress;

	//IEEE-488参数
	char *m_pStrIEEEParam;

	// 默认资源管理器会话的唯一逻辑标识符。
	ViSession m_vfaultRM;
	//IEEE-488句柄
	ViSession m_vIEEEHandle;

public:
	CIEEE488Port(void);
	virtual ~CIEEE488Port(void);

public:
	//打开通信端口
	virtual bool Open(std::string strParam);

	//关闭通信端口
	virtual void Close(void);

	//发送数据
	virtual int Send(const unsigned char *cData, int nLen);

	//接收数据
	virtual int Recv(unsigned char *cData, int nLen);

	//重新打开通信口
	virtual bool ReOpen(void);

private:
	//解析Open函数传递过来的串口参数
	bool parseOpenParam(std::string strParam);

	//设置初始化参数,如缓冲区大小和超时时间等
	bool initSetting(void);
};

4】IEEE488Port.cpp

#include "stdafx.h"
#include "IEEE488Port.h"

std::pair<std::string, int> pairParityType[]= 
{
	std::make_pair("N", 0),
	std::make_pair("O", 1),
	std::make_pair("E", 2),
	std::make_pair("M", 3),
	std::make_pair("S", 4),

};
std::map<std::string, int> CComIEEE488Fun::cComParityMap(pairParityType, pairParityType+sizeof(pairParityType)/sizeof(pairParityType[0]));


CIEEE488Port::CIEEE488Port(void) : CComPort()
{
	// 存放IEEE-488通信地址
	m_pStrIEEEAddress = new char[128];
	m_pStrIEEEAddress[0]=0;
	// 存放参数
	m_pStrIEEEParam = new char[32];
	m_pStrIEEEParam[0] = 0;
}


CIEEE488Port::~CIEEE488Port(void)
{
	//试图关闭通信口
	Close();

	delete []m_pStrIEEEAddress;
	delete []m_pStrIEEEParam;
}

//打开通信端口
bool CIEEE488Port::Open(std::string strParam)
{
	//通信口已被打开
	if(m_bIsOpened)
		return true;

	//解析IEEE-488通信口打开参数
	if(parseOpenParam(strParam)==false)
	{
		return false;
	}

	// 初始化一个VISA资源管理器
	ViStatus status = viOpenDefaultRM (&m_vfaultRM);
	if(status!= VI_SUCCESS)
		return false;
	//打开IEEE-488通信口,并创建操作句柄
	status = viOpen(m_vfaultRM, m_pStrIEEEAddress,VI_NULL,VI_NULL, &m_vIEEEHandle);
	if(status != VI_SUCCESS)
	{
		return false;
	}
	
	//设置IEEE-488通信口初始化参数
	if(initSetting()==false)
		return false;

	m_bIsOpened = true;
	return true;
}

//关闭通信端口
void CIEEE488Port::Close(void)
{
	if(m_bIsOpened==false)
		return;

	// viClose:关闭特定的会话、事件或查找列表
	viClose(m_vIEEEHandle);
	viClose (m_vfaultRM);
	m_bIsOpened = false;
}

//发送数据
int CIEEE488Port::Send(const unsigned char *cData, int nLen)
{
	ViPUInt16 status = NULL;
	DWORD dwRealSend = 0;

	if(m_bIsOpened==false)
		return -1;

	如果IEEE-488有错误,则清除输入/输出缓冲区
	viReadSTB(m_vIEEEHandle, status);
	if(status != VI_SUCCESS)
	{
		// 终止操作(VISA将中止当前进程中对指定vi执行的任何调用)
		viTerminate(m_vIEEEHandle, VI_NULL,  VI_NULL);
		//格式化指定缓冲区
		viFlush(m_vIEEEHandle,VI_WRITE_BUF_DISCARD);
	}
	
	//写数据(同步)
	// viPrintf(m_vIEEEHandle, (ViString)cData)
	if(viWrite(m_vIEEEHandle, cData, nLen, &dwRealSend) != VI_SUCCESS)
	{
		return -2;
	}

	//返回实际发送的数据大小
	return dwRealSend;
}

//接收数据
int CIEEE488Port::Recv(unsigned char *cData, int nLen)
{
	ViPUInt16 status = NULL;
	DWORD dwRealRead = 0;
	
	if(m_bIsOpened==false)
		return -1;

	//如果IEEE-488有错误,则清除输入/输出缓冲区
	viReadSTB(m_vIEEEHandle, status);
	if(status != VI_SUCCESS)
	{
		// 终止操作(VISA将中止当前进程中对指定vi执行的任何调用)
		viTerminate(m_vIEEEHandle, VI_NULL,  VI_NULL);
		 //格式化指定缓冲区
		viFlush(m_vIEEEHandle,VI_READ_BUF_DISCARD);
	}

	//读数据(同步)
	// 从设备读取一个字符串,然后格式化后保存值dwRealRead中(隐式分割符是被忽略的)
	// viScanf(m_vIEEEHandle, (ViString)cData)
	if(viRead(m_vIEEEHandle, cData, nLen, &dwRealRead) != VI_SUCCESS)
	{
		return -2;
	}

	return dwRealRead;
}

//重新打开通信口
bool CIEEE488Port::ReOpen(void)
{
	if(strlen(m_pStrIEEEAddress)==0 || strlen(m_pStrIEEEParam)==0)
		return false;

	//关闭通信口
	Close();

	//打开通信口
	std::string strParam = m_pStrIEEEAddress + std::string(";") + m_pStrIEEEParam;
	return Open(strParam);
}

//解析Open函数传递过来的串口参数
bool CIEEE488Port::parseOpenParam(std::string strParam)
{
	//寻找IEEE-488通信地址的结束位置(";"号)
	std::size_t nFound = strParam.find(';');
	//未找到通信口名
	if (nFound==std::string::npos)
		return false;
	
	//分解参数字符串为端口名和参数两个部分
	strcpy_s(m_pStrIEEEAddress, 128, strParam.substr(0, nFound).c_str());
	strcpy_s(m_pStrIEEEParam, 32, strParam.substr(nFound+1).c_str());

	return true;
}

//设置初始化参数,如缓冲区大小和超时时间等
bool CIEEE488Port::initSetting(void)
{
	//设置I/O读/写缓冲区大小(初始化一个指定的通信设备的通信参数。)
	if(!viSetBuf(m_vIEEEHandle, VI_READ_BUF|VI_WRITE_BUF, 1024))
	{
		Close();
		return false;
	}

	//设置超时参数
	viSetAttribute(m_vIEEEHandle,VI_ATTR_TMO_VALUE,1000);

	//格式化指定缓冲区
	viFlush(m_vIEEEHandle,VI_READ_BUF |VI_WRITE_BUF);

	/******************************************************/
	//开始设置通信口的波特率,数据位,停止位,流控,校验等参数
	char **cRemainder = NULL;
	char* cBaud = strtok_s(m_pStrIEEEParam, ",", cRemainder);
	viSetAttribute(m_vIEEEHandle,VI_ATTR_ASRL_BAUD, atoi(cBaud));
	char* cDataBits = strtok_s(NULL, ",", cRemainder);
	viSetAttribute(m_vIEEEHandle,VI_ATTR_ASRL_DATA_BITS, atoi(cDataBits));
	char* cParity = strtok_s(NULL, ",", cRemainder);
	viSetAttribute(m_vIEEEHandle,VI_ATTR_ASRL_PARITY, CComIEEE488Fun::cComParityMap[cParity]);
	char* cStopBits = strtok_s(NULL, ",", cRemainder);
	viSetAttribute(m_vIEEEHandle,VI_ATTR_ASRL_STOP_BITS, atoi(cStopBits));

	return true;
}

【注】请自觉在项目属性页->【配置属性】->【链接器】->【常规】->【附加库目录】中添加所需lib文件所在位置;

            项目属性页->【配置属性】->【链接器】->【输入】->【附加依赖项】中添加所需.lib文件;

             dll文件需放在项目对应的目录下。

【注】具体的信息参见“NI-VISA用户手册和NI-VISA程序员参考手册.zip”,网上有资源,请自行搜索。

  • 2
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值