可编程仪器标准命令(英语:Standard
Commands for Programmable Instruments,缩写:SCPI)定义了一套用于控制可编程测试测量仪器的标准语法和命令。《百度百科》
本文主要还是依赖仪器厂商提供的数据
首先是仪器型号,M8811数控电源,相关手册:百度文库
首先连接通信线,鉴于原厂的数据线很贵,于是只能自己解决,根据手册可以发现
后面的DB9是TTL电平,直接上USB转TTL即可,不能上标准的RS232,因为电平问题
可能是我的串口线有问题,实际接线的时候1~5是反过来的,我也是量GND与VCC电压发现的
看手册,别的可以忽略,直接看《第六章 SCPI通信协议》
我们需要一个串口调试工具,网上下的都不好用,于是自己做一个
比较简单,代码如下
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace DigitalPower
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
getAllPortName();
}
private void getAllPortName()
{
string[] spNames = SerialPort.GetPortNames();
cbPort.Items.Clear();
foreach (var v in spNames)
cbPort.Items.Add(v);
if (cbPort.Items.Count > 0)
cbPort.SelectedIndex = 0;
}
private void btRefresh_Click(object sender, EventArgs e)
{
getAllPortName();
}
private void btOpen_Click(object sender, EventArgs e)
{
if (btOpen.Text == "打开")
{
try
{
serialPort1.PortName = cbPort.SelectedItem.ToString();
serialPort1.Open();
btOpen.Text = "关闭";
btSend.Enabled = true;
}
catch { MessageBox.Show("无法打开端口!"); }
}
else
{
try
{
serialPort1.Close();
btOpen.Text = "打开";
btSend.Enabled = false;
}
catch { MessageBox.Show("无法关闭端口!"); }
}
}
private void btSend_Click(object sender, EventArgs e)
{
serialPort1.WriteLine(tbSend.Text);
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string str = serialPort1.ReadExisting();
this.Invoke(new MethodInvoker(delegate
{
lbDisaplay.Items.Add(str);
lbDisaplay.SelectedIndex = lbDisaplay.Items.Count - 1;
}));
}
private void btClear_Click(object sender, EventArgs e)
{
lbDisaplay.Items.Clear();
}
}
}
用工具测试一下手册上提供的命令,调试正常,于是再建一个工程
可以显示电压电流和设置电压电流,为了方便还是写一个类吧
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;
namespace DPtest
{
class DPM88
{
SerialPort sp = new SerialPort();
public DPM88()
{
sp.DataBits = 8;
sp.Parity = Parity.None;
sp.StopBits = StopBits.One;
sp.ReadBufferSize = 4096;
sp.ReadTimeout = 50;
sp.ReceivedBytesThreshold = 1;
}
int waitTime = 50;
public bool OpenDevice(int baudrate)
{
bool ret = false;
if (sp.IsOpen)
sp.Close();
string[] spNames = SerialPort.GetPortNames();
foreach (var v in spNames)
{
try
{
sp.PortName = v;
sp.BaudRate = baudrate;
sp.Open();
sp.WriteLine("*IDN?");
long tgTime = DateTime.Now.Ticks + 10000 * waitTime;
while (sp.BytesToRead <= 0 && tgTime > DateTime.Now.Ticks)
Thread.Sleep(1);
if (sp.BytesToRead > 0)
{
sp.DiscardInBuffer();
ret = true;
sp.WriteLine("SYST:REM");
break;
}
}
catch { }
}
return ret;
}
public void SetVoltage(double voltage)
{
string str = voltage.ToString("0.0000");
sp.WriteLine("VOLT " + str);
}
public void SetCurrent(double current)
{
string str = current.ToString("0.0000");
sp.WriteLine("CURR " + str);
}
public double GetSetVoltage()
{
double vol = 0;
vol = GetDoubleCmd("VOLT?");
return vol;
}
public double GetSetCurrent()
{
double cur = 0;
cur = GetDoubleCmd("CURR?");
return cur;
}
public double GetOutVoltage()
{
double vol = 0;
vol = GetDoubleCmd("MEAS:VOLT?");
return vol;
}
public double GetOutCurrent()
{
double cur = 0;
cur = GetDoubleCmd("MEAS:CURR?");
return cur;
}
private double GetDoubleCmd(string cmd)
{
double ret = 0;
sp.WriteLine(cmd);
long tgTime = DateTime.Now.Ticks + 10000 * waitTime;
while (sp.BytesToRead <= 0 && tgTime > DateTime.Now.Ticks)
Thread.Sleep(1);
if (sp.BytesToRead > 0)
{
try
{
string str = sp.ReadLine();
ret = Convert.ToDouble(str);
}
catch { }
}
return ret;
}
public void SetOutput(bool open)
{
if (open)
sp.WriteLine("OUTPU 1");
else
sp.WriteLine("OUTPU 0");
}
public bool GetOutput()
{
sp.WriteLine("OUTP?");
bool ret = false;
long tgTime = DateTime.Now.Ticks + 10000 * waitTime;
while (sp.BytesToRead <= 0 && tgTime > DateTime.Now.Ticks)
Thread.Sleep(1);
if (sp.BytesToRead > 0)
{
try
{
string str = sp.ReadLine();
if (str == "1")
ret = true;
else
ret = false;
}
catch { }
}
return ret;
}
public void ClosePort()
{
try
{
sp.Close();
}
catch { }
}
}
}
于是界面如下
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace DPtest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
DPM88 dpm = new DPM88();
private void btOpenPort_Click(object sender, EventArgs e)
{
if (btOpenPort.Text == "打开端口")
{
if (dpm.OpenDevice(38400) == true)
{
btOpenPort.Text = "关闭端口";
portOpenFlag = true;
timer1.Start();
}
else
{
MessageBox.Show("无法打开设备!");
}
}
else
{
portOpenFlag = false;
timer1.Stop();
dpm.ClosePort();
btOpenPort.Text = "打开端口";
}
}
bool portOpenFlag = false;
private void timer1_Tick(object sender, EventArgs e)
{
if (portOpenFlag)
{
lbVoltage.Text = dpm.GetOutVoltage().ToString("0.0000") + "V";
lbCurrent.Text = dpm.GetOutCurrent().ToString("0.0000") + "A";
if (dpm.GetOutput())
pictureBox1.BackColor = Color.Red;
else
pictureBox1.BackColor = this.BackColor;
}
}
private void btSetVoltage_Click(object sender, EventArgs e)
{
try
{
double d = Convert.ToDouble(tbSetVoltage.Text);
dpm.SetVoltage(d);
}
catch { }
}
private void btSetCurrent_Click(object sender, EventArgs e)
{
try
{
double d = Convert.ToDouble(tbSetCurrent.Text);
dpm.SetCurrent(d);
}
catch { }
}
private void btOnOff_Click(object sender, EventArgs e)
{
if (btOnOff.Text == "打开输出")
{
dpm.SetOutput(true);
btOnOff.Text = "关闭输出";
}
else
{
dpm.SetOutput(false);
btOnOff.Text = "打开输出";
}
}
}
}
总结:其实SCPI协议不难,只要看好手册即可
两个工程代码,写的不好,欢迎指正
http://download.csdn.net/download/lv_fu/9660570