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;
using Microsoft.Win32;
namespace PotrTEST
{
public partial class Form1 : Form
{
public SerialPort com = new SerialPort();
//定義端口類
private SerialPort ComDevice = new SerialPort();
public Form1()
{
InitializeComponent();
InitralConfig(int.Parse(comboBox_BaudRate.Text));
}
/// <summary>
/// 從注冊表獲取系統串口列表
/// </summary>
public string[] GetComList()
{
RegistryKey keyCom = Registry.LocalMachine.OpenSubKey("Hardware\\DeviceMap\\SerialComm");
string[] sSubKeys = keyCom.GetValueNames();
string[] str = new string[sSubKeys.Length];
for (int i = 0; i < sSubKeys.Length; i++)
{
str[i] = (string)keyCom.GetValue(sSubKeys[i]);
}
return str;
}
/// <summary>
/// 配置初始化
/// </summary>
private void InitralConfig(int btl)
{
Boolean open = false;
string[] coms = GetComList();
for (int i = 0; i < coms.Length; i++)
{
open = false;
if (com.IsOpen)
{
com.Close();
}
comboBox_Port.Items.Add(coms[i]);
}
//向ComDevice.DataReceived(是一個事件)注冊一個方法Com_DataReceived,當端口類接收到信息時時會自動調用Com_DataReceived方法
ComDevice.DataReceived += new SerialDataReceivedEventHandler(Com_DataReceived);
}
/// <summary>
/// 一旦ComDevice.DataReceived事件發生,就將從串口接收到的數據顯示到接收端對話框
/// </summary>
/// <param name="sender"></param>
/// <param name="sender"></param>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Com_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//開辟接收緩沖區
byte[] ReDatas = new byte[ComDevice.BytesToRead];
//從串口讀取數據
ComDevice.Read(ReDatas, 0, ReDatas.Length);
//實現數據的解碼與顯示
AddData(ReDatas);
}
/// <summary>
/// 解碼過程
/// </summary>
/// <param name="data">串口通信的數據編碼方式因串口而異,需要查詢串口相關信息以獲取</param>
public void AddData(byte[] data)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sb.AppendFormat("{0:x2}" + " ", data[i]);
}
AddContent(sb.ToString());//.ToUpper()
}
/// <summary>
/// 接收端對話框顯示消息
/// </summary>
/// <param name="content"></param>
private void AddContent(string content)
{
BeginInvoke(new MethodInvoker(delegate
{
textBox_Receive.AppendText(content);
}));
}
/// <summary>
/// 串口開關
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button_Switch_Click(object sender, EventArgs e)
{
if (comboBox_Port.Items.Count <= 0)
{
MessageBox.Show("未發現可用串口,請檢查硬件設備");
return;
}
if (ComDevice.IsOpen == false)
{
//設置串口相關屬性
ComDevice.PortName = comboBox_Port.Text;//comboBox_Port.SelectedItem.ToString();
ComDevice.BaudRate = Convert.ToInt32(comboBox_BaudRate.Text);//(comboBox_BaudRate.SelectedItem.ToString());
ComDevice.Parity = (Parity)Convert.ToInt32(comboBox_CheckBits.Text);//(comboBox_CheckBits.SelectedIndex.ToString());
ComDevice.DataBits = Convert.ToInt32(comboBox_DataBits.Text);// (comboBox_DataBits.SelectedItem.ToString());
ComDevice.StopBits = (StopBits)Convert.ToInt32(comboBox_StopBits.Text); //(comboBox_StopBits.SelectedItem.ToString());
try
{
//開啟串口
ComDevice.Open();
button_Send.Enabled = true;
button_Switch.Text = "關閉";
//while (true)
{
//接收數據
ComDevice.DataReceived += new SerialDataReceivedEventHandler(Com_DataReceived);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "未能成功開啟串口", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
else
{
try
{
ComDevice.Close();
button_Send.Enabled = false;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "串口關閉錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
button_Switch.Text = "開啟";
}
comboBox_Port.Enabled = !ComDevice.IsOpen;
comboBox_BaudRate.Enabled = !ComDevice.IsOpen;
comboBox_DataBits.Enabled = !ComDevice.IsOpen;
comboBox_StopBits.Enabled = !ComDevice.IsOpen;
comboBox_CheckBits.Enabled = !ComDevice.IsOpen;
}
/// <summary>
/// 將消息編碼並發送
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button_Send_Click(object sender, EventArgs e)
{
//if (textBox_Receive.Text.Length > 0)
//{
// textBox_Receive.AppendText("\n");
//}
byte[] sendData = null;
//sendData = Encoding.UTF8.GetBytes(textBox_Receive.Text);
sendData = Hex16StringToHex16Byte(textBox_Receive.Text);
SendData(sendData);
}
/// <summary>
/// 此方法用於將16進制的字符串轉換成16進制的字節數組
/// </summary>
/// <param name="_hex16ToString">要轉換的16進制的字符串。</param>
public static byte[] Hex16StringToHex16Byte(string _hex16String)
{
//去掉字符串中的空格。
_hex16String = _hex16String.Replace(" ", "");
if (_hex16String.Length / 2 == 0)
{
_hex16String += " ";
}
//聲明一個字節數組,其長度等於字符串長度的一半。
byte[] buffer = new byte[_hex16String.Length / 2];
for (int i = 0; i < buffer.Length; i++)
{
//為字節數組的元素賦值。
buffer[i] = Convert.ToByte((_hex16String.Substring(i * 2, 2)), 16);
}
//返回字節數組。
return buffer;
}
/// <summary>
/// 此函數將編碼后的消息傳遞給串口
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public bool SendData(byte[] data)
{
if (ComDevice.IsOpen)
{
try
{
//將消息傳遞給串口
ComDevice.Write(data, 0, data.Length);
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "發送失敗", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
MessageBox.Show("串口未開啟", "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return false;
}
/// <summary>
/// 16進制編碼
/// </summary>
/// <param name="hexString"></param>
/// <returns></returns>
private byte[] strToHexByte(string hexString)
{
hexString = hexString.Replace(" ", "");
if ((hexString.Length % 2) != 0) hexString += " ";
byte[] returnBytes = new byte[hexString.Length / 2];
for (int i = 0; i < returnBytes.Length; i++)
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2).Replace(" ", ""), 16);
return returnBytes;
}
private void Form1_Load(object sender, EventArgs e)
{
//button_Send.PerformClick();
}
//以下兩個指令是結合一款繼電器而設計的
//private void button_On_Click(object sender, EventArgs e)
//{
// textBox_Send.Text = "005A540001010000B0";
//}
//private void button_Off_Click(object sender, EventArgs e)
//{
// textBox_Send.Text = "005A540002010000B1";
//}
}
}