艾德克斯负载电源控制代码(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);
        }

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

posted @ 2026-05-28 19:29  Cmale  阅读(7)  评论(0)    收藏  举报