Winform程序實現COM口通訊

故事背景:公司生產線上新購一臺機臺(本來有兩臺同型號的老機器),結果本來的用VB寫的測試電壓的程序在新機器上沒法使用,讀取不到電腦COM口上機臺返回的數據;最鬱悶的是電話問廠商人家說新的機器沒有改變什麼(最坑的就是這句話了),只是比老機器效率高點,而後就沒了,沒辦法,已經付過錢了,人家吊的不行。萬般無奈之下,只有本身找緣由了;因而乎,上網找各類資料,本身寫了一個Winform的測試COM通訊的程序,寫完後結果和VB程序 同樣的問題,讀取不到COM口數據,通過兩天的研究終於搞定了,緣由是新設備中的通訊協議中的握手協議改了。廢話很少說,上圖片和代碼:ide

1.Winform界面以下:測試

其中:波特率的的Items包括spa

300
600
1200
2400
4800
9600
19200
38400
43000
56000
57600
115200code

數據位的Items有:orm

1
2
4
8blog

中止位的Items有:圖片

1
1.5
2ip

校驗位的Items有:string


奇校驗
偶校驗it

備註:界面上的toolStrip能夠改成StatusStrip更好些,發送數據的兩個RadioButton的名字能夠改下(由於這個是在度娘裏找的,懶的改代碼裏的名字,因此我也就沒改)

 

2.上代碼(已運行過的代碼,可直接使用;因爲我只要測試COM的通訊,因此定製發送數據和保存設置的功能沒寫,可根據需求自行添加)

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;

namespace TestCOM
{
    public partial class Form1 : Form
    {
        SerialPort sp1 = new SerialPort();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            sp1.DataReceived+=new SerialDataReceivedEventHandler(sp1_DataReceived);

            string[] str = SerialPort.GetPortNames();
            if (str == null)
            {
                MessageBox.Show("本機沒有串口!", "Error");
                return;
            }

            //添加串口項目
            foreach (string s in System.IO.Ports.SerialPort.GetPortNames())
            {//獲取有多少個COM口
                cbSerial.Items.Add(s);
            }

            //串口設置默認選擇項
            cbSerial.SelectedIndex = 0;         //設置cbSerial的默認選項
            cbBaudRate.SelectedIndex = 5;
            cbDataBits.SelectedIndex = 3;
            cbStop.SelectedIndex = 0;
            cbParity.SelectedIndex = 0;
            radio2.Checked = true;  //發送數據的「16進制」單選按鈕
            rbRcvStr.Checked = true;
        }

