当前位置: 首页 > news >正文

调用.net DLL让CANoe自动识别串口号

1.前言

CANoe9.0用CAPL控制数控电源_canoe读取程控电源电流值-CSDN博客

之前做CAPL通过串口控制数控电源,存在一个缺点:更换电脑需要改串口号

CSDN上有类似的博客,不过要收费,本文根据VID和PID来自动获取串口号,代码少,使用起来更方便

本文可以告诉大家

(1)C#中如何根据VID和PID来获取串口号

(2)CAPL如何调用C#的DLL

(3)如何获取设备的VID和PID

(4)如何创建C#的DLL

2.开发环境

2.1硬件环境

科睿源 KA3005P

2.2软件环境

Win10 + CANoe12.0 + VS2013

3.参考资料

CANoe Help文档

4.自动识别串口原理

4.1方案一

枚举所有串口,分别询问每个串口是否是指定设备,优点是通用,缺点是速度慢

4.2方案二

根据设备的VID和PID获取串口号,优点是速度快,缺点是只适合USB转串口,如果存在多个同类设备,仍然需要每个询问

由于KA3005P是USB接口的虚拟串口,因此我这里选择方案二

5.创建C# DLL

5.1 注意事项

5.2 创建DLL工程

5.3 代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.IO.Ports;
using UCANHelper;namespace SerialPortAutoDetect
{public class SerialPortAutoDetect{public static int GetAllPorts(int[] ports, int maxLength){var port_names = SerialPort.GetPortNames();int i = 0;for (i = 0; i < ports.Length && i < maxLength; i++){string num = port_names[i].Replace("COM", "");ports[i] = Convert.ToInt32(num);}return i;}public static int GetPortsByVidPid(int[] ports, int maxLength, ushort vid, ushort pid){List<string> names = USB_Help.ComPortNames(vid.ToString("X4"), pid.ToString("X4"));int i = 0;for (i = 0; i < names.Count && i < maxLength; i++){string num = names[i].Replace("COM", "");ports[i] = Convert.ToInt32(num);}return i;}}
}

