艾德克斯负载电源控制代码(C#)
封装成Dll文件,using MyTools; 后调用。
应用先实例化和声明数组。
readonly UART uartLoad = new UART(26);//接收26个字节触发串口数据 readonly UART uartPowr = new UART(1);//接收1个字节触发串口数据,如果不带参数,则默认为1 readonly 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; // 添加:无参构造函数,默认阈值为1 public 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 -> double return (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,除数 1000 uint voltageRaw = (uint)((buffer[6] << 24) | (buffer[5] << 16) | (buffer[4] << 8) | buffer[3]); string voltage = (voltageRaw / 1000.0).ToString("0.0000"); // 电流: 字节 7-10,除数 10000 uint currentRaw = (uint)((buffer[10] << 24) | (buffer[9] << 16) | (buffer[8] << 8) | buffer[7]); string current = (currentRaw / 10000.0).ToString("0.000"); // 功率: 字节 11-14,除数 1000 uint 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 + Byte3 public LoadCommandAttribute(byte byte2, byte byte3) { Byte2 = byte2; Byte3 = byte3; radix = null; } // 构造函数:Byte2 + Byte3 + radix public 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); }
后期增加功能,直接在枚举里面增加即可。

浙公网安备 33010602011771号