        private void btnSwitch_Click(object sender, EventArgs e)
        {

            if (!sp1.IsOpen)
            {
                try
                {
                    string serialName = cbSerial.SelectedItem.ToString();
                    sp1.PortName = serialName;
                    string strBaudRate = cbBaudRate.Text;
                    string strDateBits = cbDataBits.Text;

                    string strStopBits = cbStop.Text;
                    Int32 iBaudRate = Convert.ToInt32(strBaudRate);
                    Int32 iDateBits = Convert.ToInt32(strDateBits);

                    sp1.BaudRate = iBaudRate;
                    sp1.DataBits = iDateBits;
                    switch (cbStop.Text)
                    {
                        case "1":
                            sp1.StopBits = StopBits.One;
                            break;
                        case "1.5":
                            sp1.StopBits = StopBits.OnePointFive;
                            break;
                        case "2":
                            sp1.StopBits = StopBits.Two;
                            break;
                        default:
                            MessageBox.Show("Error:參數不正確!", "Error");
                            break;
                    }

                    switch (cbParity.Text)
                    {
                        case "":
                            sp1.Parity = Parity.None;
                            break;
                        case "奇校驗":
                            sp1.Parity = Parity.Odd;
                            break;
                        case "偶校驗":
                            sp1.Parity = Parity.Even;
                            break;
                        default:
                            MessageBox.Show("Error:參數不正確!", "Error");
                            break;
                    }
                    //sp1.ReceivedBytesThreshold = 1;
                    //sp1.Handshake = Handshake.RequestToSend;//握手協議:RTS硬件流控制
                    //我遇到的問題就是這裏的問題,Handshake默認是None,可是有些設備的Handshake可能就不是這個,因此要根據鏈接的設備而定;若是是用跳線測試電腦COM通訊的話這裏就用默認的,改爲RTS的話是不行的



                    if (sp1.IsOpen == true)
                    {
                        sp1.Close();
                    }
                    //狀態欄設置
                    tsSpNUM.Text = "串口號:" + sp1.PortName + "|";
                    tsBaudRate.Text = "波特率:" + sp1.BaudRate + "|";
                    tsDataBits.Text = "數據位:" + sp1.DataBits + "|";
                    tsStopBits.Text = "中止位:" + sp1.StopBits + "|";
                    tsParity.Text = "校驗位:" + sp1.Parity + "|";

                    cbSerial.Enabled = false;
                    cbBaudRate.Enabled = false;
                    cbDataBits.Enabled = false;
                    cbStop.Enabled = false;
                    cbParity.Enabled = false;

                    sp1.Open();
                    btnSwitch.Text = "關閉串口";

                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error:" + ex.Message + "Error");
                    return;
                }
            }
            else
            {
                tsSpNUM.Text = "串口號:未指定|";
                tsBaudRate.Text = "波特率:未指定|";
                tsDataBits.Text = "數據位:未指定|";
                tsStopBits.Text = "中止位:未指定|";
                tsParity.Text = "校驗位:未指定|";

                cbSerial.Enabled = true;
                cbBaudRate.Enabled = true;
                cbDataBits.Enabled = true;
                cbStop.Enabled = true;
                cbParity.Enabled = true;

                sp1.Close();
                btnSwitch.Text = "打開串口";
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (!sp1.IsOpen)
            {
                MessageBox.Show("請先打開串口", "Error");
                return;
            }
            string strSend = txtSend.Text;
            if (radio1.Checked == true)
            {
                string sendBuf = strSend;
                string sendnoNull = sendBuf.Trim();
                string sendNOComma = sendnoNull.Replace(',', ' ');
                string sendNOComma1 = sendNOComma.Replace('', ' ');
                string strSendNoComma2 = sendNOComma1.Replace("0x", "");
                strSendNoComma2.Replace("0X", "");
                string[] strArray = strSendNoComma2.Split(' ');


                int byteBufferLength = strArray.Length;
                for (int i = 0; i < strArray.Length; i++)
                {
                    if (strArray[i] == "")
                    {
                        byteBufferLength--;
                    }
                }

                byte[] byteBuffer = new byte[byteBufferLength];
                int ii = 0;
                for (int i = 0; i < strArray.Length; i++)
                {
                    Byte[] bytesOfStr = Encoding.Default.GetBytes(strArray[i]);

                    int decNum = 0;
                    if (strArray[i] == "")
                    {
                        continue;
                    }
                    else
                    {
                        decNum = Convert.ToInt32(strArray[i],16);
                    }
                    try
                    {
                        byteBuffer[ii] = Convert.ToByte(decNum);
                    }
                    catch (Exception)
                    {

                        MessageBox.Show("字節越界,請逐個字節輸入!","Error");
                        return;
                    }
                    ii++;
                }
                sp1.Write(byteBuffer,0,byteBuffer.Length);



            }
            else
            {
                sp1.WriteLine(txtSend.Text);
            }

        }

        private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (sp1.IsOpen)
            {
                byte[] byteRead = new byte[sp1.BytesToRead];
                if (rbRcvStr.Checked)
                {
                    txtRcv.Text += sp1.ReadLine() + "\r\n";
                    sp1.DiscardInBuffer();
                }
                else
                {
                    try
                    {
                        Byte[] receivedData = new Byte[sp1.BytesToRead];
                        sp1.Read(receivedData, 0, receivedData.Length);
                        sp1.DiscardInBuffer();
                        string strRcv = null;
                        for (int i = 0; i < receivedData.Length; i++)
                        {
                            strRcv += receivedData[i].ToString("X2");
                        }
                        txtRcv.Text += strRcv + "\r\n";
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message,"出錯提示");
                        txtSend.Text = "";
                    }
                }
            }
            else
            {
                MessageBox.Show("請打開某個串口","錯誤提示");
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            txtRcv.Text = string.Empty;
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }






    }
}
View Code

 

備註:我處理的這個機臺的Handshake的方式就是RTS,可是應該有不少設備的Handshake是None的(默認的),因此要根據具體的設備(設備的說明書上應該有說的)。

相關文章
相關標籤/搜索