USB_Help.cs

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;namespace UCANHelper
{class USB_Help{#region 根据VID PID通过注册表获取端口号public static List<string> ComPortNames(String VID, String PID){//https://cloud.tencent.com/developer/ask/sof/115144954RegistryKey rk1 = Registry.LocalMachine;RegistryKey rk2 = rk1.OpenSubKey("SYSTEM\\CurrentControlSet\\Enum");String pattern = String.Format("^VID_{0}.PID_{1}", VID, PID);Regex _rx = new Regex(pattern, RegexOptions.IgnoreCase);List<string> ports = new List<string>();string[] pc_com_ports = SerialPort.GetPortNames();foreach (String s3 in rk2.GetSubKeyNames()){RegistryKey rk3 = rk2.OpenSubKey(s3);foreach (String s in rk3.GetSubKeyNames()){if (_rx.Match(s).Success){RegistryKey rk4 = rk3.OpenSubKey(s);foreach (String s2 in rk4.GetSubKeyNames()){RegistryKey rk5 = rk4.OpenSubKey(s2);RegistryKey rk6 = rk5.OpenSubKey("Device Parameters");string port_name = (string)rk6.GetValue("PortName");if (port_name != null && pc_com_ports.Contains<string>(port_name)){ports.Add(port_name);}}}}}return ports;}#endregion}
}

编译,生成SerialPortAutoDetect.dll

6.获取设备的VID和PID

在设备管理器中,找到端口,右击属性

7.CAPL中访问

仅有初始化部分,其他的参考之前的博客

includes
{#pragma netlibrary("..\DLL\SerialPortAutoDetect.dll")
}variables
{// GLOBALconst int kBUFFER_SIZE = 1000;const int kINFO        = 1;const int kWARN        = 2;const int kERROR       = 3;const int kHANDSHAKE_DISABLED = 0;const int kHANDSHAKE_RTSCTS   = 33;// define for dp serial port com9dword port = 6;const dword baudrate = 9600;const dword dataBits = 8;const dword stopBits = 1;const dword parity = 0;//0:none 1:even 0:odd// data is copied from callback buffer to gReceiverBuffer (collects data)byte gReceiverCallbackBuffer[kBUFFER_SIZE];byte gReceivedBuffer[kBUFFER_SIZE];dword gReceivedIndex= 0;// state variablebyte gSending = 0;byte gGetValueSt = 0;byte gSetValueSt = 0;msTimer t100ms;msTimer t20ms;dword vid = 0x0416;dword pid = 0x5011;
}on preStart
{InitSerialPort();  
}on start
{setTimer(t100ms,100);
}
//RS232 Init
InitSerialPort()
{long ports[10];long count=0;count=SerialPortAutoDetect::SerialPortAutoDetect::GetPortsByVidPid(ports,10,vid,pid);if(count > 0){port=ports[0];writeLineEx(0,kINFO,"Find %d serial port, use first serial port: %d.", count, port);}else{writeLineEx(0,kINFO,"Can not find any serial port, use default serial port %d.", port);}    // close serial port (port may have changed, former port shall not remain open)if(Rs232Close(port)!=1)writeLineEx(0,kERROR,"An error occurred during closing of the serial port %d.", port);    // set state (close aborts all open requests)gSending = 0;// open the serial port (comes up with Windows defaults)if(Rs232Open(port)==1)writeLineEx(0,kINFO, "Serial port %d successfully opened.", port);    elsewriteLineEx(0,kERROR,"An error occurred during opening of the serial port %d.", port);    // configure the serial port// - just take the panel contentif(Rs232Configure(port,baudrate,dataBits,stopBits,parity)==1)writeLineEx(0,kINFO, "Serial port %d successfully initialized.", port);    elsewriteLineEx(0,kERROR,"An error occurred during initialization of the serial port %d.", port);    // port, handshake, xonLim, xoffLim, xonChar, xoffChar, writeTimeout// without last timeout parameter: use default timeout// for transmission of small amounts of data one may not need to use handshake ! // e.g. 33 for RTS/CTS as second parameter for large volumes of data, 0 for small volumesif(Rs232SetHandshake(port, kHANDSHAKE_DISABLED, 0, 0, 0, 0))writeLineEx(0,kINFO, "Handshake parameters for serial port %d successfully configured.", port);    elsewriteLineEx(0,kERROR,"An error occurred during the serial port %d configuration of handshake parameters.", port);// set buffer for reception (otherwise callback would not work)if(Rs232Receive(port, gReceiverCallbackBuffer, kBUFFER_SIZE))writeLineEx(0,kINFO, "Receiver buffer for serial port %d successfully set.", port);    elsewriteLineEx(0,kERROR,"An error occurred during setting the receiver buffer for serial port %d.", port);
}

8.测试

可以正确识别到串口3

相关文章:

  • 数据库完整性
  • 【吾爱】逆向实战crackme160破解记录(二)
  • 从“remote rejected”看git角色区别,Maintainer和Devoloper
  • GaLore:基于梯度低秩投影的大语言模型高效训练方法详解一
  • 开发体育比分平台,有哪些坑需要注意的
  • 深入对比主流Java Web服务器与框架
  • 前端​​HTML contenteditable 属性使用指南
  • 黑马Java面试笔记之 消息中间件篇(RabbitMQ)
  • 【办公类-48-04】202506每月电子屏台账汇总成docx-5(问卷星下载5月范围内容,自动获取excel文件名,并转移处理)
  • MybatisPlus--核心功能--service接口
  • PHP+mysql 美容美发预约小程序源码 支持DIY装修+完整图文搭建教程
  • 对 `llamafactory-cli api -h` 输出的详细解读
  • 【python与生活】用 Python 从视频中提取音轨:一个实用脚本的开发与应用
  • 【前端后端环境】
  • 燃尽图和甘特图
  • 【结构型模式】装饰器模式
  • 如何轻松地将数据从 iPhone传输到iPhone 16
  • godwork_ AT 5.2 摄影测量空三数据处理软件。
  • Monorepo 详解:现代前端工程的架构革命
  • OpenCV CUDA模块霍夫变换------在 GPU 上执行概率霍夫变换检测图像中的线段端点类cv::cuda::HoughSegmentDetector
  • 网站开发属于什么软件/百度识图网页版入口
  • 房屋装修设计网站/网站内容seo
  • 网站源码带采集/软文案例短篇
  • 有哪些做问卷调查赚钱的网站6/黑帽seo优化推广
  • 郑州网站建设哪家最好/微信小程序建站
  • 软件二次开发/seo搜索方法