调用.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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/84102.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot十二、SpringBoot系列web篇之过滤器Filte详解

一、前言 JavaWeb三大组件Servlet、Filter、Listener&#xff0c;其中之一便是过滤器Filter。 其实&#xff0c;Filter我们平常用的不多&#xff0c;一般多为项目初期搭建web架构的时候使用&#xff0c;后面用的就少了&#xff0c;在日常业务开发中不太可能碰到需要手写Filte…

Java实现飞机射击游戏:从设计到完整源代码

JAVA打飞机游戏毕业设计 一、游戏概述 本游戏基于Java Swing开发&#xff0c;实现了经典的飞机射击游戏。玩家控制一架战斗机在屏幕底部移动&#xff0c;发射子弹击落敌机&#xff0c;同时躲避敌机攻击。游戏包含多个关卡&#xff0c;随着关卡提升&#xff0c;敌机速度和数量…

通俗易懂linux环境变量

如果想要清楚的了解环境变量&#xff0c;我觉得我们需要先大致搞清楚一个简单的事——什么是会话&#xff1f; 会话大致是什么&#xff1f; 在这里我们的目的是更好的理解环境变量&#xff0c;所以适当讲解一下会话即可。通常我们都是用xshell连接远程服务器&#xff0c;都会打…

【补题】Codeforces Round 715 (Div. 2) C. The Sports Festival

题意&#xff1a;给你一个序列&#xff0c;你可以对它重新排序&#xff0c;然后使每个i&#xff0c;max(a0,a1……ai)-min(a0,a1……ai)最小。问答案是多少 思路&#xff1a; C. The Sports Festival&#xff08;区间DP&#xff09;-CSDN博客 区间dp&#xff0c;完全没想到…

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]

报错信息&#xff1a;libc.so.6: cannot open shared object file: No such file or directory&#xff1a; #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…

SIFT算法详细原理与应用

SIFT算法详细原理与应用 1 SIFT算法由来 1.1 什么是 SIFT&#xff1f; SIFT&#xff0c;全称为 Scale-Invariant Feature Transform&#xff08;尺度不变特征变换&#xff09;&#xff0c;是一种用于图像特征检测和描述的经典算法。它通过提取图像中的局部关键点&#xff0c;…

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…

Go字符串切片操作详解:str1[:index]

在Go语言中&#xff0c;return str1[:index] 是一个​​字符串切片操作​​&#xff0c;它截取字符串的一部分。让我们深入解析这个操作的含义和原理&#xff1a; 基本语法和含义 str1&#xff1a;原始字符串[:index]&#xff1a;切片操作符str1[:index]&#xff1a; ​​起始…

NVIDIA Dynamo:数据中心规模的分布式推理服务框架深度解析

NVIDIA Dynamo&#xff1a;数据中心规模的分布式推理服务框架深度解析 摘要 NVIDIA Dynamo是一个革命性的高吞吐量、低延迟推理框架&#xff0c;专为在多节点分布式环境中服务生成式AI和推理模型而设计。本文将深入分析Dynamo的架构设计、核心特性、代码实现以及实际应用示例&…

408第一季 - 数据结构 - 栈与队列的应用

括号匹配 用瞪眼法就可以知道的东西 栈在表达式求值运用 先简单看看就行&#xff0c;题目做了就理解了 AB是操作符,也是被狠狠加入后缀表达式了&#xff0c;然后后面就是*&#xff0c;只要优先级比栈顶运算符牛逼就放里面&#xff0c;很显然&#xff0c;*比牛逼 继续前进&#…

Ubuntu 下开机自动执行命令的方法

Ubuntu 下开机自动执行命令的方法&#xff08;使用 crontab&#xff09; 在日常使用 Ubuntu 或其他 Linux 系统时&#xff0c;我们常常需要让某些程序或脚本在系统启动后自动运行。例如&#xff1a;启动 Clash 代理、初始化服务、定时同步数据等。 本文将介绍一种简单且常用的…

