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

艾德克斯负载电源控制代码(C#)

封装成Dll文件,using MyTools; 后调用。

应用先实例化和声明数组。

        readonly UART uartLoad = new UART(26);//接收26个字节触发串口数据readonly UART uartPowr = new UART(1);//接收1个字节触发串口数据,如果不带参数,则默认为1readonly IT68XX IT68XX = new IT68XX();readonly IT85XX IT85XX = new IT85XX();private readonly SerialPort _sp1 = new SerialPort();private readonly SerialPort _sp2 = new SerialPort();private double factor = 1.0;  // 负载获得数据需要按倍数转换byte[] buf=new byte[26];  // 数据缓存区

dll文件源码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Threading;namespace MyTools
{/// <summary>/// 串口通信类,提供串口的基本操作功能/// </summary>public class UART
{// 添加:定义数据接收事件public event SerialDataReceivedEventHandler DataReceived;// 添加:存储接收阈值private int _receivedBytesThreshold = 1;// 添加:无参构造函数,默认阈值为1public UART(){_receivedBytesThreshold = 1;}// 添加:带参数的构造函数,可设置阈值public UART(int receivedBytesThreshold){_receivedBytesThreshold = receivedBytesThreshold;}public void Set_Open(SerialPort _sp, string com, int baudRate = 9600)//串口打开
    {if (_sp.IsOpen)_sp.Close();  // 如果串口已打开,先关闭
_sp.PortName = com;           // 设置串口号_sp.BaudRate = baudRate;      // 设置波特率_sp.DataBits = 8;             // 设置数据位为8位_sp.StopBits = StopBits.One;  // 设置停止位为1位_sp.Parity = Parity.None;     // 设置无校验位_sp.ReceivedBytesThreshold = _receivedBytesThreshold;// 设置接收字节数阈值// 添加:注册数据接收事件_sp.DataReceived += _sp_DataReceived;_sp.Open();}public void Set_Close(SerialPort _sp)//串口关闭
    {// 添加:注销事件,避免内存泄漏_sp.DataReceived -= _sp_DataReceived;//SP.RtsEnable = false;//开启请求发送if (_sp.IsOpen)_sp.Close();//串口关闭
    }public void Get_PortNames(out string[] Port)//获取所有可用的串口号
    {Port = SerialPort.GetPortNames();}public void Send_string(SerialPort _sp, string sendData){if (_sp.IsOpen)_sp.Write(sendData);  // 通过串口发送字符串
    }public void Send_bytes(SerialPort _sp, byte[] sendData){if (_sp.IsOpen)_sp.Write(sendData, 0, sendData.Length);  // 通过串口发送字节数组
    }public void Send_hex(SerialPort _sp, string hexString){// 移除空格和连字符hexString = hexString.Replace(" ", "").Replace("-", "");// 创建字节数组,长度为十六进制字符串的一半byte[] bytes = new byte[hexString.Length / 2];// 将每两个字符转换成一个字节for (int i = 0; i < hexString.Length; i += 2){// 将十六进制子串转换为字节bytes[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16);}// 调用字节数组发送方法
        Send_bytes(_sp, bytes);}public bool IsOpen(SerialPort _sp){return _sp.IsOpen;  // 返回串口打开状态
    }// 添加:内部事件处理方法private void _sp_DataReceived(object sender, SerialDataReceivedEventArgs e){// 将事件转发给外部订阅者DataReceived?.Invoke(sender, e);}
}public class IT85XX{/// <summary>/// 负载控制/// </summary>/// <param name="SP"></param>/// <param name="Enum"></param>public void Send_Cmd(SerialPort _sp, IT85_Cmd Enum){if (!_sp.IsOpen) return;int checkSum = 0;byte[] bTransport = new byte[26];bTransport[0] = 0xAA;bTransport[1] = 0x00;// 通过特性获取命令配置var field = typeof(IT85_Cmd).GetField(Enum.ToString());var attr = (LoadCommandAttribute)field.GetCustomAttributes(typeof(LoadCommandAttribute), false)[0];bTransport[2] = attr.Byte2;//命令bTransport[3] = attr.Byte3;//命令扩展for (int i = 0; i < bTransport.Length - 1; i++)  // 计算checkSum
            {checkSum += bTransport[i];}bTransport[25] = (byte)(checkSum);// 发送_sp.Write(bTransport,0, bTransport.Length);}public void Set_Mode(SerialPort _sp, LoadMode mode){if (!_sp.IsOpen) return;int checkSum = 0;byte[] bTransport = new byte[26];bTransport[0] = 0xAA;bTransport[1] = 0x00;// 通过特性获取命令配置var field = typeof(LoadMode).GetField(mode.ToString());var attr = (LoadCommandAttribute)field.GetCustomAttributes(typeof(LoadCommandAttribute), false)[0];bTransport[2] = attr.Byte2;//命令bTransport[3] = attr.Byte3;//命令扩展for (int i = 0; i < bTransport.Length - 1; i++)  // 计算checkSum
            {checkSum += bTransport[i];}bTransport[25] = (byte)(checkSum);// 发送_sp.Write(bTransport,0, bTransport.Length);}public void Set_Value(SerialPort _sp, IT85_Set vawr, double setValue){if (!_sp.IsOpen) return;int checkSum = 0;short radix = 0;byte[] bTransport = new byte[26];bTransport[0] = 0xAA;bTransport[1] = 0x00;// 通过特性获取命令配置var field = typeof(IT85_Set).GetField(vawr.ToString());var attr = (LoadCommandAttribute)field.GetCustomAttributes(typeof(LoadCommandAttribute), false)[0];bTransport[2] = attr.Byte2;//命令bTransport[3] = attr.Byte3;//命令扩展if (attr.radix.HasValue){radix = attr.radix.Value;}string hex = ((Int32)(setValue * radix)).ToString("X8");bTransport[3] = (byte)Convert.ToInt32(hex.Substring(6, 2), 16);bTransport[4] = (byte)Convert.ToInt32(hex.Substring(4, 2), 16);bTransport[5] = (byte)Convert.ToInt32(hex.Substring(2, 2), 16);bTransport[6] = (byte)Convert.ToInt32(hex.Substring(0, 2), 16);for (int i = 0; i < bTransport.Length - 1; i++)  // 计算checkSum
            {checkSum += bTransport[i];}bTransport[25] = (byte)(checkSum);// 发送_sp.Write(bTransport, 0, bTransport.Length);}public void Send_GetCommand(SerialPort _sp, IT85_Get value){if (!_sp.IsOpen) return;int checkSum = 0;byte[] bTransport = new byte[26];bTransport[0] = 0xAA;bTransport[1] = 0x00;// 通过特性获取命令配置var field = typeof(IT85_Get).GetField(value.ToString());var attr = (LoadCommandAttribute)field.GetCustomAttributes(typeof(LoadCommandAttribute), false)[0];bTransport[2] = attr.Byte2;//命令bTransport[3] = attr.Byte3;//命令扩展for (int i = 0; i < bTransport.Length - 1; i++)  // 计算checkSum
            {checkSum += bTransport[i];}bTransport[25] = (byte)(checkSum);// 发送_sp.Write(bTransport, 0, bTransport.Length);}/// <summary>/// 获取负载结果(返回固定值:电流、电压、功率、电阻)/// </summary>/// <param name="SP">串口对象</param>/// <param name="Result">输出结果值</param>public double Get_str_Result(SerialPort SP, byte[] buffer){if (!SP.IsOpen)throw new InvalidOperationException("串口未打开");// 一行完成:组合字节 -> uint -> doublereturn (double)((uint)((buffer[6] << 24) | (buffer[5] << 16) | (buffer[4] << 8) | buffer[3]));}/// <summary>/// 获取负载结果(电压、电流、功率)- 字符串格式版本/// </summary>/// <param name="sp">串口对象</param>/// <returns>返回元组 (电压, 电流, 功率)</returns>public (string Voltage, string Current, string Power) Get_VCW_Result(SerialPort sp,byte[]buffer){// 参数验证if (sp == null || !sp.IsOpen){return ("0", "0", "0");}try{// 使用位运算高效解析数据(小端序)// 电压: 字节 3-6,除数 1000uint voltageRaw = (uint)((buffer[6] << 24) | (buffer[5] << 16) | (buffer[4] << 8) | buffer[3]);string voltage = (voltageRaw / 1000.0).ToString("0.0000");// 电流: 字节 7-10,除数 10000uint currentRaw = (uint)((buffer[10] << 24) | (buffer[9] << 16) | (buffer[8] << 8) | buffer[7]);string current = (currentRaw / 10000.0).ToString("0.000");// 功率: 字节 11-14,除数 1000uint powerRaw = (uint)((buffer[14] << 24) | (buffer[13] << 16) | (buffer[12] << 8) | buffer[11]);string power = (powerRaw / 1000.0).ToString("0.00");return (voltage, current, power);}catch{// 异常时返回默认值return ("0", "0", "0");}}}public class IT68XX{public void Send_Cmd(SerialPort _sp, IT68_Cmd Enum){if (!_sp.IsOpen) return; //如果串口关闭则退出_sp.DiscardInBuffer();//清空接收区缓存_sp.DiscardOutBuffer();//清空发送区缓存_sp.Write("*CLS" + "\n");//清除错误// 通过特性获取命令配置var field = typeof(IT68_Cmd).GetField(Enum.ToString());var attr = (PowrCommandAttribute)field.GetCustomAttributes(typeof(PowrCommandAttribute), false)[0];string cmd = attr.cmd;_sp.Write(cmd + "\n");// 只有特定命令需要额外的*CLS(根据原代码逻辑)if (cmd == "SYSTem:RWLock"){_sp.Write("*CLS" + "\n");}Thread.Sleep(100);}public void Set_VA(SerialPort _sp, double Voltage, double Current){if (_sp.IsOpen)//如果串口关闭则退出
            {//清空接收缓存_sp.DiscardInBuffer();//清空接收缓冲区_sp.Write("VOLTage " + Voltage.ToString() + "" + "\n");//设置电压_sp.Write("CURRent " + Current.ToString() + "" + "\n");//设置电流Thread.Sleep(100);}}/// <summary>/// 返回结果/// </summary>/// <param name="SP"></param>/// <param name="power"></param>public string Get_Str_Result(SerialPort SP){return SP.ReadLine();}}// 定义特性类
    [AttributeUsage(AttributeTargets.Field)]public class LoadCommandAttribute : Attribute{public byte Byte2 { get; set; }         //命令字public byte Byte3 { get; set; }         // 使用可空类型属性public short? radix { get; set; }         //VACW比例// 构造函数:Byte2 + Byte3public LoadCommandAttribute(byte byte2, byte byte3){Byte2 = byte2;Byte3 = byte3;radix = null;}// 构造函数:Byte2 + Byte3 + radixpublic LoadCommandAttribute(byte byte2, byte byte3, short radix){Byte2 = byte2;Byte3 = byte3;this.radix = radix;}}public class PowrCommandAttribute : Attribute{public string cmd { get; set; }         //命令字public PowrCommandAttribute(string _cmd){cmd = _cmd;}}// 修改枚举定义public enum IT85_Cmd{[LoadCommand(0x21, 0x01)] 负载开,[LoadCommand(0x21, 0x00)] 负载关,[LoadCommand(0x20, 0x01)] 负载获权,[LoadCommand(0x20, 0x00)] 负载交权}public enum IT85_Set{[LoadCommand(0x22, 0, 10000)] 设置负载的最大输入电压值,[LoadCommand(0x24, 0, 10000)] 设置负载的最大输入电流值,[LoadCommand(0x26, 0, 1000)] 设置负载的最大输入功率值,[LoadCommand(0x2A, 0, 10000)] 设置负载的定电流值,[LoadCommand(0x2C, 0, 1000)] 设置负载的定电压值,[LoadCommand(0x2E, 0, 1000)] 设置负载的定功率值,[LoadCommand(0x30, 0, 1000)] 设置负载的定电阻值,[LoadCommand(0x10, 0, 10000)] 设置负载的拉载电压值,[LoadCommand(0x12, 0, 10000)] 设置负载的卸载电压值}public enum IT85_Get{[LoadCommand(0x23, 0x00)] 读取负载的最大输入电压值,[LoadCommand(0x25, 0x00)] 读取负载的最大输入电流值,[LoadCommand(0x27, 0x00)] 读取负载的最大输入功率值,[LoadCommand(0x2B, 0x00)] 读取负载的定电流值,[LoadCommand(0x2D, 0x00)] 读取负载的定电压值,[LoadCommand(0x2F, 0x00)] 读取负载的定功率值,[LoadCommand(0x31, 0x00)] 读取负载的定电阻值,[LoadCommand(0x11, 0x00)] 读取负载的拉载电压值,[LoadCommand(0x13, 0x00)] 读取负载的卸载电压值,[LoadCommand(0x5F, 0x00)] 读取负载的输入VAW}public enum LoadMode{[LoadCommand(0x28, 0x00)] CC模式,[LoadCommand(0x28, 0x01)] CV模式,[LoadCommand(0x28, 0x02)] CW模式,[LoadCommand(0x28, 0x03)] CR模式}public enum IT68_Cmd{[PowrCommand("OUTPut 1")] 电源开,[PowrCommand("OUTPut 0")] 电源关,[PowrCommand("SYSTem:RWLock")] 电源获权,[PowrCommand("SYST:LOCal")] 电源交权,[PowrCommand("VOLTage?")] 电源返回设置电压,[PowrCommand("MEASure:VOLTage?")] 电源返回当前电压,[PowrCommand("CURRent?")] 电源返回设置电流,[PowrCommand("MEASure:CURRent?")] 电源返回当前电流}
}

调用:

uartPowr.DataReceived += new SerialDataReceivedEventHandler(uartPowr_DataReceived);
uartLoad.DataReceived += new SerialDataReceivedEventHandler(uartLoad_DataReceived);
private void uartLoad_DataReceived(object sender, SerialDataReceivedEventArgs e){_sp2.Read(buf, 0, 26);var result = IT85XX.Get_VCW_Result(_sp2, buf);//double str = IT85XX.Get_str_Result(_sp2, buf);//获取设定值this.Invoke((Action)(() =>{label2.Text = "电压:" + result.Voltage + " " + "电流:" + result.Current + " " + "功率:" + result.Power; //(str/ factor).ToString(); // 转换后的数据
            }));_sp2.DiscardInBuffer();//丢弃串口接收缓存区数据_sp2.DiscardOutBuffer();//丢弃串口发送缓存区数据
        }private void uartPowr_DataReceived(object sender, SerialDataReceivedEventArgs e){string str = IT68XX.Get_Str_Result(_sp1);this.Invoke((Action)(() =>{label1.Text = str;}));_sp1.DiscardInBuffer();//丢弃串口接收缓存区数据_sp1.DiscardOutBuffer();//丢弃串口发送缓存区数据}

举例:

private void button7_Click(object sender, EventArgs e){IT68XX.Send_Cmd(_sp1, IT68_Cmd.电源返回当前电流);}
 private void button36_Click(object sender, EventArgs e){IT85XX.Send_GetCommand(_sp2, IT85_Get.读取负载的输入VAW);}

后期增加功能,直接在枚举里面增加即可。

http://www.jsqmd.com/news/905084/

相关文章:

  • 从UEFI固件到操作系统:深入理解SMBIOS协议在系统启动时的数据流
  • 为什么你的Veo预览总比渲染慢3帧?——基于NVIDIA CUDA Graph与Veo Pipeline深度剖析(附12组Benchmark数据)
  • VEX机器人高速颜色分选机构设计:从气动活板门到毫秒级响应
  • OpCore Simplify深度解析:智能黑苹果EFI配置的完整解决方案
  • 9个用于测试自动化的最佳AI测试工具
  • Snowflake Arctic Embed-L架构深度解析:从BERT到SOTA的演进之路
  • 深圳5家雅思培训机构实测排行:聚焦提分与服务 - 互联网科技品牌测评
  • HLS设计技巧
  • 从1931年CIE标准到你的手机屏幕:Yxy/XYZ颜色空间的通俗图解与避坑指南
  • 2026卫生高级职称考试名师怎么选?数万考生实测真心推荐! - 医考机构品牌测评专家
  • react-native-google-analytics-bridge版本6迁移指南:API变更与代码适配实战
  • 基于AMB82-MINI与Arduino的实时人脸识别系统开发实践
  • Windows平台终极解决方案:自动化ADB与Fastboot驱动安装工具的完整技术栈深度解析
  • 告别臃肿:用G-Helper给你的华硕笔记本做一次“瘦身手术“
  • 从‘/proc’文件系统看线程名:深入理解prctl、pthread_setname_np与Linux内核的交互
  • 基于BERT与主动学习的游戏用户评论分类:小样本下的高精度解决方案
  • 深圳雅思提分机构实测排行:五家机构核心能力对比 - 互联网科技品牌测评
  • OpenClaw+88api保姆级教程:国内直连 Claude/GPT 模型,一篇搞定环境配置(2026实测可用)
  • 从QPSK到MSK:一张图看懂相位连续性的演进与频谱优化
  • BetterNCM Installer:5分钟快速搞定网易云音乐插件安装终极方案
  • 从Prompt到Profit:Sora 2 AI主播生成商业化闭环(附可运行的TikTok/小红书/视频号三端自动发布脚本)
  • LayoutLMv3-base-chinese应用场景大全:表单理解到文档视觉问答的8大案例
  • 从树莓派选系统说起:Raspbian、Ubuntu Server、Debian,新手到底该刷哪个镜像?
  • 执业医师考试哪个课程好?2026这套完整备考方案值得关注 - 医考机构品牌测评专家
  • AI语音克隆已进入“零样本时代”:从3小时录音到1秒克隆的技术跃迁,及反制所需的3层动态声纹加密架构
  • 如何永久保存微信聊天记录?这款开源工具让你轻松导出并分析所有对话
  • 【macOS保姆级】Claude Code从安装到API配置全流程:国内直连无需海外账号,亲测跑通
  • Ubuntu 20.04下A-LOAM复现避坑全记录:从PCL 1.9到Ceres库版本选择
  • 别再为SAP销售订单批导报错头疼了!详解定价类型(A/B/C/G)选择与条件类型更新逻辑
  • 5 分钟本地一键部署 OpenClaw 教程|内置 490 个大模型|Windows 适配完整版