• Winform程序实现COM口通信


    故事背景:公司生产线上新购一台机台(原本有两台同型号的老机器),结果原本的用VB写的测试电压的程序在新机器上无法使用,读取不到电脑COM口上机台返回的数据;最郁闷的是电话问厂商人家说新的机器没有改变什么(最坑的就是这句话了),只是比老机器效率高点,然后就没了,没办法,已经付过钱了,人家吊的不行。万般无奈之下,只有自己找原因了;于是乎,上网找各种资料,自己写了一个Winform的测试COM通信的程序,写完后结果和VB程序 一样的问题,读取不到COM口数据,经过两天的研究终于搞定了,原因是新设备中的通信协议中的握手协议改了。废话不多说,上图片和代码:

    1.Winform界面如下:

    其中:波特率的的Items包括

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

    数据位的Items有:

    1
    2
    4
    8

    停止位的Items有:

    1
    1.5
    2

    校验位的Items有:


    奇校验
    偶校验

    备注:界面上的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() + "
    ";
                        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 + "
    ";
                        }
                        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的(默认的),所以要根据具体的设备(设备的说明书上应该有说的)。

  • 相关阅读:
    hdu5714 拍照[2016百度之星复赛C题]
    hdu5715 XOR 游戏 [2016百度之星复赛D题]
    AFO
    BZOJ 3566 概率充电器
    BZOJ 3427 Bytecomputer
    BZOJ 4513 储能表
    BZOJ 3667 Miller_Rabin
    BZOJ 4557 侦察守卫
    BZOJ 3894 文理分科
    SUOI #69 奔跑的Aqua
  • 原文地址:https://www.cnblogs.com/jerrylucky/p/4885157.html
Copyright © 2020-2023  润新知