当前位置: 首页 > 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.rkmt.cn/news/1416378.html

相关文章:

  • 从UEFI固件到操作系统:深入理解SMBIOS协议在系统启动时的数据流
  • 深圳5家雅思培训机构实测排行:聚焦提分与服务 - 互联网科技品牌测评
  • Windows平台终极解决方案:自动化ADB与Fastboot驱动安装工具的完整技术栈深度解析
  • OpenClaw+88api保姆级教程:国内直连 Claude/GPT 模型,一篇搞定环境配置(2026实测可用)
  • 从QPSK到MSK:一张图看懂相位连续性的演进与频谱优化
  • 执业医师考试哪个课程好?2026这套完整备考方案值得关注 - 医考机构品牌测评专家
  • 从树莓派选系统说起:Raspbian、Ubuntu Server、Debian,新手到底该刷哪个镜像?
  • 【macOS保姆级】Claude Code从安装到API配置全流程:国内直连无需海外账号,亲测跑通
  • 告别黑屏和拉伸!保姆级教程:在Ubuntu上为老旧或特殊显示器自定义分辨率
  • 别再为SAP销售订单批导报错头疼了!详解定价类型(A/B/C/G)选择与条件类型更新逻辑
  • 如何快速掌握浏览器资源捕获:猫抓(cat-catch)专业工具完整实战指南
  • 精准客户成本归因:告别代理分摊,实现SaaS/云服务真实利润分析
  • 从城市白领到农场主:我是如何用一台MacBook和一台3马力耕耘机,实现写作与务农双线作战的
  • 手把手教你:Windows 10开机卡在grub?不用EasyUEFI,用Diskpart三步搞定启动项
  • 实战踩坑:在Ubuntu 24.04上用mdadm组RAID 0,性能翻倍后我遇到了这些问题
  • 【独家首发】Gemini 2.5 Pro东南亚语言基准测试报告:对比Llama-3-70B与Claude-3.5-Sonnet在柬埔寨语法律文本生成任务中BLEU+42.6%领先优势
  • CICC/gtr-t5-xl与sentence-transformers集成:版本兼容性终极指南
  • 鸣潮自动化终极指南:如何用ok-ww轻松解放双手,快速完成日常任务
  • AIBOX-1684X 风扇工作策略调节
  • 张掖外贸网站开发找哪家?WaiMaoYa 外贸鸭建好外贸独立站,坐等海外客户主动上门 - 外贸营销驿站
  • Windows 11专业瘦身实战:3步实现高效系统优化与隐私保护
  • 前瞻布局・智领金陵|2026 南京 8 大小程序服务商榜单 - 软件测评师
  • TinyLLama-v0-openmind入门指南:如何用这个迷你Llama模型快速生成故事?
  • Win11版本太多挑花眼?一文读懂Dev/Beta/RP/正式版区别与ISO下载选择
  • 自定义Advisor 20260528
  • ResNet-50与其他主流CNN模型对比分析:何时选择哪个模型?终极选择指南
  • 从银行密集任命首席合规官,看企业合规管理新时代的必修课
  • 气体涡轮流量计采购必看:国内优质厂家推荐与常见工况选型误区 - 品牌推荐大师
  • 8086汇编程序设计_从基础到实战
  • 海口外贸独立站哪家经验足?WaiMaoYa 外贸鸭贸易企业定制站点,深耕全球经销商渠道 - 外贸营销驿站