jpackage 打包 jar包 为exe可执行程序

jpackage --input target/ --main-jar note.jar --runtime-image H:/Dpanbeifeng/apps/finalshell/jre --type app-image --dest output/ --main-class com.textmanager.Main --icon logo2.png --name 猫咪快笔记 jpackage 打包指令详细介绍 jpackage 概述 jpackage 是…

H5移动端性能优化策略(渲染优化+弱网优化+WebView优化)

一、渲染优化&#xff1a;首屏速度提升的核心​​ ​​1. 关键页面采用SSR或Native渲染​​ ​​适用场景​​&#xff1a;首页、列表页、详情页等强内容展示页面 ​​优化原理​​&#xff1a; ​​SSR&#xff08;服务端渲染&#xff09;​​&#xff1a;在服务端生成完整…

Matlab | matlab中的图像处理详解

MATLAB 图像处理详解 这里写目录标题图像处理 MATLAB 图像处理详解一、图像基础操作1. 图像读写与显示2. 图像信息获取3. 图像类型转换二、图像增强技术1. 对比度调整2. 去噪处理3. 锐化处理三、图像变换1. 几何变换2. 频域变换四、图像分割1. 阈值分割2. 边缘检测3. 区域分割五…

keysight是德科技N9923A网络分析仪

keysight是德科技N9923A网络分析仪 简  述&#xff1a;N9923A 是一款使用电池供电的便携式射频矢量网络分析仪&#xff0c;其中包括全 2 端口网络分析仪、电缆和天线测试仪、故障点距离测试仪、功率计以及 1 通道和 2 通道矢量电压表。 主要特性与技术指标 网络分析仪 * 2…

idea不识别lombok---实体类报没有getter方法

介绍 本篇文章&#xff0c;主要讲idea引入lombok后&#xff0c;在实体类中加注解Data&#xff0c;在项目启动的时候&#xff0c;编译不通过&#xff0c;报错xxx.java没有getXxxx&#xff08;&#xff09;方法。 原因有以下几种 1. idea没有开启lombok插件 2. 使用idea-2023…

本地主机部署开源企业云盘Seafile并实现外部访问

Seafile是一个开源、专业、可靠的云存储平台&#xff1b;解决文件集中存储、共享和跨平台访问等问题。这款软件功能强大&#xff0c;界面简洁、操作方便。 本文将详细的介绍如何利用本地主机部署 Seafile&#xff0c;并结合nat123&#xff0c;实现外网访问本地部署的 Seafile …

【从0-1的CSS】第1篇:CSS简介,选择器以及常用样式

文章目录 CSS简介CSS的语法规则选择器id选择器元素选择器类选择器选择器优先级 CSS注释 CSS常用设置样式颜色颜色名称(常用)RGB(常用)RGBA(常用)HEX(常用)HSLHSLA 背景background-colorbackground-imagebackground-size 字体text-aligntext-decorationtext-indentline-height 边…

SpringBoot+MySQL家政服务平台 设计开发

概述 基于SpringBootMySQL开发的家政服务平台完整项目&#xff0c;该系统实现了用户预约、服务管理、订单统计等核心功能&#xff0c;采用主流技术栈开发&#xff0c;代码规范且易于二次开发。 主要内容 系统功能架构 本系统采用前后端分离架构&#xff0c;前端提供用户交互…

3.1 HarmonyOS NEXT分布式数据管理实战:跨设备同步、端云协同与安全保护

HarmonyOS NEXT分布式数据管理实战&#xff1a;跨设备同步、端云协同与安全保护 在万物互联的时代&#xff0c;数据的跨设备流转与安全共享是全场景应用的核心需求。HarmonyOS NEXT通过分布式数据管理技术&#xff0c;实现了设备间数据的实时同步与端云协同&#xff0c;为开发…