通过NI-VISA收发串口消息和socket TCP消息
1.安装NI-VISA 从 www.ni.com 下载并安装
开发环境和运行环境都需要安装,后得到 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软件自带的监控工具监控,打开 关闭 收数据 发数据 操作
红色代表失败
标签:
MFC VC++ 奇技淫巧
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义