using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
namespace RS232
{
public partial class fclsRS232Tester : Form
{
// Various colors for logging info
private Color[] MsgTypeColor = { Color.Blue, Color.Green, Color.Black, Color.Orange, Color.Red };
string InputData = String.Empty;
BackgroundWorker background_Send = new BackgroundWorker();
/// <summary> Convert a string of hex digits (ex: E4 CA B2) to a byte array. </summary>
/// <param name="s"> The string containing the hex digits (with or without spaces). </param>
/// <returns> Returns an array of bytes. </returns>
private byte[] HexStringToByteArray(string s)
{
s = s.Replace(" ", "");
byte[] buffer = new byte[s.Length / 2];
for (int i = 0; i < s.Length; i = 2)
buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
return buffer;
}
/// <summary> Converts an array of bytes into a formatted string of hex digits (ex: E4 CA B2)</summary>
/// <param name="data"> The array of bytes to be translated into a string of hex digits. </param>
/// <returns> Returns a well formatted string of hex digits with spacing. </returns>
private string ByteArrayToHexString(byte[] data)
{
StringBuilder sb = new StringBuilder(data.Length * 3);
foreach (byte b in data)
sb.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, ' '));
return sb.ToString().ToUpper();
}
private byte[] intToByte(int i)
{
byte[] abyte0 = new byte[4];
abyte0[0] = (byte)((0xff000000 & i) >> 24);
abyte0[1] = (byte)((0xff0000 & i) >> 16);
abyte0[2] = (byte)((0xff00 & i) >> 8);
abyte0[3] = (byte)(0xff & i);
return abyte0;
}
public byte[] shortToByte(int i)
{
byte[] abyte0 = new byte[2];
abyte0[0] = (byte)((0xff00 & i) >> 8);
abyte0[1] = (byte)(0xff & i);
return abyte0;
}
public fclsRS232Tester()
{
InitializeComponent();
cmbParity.Items.Clear();
cmbParity.Items.AddRange(Enum.GetNames(typeof(Parity)));
cmbStopBits.Items.Clear();
cmbStopBits.Items.AddRange(Enum.GetNames(typeof(StopBits)));
cmbStopBits.SelectedIndex = cmbStopBits.Items.IndexOf("One");
cmbDataBits.SelectedIndex = cmbDataBits.Items.IndexOf("8");
cmbParity.SelectedIndex = cmbParity.Items.IndexOf("None");
cmbBaudRate.SelectedIndex = cmbBaudRate.Items.IndexOf("19200");
//初始化下拉串口名称列表框
cmbPortName.Items.Clear();
foreach (string s in SerialPort.GetPortNames())
cmbPortName.Items.Add(s); ;
if (cmbPortName.Items.Count > 0)
cmbPortName.SelectedIndex = 0;
//else
//{
// MessageBox.Show(this, "There are no COM Ports detected on this computer.\nPlease install a COM Port and restart this app.", "No COM Ports Installed", MessageBoxButtons.OK, MessageBoxIcon.Error);
// this.Close();
//}
cbomode.Items.Add("固定");
cbomode.Items.Add("自增");
cbomode.Items.Add("自减");
cbomode.SelectedIndex = 0;
background_Send.WorkerSupportsCancellation = true;
background_Send.DoWork = new DoWorkEventHandler(background_Send_DoWork);
background_Send.RunWorkerCompleted = new RunWorkerCompletedEventHandler(background_Send_RunWorkerCompleted);
}
private void Disablecontrol()
{
cmbPortName.Enabled = false;
cmbBaudRate.Enabled = false;
cmbDataBits.Enabled = false;
cmbStopBits.Enabled = false;
cmbParity.Enabled = false;
}
private void Enablecontrol()
{
cmbPortName.Enabled = true;
cmbBaudRate.Enabled = true;
cmbDataBits.Enabled = true;
cmbStopBits.Enabled = true;
cmbParity.Enabled = true;
}
// <summary>
/// 串口初始化函数
/// </summary>
private void btnOpen_Click(object sender, EventArgs e)
{
if (btnOpen.Text == "打开串口")
{
if (cmbPortName.Text.Trim() == "")
{
MessageBox.Show("COM Port cann't empty!", "RS232 tester", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// try to open the selected port:
try
{
// If the port is open, close it.
if (port.IsOpen)
port.Close();
else
{
// Set the port's settings
port.BaudRate = int.Parse(cmbBaudRate.Text);
port.DataBits = int.Parse(cmbDataBits.Text);
port.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cmbStopBits.Text);
port.Parity = (Parity)Enum.Parse(typeof(Parity), cmbParity.Text);
port.PortName = cmbPortName.Text;
// Open the port
port.Open();
this.Disablecontrol();
stsStatus.Text = port.PortName ": is Opened!" ;
btnOpen.Text = "关闭串口";
}
}
// give a message, if the port is not available:
catch
{
MessageBox.Show("Serial port " port.PortName " cannot be opened!", "RS232 tester", MessageBoxButtons.OK, MessageBoxIcon.Warning);
cmbPortName.SelectedText = "";
stsStatus.Text = "Select serial port!";
}
}
else
{
try
{
if (port.IsOpen) port.Close();
this.Enablecontrol();
stsStatus.Text = port.PortName ": 已关闭";
btnOpen.Text = "打开串口";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
private void SendData(string str)
{
try
{
if (!port.IsOpen)//判断串口是否打开
{
MessageBox.Show("Serial port is closed!", "RS232 tester", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
string sendstr = (chkpx.Checked) ? '\r' str '\n' : str;
if (chkhex.Checked)
{
byte[] data = HexStringToByteArray(sendstr);
port.Write(data, 0, data.Length);
txtOut.Text = strtohex(sendstr);
}
else
{
byte[] data = System.Text.Encoding.ASCII.GetBytes(sendstr);
port.Write(data, 0, data.Length);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
string sendbuf;
private void btnSend_Click(object sender, EventArgs e)
{
if (btnSend.Text.Equals("停止发送"))
{
timer1.Enabled = false;
btnSend.Text = "发送";
sendbuf = "";
return;
}
if (chkauto.Checked)
{
sendbuf = txtOut.Text;
timer1.Interval = int.Parse(txtimes.Text);
timer1.Enabled = true;
btnSend.Text = "停止发送";
}
else
{
string temp = txtOut.Text;
SendData(temp);
switch (cbomode.SelectedIndex)
{
case 0:
temp = txtOut.Text;
break;
case 1:
temp = strinc(txtOut.Text, 10);
break;
case 2:
temp = strdec(txtOut.Text, 10);
break;
}
txtOut.Text = temp;
}
}
private void btnClear_Click(object sender, EventArgs e)
{
txtMsg.Clear();
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string dataRe = "";
byte[] byteRead = new byte[port.BytesToRead];
port.Read(byteRead, 0, byteRead.Length);
dataRe= System.Text.Encoding.ASCII.GetString(byteRead);
SetText(dataRe);
}
private void SetText(String data)
{
if (data == null) return;
txtMsg.Invoke(new EventHandler(delegate
{
txtMsg.SelectedText = string.Empty;
txtMsg.SelectionFont = new Font(txtMsg.SelectionFont, FontStyle.Bold);
if (chkenter.Checked)
txtMsg.AppendText(data "\r\n");
else
txtMsg.AppendText(data);
txtMsg.Select();//让RichTextBox获得焦点
txtMsg.Select(txtMsg.TextLength, 0);//将插入符号置于文本结束处
txtMsg.ScrollToCaret();
}));
}
private void background_Send_DoWork(object sender, DoWorkEventArgs e)
{
try
{
string temp = sendbuf;
SendData(temp);
switch (cbomode.SelectedIndex)
{
case 0:
temp = sendbuf;
break;
case 1:
temp = strinc(sendbuf, 10);
break;
case 2:
temp = strdec(sendbuf, 10);
break;
}
sendbuf = temp;
}
catch (System.IO.IOException ex)//读取失败
{
stsStatus.Text = ex.Message;
e.Cancel = true;
return;
}
catch (Exception ex)
{
stsStatus.Text = ex.Message;
e.Cancel = true;
return;
}
}
private void background_Send_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
return;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (!background_Send.IsBusy)
{
background_Send.RunWorkerAsync();
}
}
private void chkauto_CheckedChanged(object sender, EventArgs e)
{
txtimes.Enabled = chkauto.Checked;
}
#region string function
/// <summary>
/// Char转ASCII
/// </summary>
/// <param name="character"></param>
/// <returns></returns>
public static int Asc(string character)
{
if (character.Length == 1)
{
System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
int intAsciiCode = (int)asciiEncoding.GetBytes(character)[0];
return (intAsciiCode);
}
else
{
throw new Exception("Character is not valid.");
}
}
/// <summary>
/// ASCII码转Char
/// </summary>
/// <param name="asciiCode"></param>
/// <returns></returns>
public static string Chr(int asciiCode)
{
if (asciiCode >= 0 && asciiCode <= 255)
{
System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
byte[] byteArray = new byte[] { (byte)asciiCode };
string strCharacter = asciiEncoding.GetString(byteArray);
return (strCharacter);
}
else
{
throw new Exception("ASCII Code is not valid.");
}
}
/// <summary>
/// 字符串加1函数
/// </summary>
/// <param name="s1"></param>
/// <param name="hex"></param>
/// <returns></returns>
public static string strinc(string s1, int hex)
{
string str, newstr;
int index = 0;
int newInt;
str = s1.Trim().Replace(" ", "");
str = str.ToUpper();
if (hex == 10)
{
for (int i = str.Length - 1; i > 0; i--)
{
if (str[i] != (char)57)
{
index = i;
break;
}
}
newInt = Convert.ToInt32(str.Substring(index)) 1;
str = str.Substring(0, index) newInt.ToString();
}
else if (hex == 16)
{
newstr = "";
for (int i = str.Length - 1; i > 0; i--)
{
if (str[i] == (char)57)
{
newstr = "A";
index = i;
break;
}
else if (str[i] != (char)70)
{
newstr = Chr(Asc(str.Substring(i, 1)) 1);
index = i;
break;
}
}
str = str.Substring(0, index) newstr str.Substring(index 1).Replace("F", "0");
}
return str;
}
/// <summary>
/// 字符串减1函数
/// </summary>
/// <param name="s1"></param>
/// <param name="hex"></param>
/// <returns></returns>
public static string strdec(string s1, int hex)
{
string str, newstr;
int index = 0;
int newInt;
str = s1.Trim().Replace(" ", "");
str = str.ToUpper();
if (hex == 10)
{
for (int i = str.Length - 1; i > 0; i--)
{
if (str[i] != (char)48)
{
index = i;
break;
}
}
newInt = Convert.ToInt32(str.Substring(index)) - 1;
str = str.Substring(0, index) newInt.ToString().PadLeft(str.Length - index, '0');
}
else if (hex == 16)
{
newstr = "";
for (int i = str.Length - 1; i > 0; i--)
{
if (str[i] == (char)65)
{
newstr = "9";
index = i;
break;
}
else if (str[i] != (char)48)
{
newstr = Chr(Asc(str.Substring(i, 1)) - 1);
index = i;
break;
}
}
str = str.Substring(0, index) newstr str.Substring(index 1).Replace("0", "F");
}
return str;
}
/// <summary>
/// 字符串转16进制字符
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string strtohex(string str)
{
string strTemp = "";
if (str == "")
return "";
byte[] bTemp = System.Text.Encoding.Default.GetBytes(str);
for (int i = 0; i < bTemp.Length; i )
{
strTemp = bTemp[i].ToString("X2");
}
return strTemp;
}
#endregion
}
}