通过NI-VISA收发串口消息和socket TCP消息

1.安装NI-VISA    从 www.ni.com 下载并安装

下载NI-VISA - NI

开发环境和运行环境都需要安装,后得到 visa.h  visa32.lib visatype.h,安装软件后运行环境目录并不需要visa32.dll文件就能运行

 2.安装后在   C:\Users\Public\Documents\National Instruments\NI-VISA\Examples\C  这个目录有一个C代码的visa使用例子可以自己打开看看  Examples_MSVC.dsw

 

3.把自己写的代码附上,“添加现有项”  把 visa.h  visa32.lib visatype.h 添加到自己的项目中

 1 #pragma once
 2 
 3 #include "NI/visa.h"
 4 
 5 
 6 class CVisaDevice
 7 {
 8 public:
 9     CVisaDevice();
10     virtual ~CVisaDevice();
11 
12     ViSession defRM;//VISA句柄
13     ViSession hViSession;//资源句柄
14     UINT m_iTimeOut;//超时时间
15     BOOL m_bOpenDevState;//设备打开状态
16 
17 
18     BOOL VisaInitSerialPort(CWnd* pPortOwner, UINT iPortNumber, UINT iBaud, UINT iDataBits = 8, UINT iStopBits = 10, UINT iCheckBits = 0);
19     BOOL VisaInitLanPort(CWnd* pPortOwner, char* cpIP, UINT iPort);
20     void VisaCloseDevice();
21     void VisaClearBuf();
22     int VisaWriteData(const char* szBuf, ...);
23     int VisaReadData(char* cRead, int iMaxLen = 128);
24 };
  1 #include "pch.h"
  2 #include "CVisaDevice.h"
  3 
  4 
  5 CVisaDevice::CVisaDevice()
  6 {
  7     m_iTimeOut = 500;//如果ViRead没有读到数据时,函数的返回时间
  8     m_bOpenDevState = FALSE;
  9 }
 10 
 11 
 12 CVisaDevice::~CVisaDevice()
 13 {
 14 
 15 }
 16 
 17 
 18 BOOL CVisaDevice::VisaInitSerialPort(CWnd* pPortOwner, UINT iSerialPort, UINT iBaud, UINT iDataBits, UINT iStopBits, UINT iCheckBits)
 19 {
 20     ViStatus status;
 21     status = viOpenDefaultRM(&defRM);//打开缺省资源管理器资源对话通道
 22     if (status < VI_SUCCESS)
 23     {
 24         //AfxMessageBox(_T("无法打开VISA资源对话"));
 25         return FALSE;
 26     }
 27 
 28     ViChar resourceName[256] = "";
 29     memset(resourceName, 0, sizeof(resourceName));
 30     sprintf_s(resourceName, "ASRL%d::INSTR", iSerialPort);
 31 
 32     status = viOpen(defRM, resourceName, VI_NULL, VI_NULL, &hViSession);
 33     if (status < VI_SUCCESS)
 34     {
 35         //AfxMessageBox(_T("无法打开设备会话"));
 36         status = viClose(hViSession);
 37         status = viClose(defRM);
 38         return FALSE;
 39     }
 40     //设置超时时间
 41     status = viSetAttribute(hViSession, VI_ATTR_TMO_VALUE, m_iTimeOut);
 42     //设置波特率
 43     status = viSetAttribute(hViSession, VI_ATTR_ASRL_BAUD, iBaud);
 44     //设置数据位  5-8
 45     status = viSetAttribute(hViSession, VI_ATTR_ASRL_DATA_BITS, iDataBits);
 46     //设置校验位 0VI_ASRL_PAR_NONE   1VI_ASRL_PAR_ODD          2VI_ASRL_PAR_EVEN     3VI_ASRL_PAR_MARK     4VI_ASRL_PAR_SPACE
 47     status = viSetAttribute(hViSession, VI_ATTR_ASRL_PARITY, iCheckBits);
 48     //设置停止位 1VI_ASRL_STOP_ONE 10   1.5VI_ASRL_STOP_ONE_5 15     2VI_ASRL_STOP_TWO 20
 49     status = viSetAttribute(hViSession, VI_ATTR_ASRL_STOP_BITS, iStopBits);
 50     //是否允许终止符
 51     status = viSetAttribute(hViSession, VI_ATTR_TERMCHAR_EN, VI_TRUE);
 52     //设置终止符
 53     status = viSetAttribute(hViSession, VI_ATTR_TERMCHAR, 0xA);//换行键 \n
 54 
 55 
 56     m_bOpenDevState = TRUE;
 57     return TRUE;
 58 }
 59 
 60 
 61 BOOL CVisaDevice::VisaInitLanPort(CWnd* pPortOwner, char* cpIP, UINT iPort)
 62 {
 63     ViStatus status;
 64     status = viOpenDefaultRM(&defRM);
 65     if (status < VI_SUCCESS)
 66     {
 67         //AfxMessageBox(_T("无法打开VISA资源对话"));
 68         return FALSE;
 69     }
 70 
 71     ViChar resourceName[256] = "";   //--------------需要根据config赋值
 72     memset(resourceName, 0, sizeof(resourceName));
 73     sprintf_s(resourceName, "TCPIP0::%s::%d::SOCKET", cpIP, iPort);
 74 
 75     status = viOpen(defRM, resourceName, VI_NULL, VI_NULL, &hViSession);
 76     if (status < VI_SUCCESS)
 77     {
 78         //AfxMessageBox(_T("打开 SOCKET 失败"));
 79         status = viClose(hViSession);
 80         status = viClose(defRM);
 81         return FALSE;
 82     }
 83 
 84     //设置超时时间
 85     viSetAttribute(hViSession, VI_ATTR_TMO_VALUE, m_iTimeOut);
 86     //这个不知道是啥
 87     viSetAttribute(hViSession, VI_ATTR_TCPIP_NODELAY, VI_TRUE);
 88     //是否允许终止符
 89     status = viSetAttribute(hViSession, VI_ATTR_TERMCHAR_EN, VI_TRUE);
 90     //设置终止符
 91     status = viSetAttribute(hViSession, VI_ATTR_TERMCHAR, 0xA);//换行键 \n
 92 
 93     m_bOpenDevState = TRUE;
 94     return TRUE;
 95 }
 96 
 97 
 98 void CVisaDevice::VisaCloseDevice()
 99 {
100     viClose(hViSession); //关闭特定的对话通道
101     viClose(defRM); //关闭特定的对话通道
102     m_bOpenDevState = FALSE;
103 }
104 
105 
106 void CVisaDevice::VisaClearBuf()
107 {
108     viClear(hViSession);//清除缓存
109 }
110 
111 //返回实际写入长度   参数1写入buf
112 int CVisaDevice::VisaWriteData(const char* szBuf, ...)
113 {
114     if (!m_bOpenDevState)
115     {
116         return -1;
117     }
118 
119     ViUInt32 writeCount = 0;//写的实际长度
120     ViStatus status;
121 
122     va_list arg;
123     char szCmd[128] = { 0 };
124     va_start(arg, szBuf);
125     vsprintf_s(szCmd, sizeof(szCmd), szBuf, arg);
126     va_end(arg);
127 
128     status = viWrite(hViSession, (ViBuf)szCmd, strlen(szCmd), &writeCount);
129     if (status < VI_SUCCESS)
130     {
131         //AfxMessageBox(_T("写入设备时出错"));
132         return -1;
133     }
134     else
135     {
136         return writeCount;
137     }
138 }
139 
140 //返回值读取长度   参数读取数据内容
141 int CVisaDevice::VisaReadData(char* cRead, int iMaxLen)
142 {
143     if (!m_bOpenDevState)
144     {
145         return -1;
146     }
147 
148     ViStatus status;
149     unsigned long iReadLen = 0;
150 
151     status = viRead(hViSession, (ViBuf)cRead, iMaxLen, &iReadLen);//读一次\n之间的内容,没有换行符则读最大长度
152     if (status < VI_SUCCESS)
153     {
154         //AfxMessageBox(_T("从设备读取响应时出错"));
155         return -1;
156     }
157     else
158     {
159         return iReadLen;
160     }
161 }

调用,串口和网络都是相同的读写函数

VisaInitSerialPort(pPortOwner, iCom, iBaud);//串口方式
VisaInitLanPort(pPortOwner, strIP.GetBuffer(0), iPort);//网络方式

    //发送指令
    int writeLen = VisaWriteData("*IDN?\r\n");
    if (writeLen <= 0)
    {
        LeaveCriticalSection(&m_csCmdLock);
        return FALSE;
    }
  Sleep(100);//等一会再读返回值
    //读返回数据
    char szData[256] = { 0 };
    memset(szData, 0, sizeof(szData));
    int readlen = VisaReadData(szData);
    if (readlen <= 0)
    {
        LeaveCriticalSection(&m_csCmdLock);
        return FALSE;
    }

4.使用NI软件自带的监控工具监控,打开 关闭 收数据 发数据 操作

 

 红色代表失败

posted @ 2022-10-12 17:36  ckrgd  阅读(1286)  评论(0编辑  收藏  举报