C# 串口软件

编写串口软件

 *在跟着别人写了一遍过后,发现串口软件会把原本一个整体的内容当成两次内容,导致显示出来的时候会发现内容会在中间出现换行*
 *通过尝试,在DataReceived事件触发后,不要立即从缓冲区读取发来的内容,设置Sleep等待50ms。然后就可解决问题*

C# 串口软件_第1张图片

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;

namespace PortHelper
{
	public partial class Form1:Form
	{
		private SerialPort SerialPort = new SerialPort();
		public Form1()
		{
			InitializeComponent();
			InitConfig();
		}
		
		private void InitConfig()
		{
			//GetPortNames()返回值是string[] ,自动返回你电脑上的串口名
			cbSerial.Items.AddRange(SerialPort.GetPortNames());
			if(cbSerial.Items.Count>0)
			{
				cbSerial.SelectedIndex = 0;
			}
			else
			{
				cbSerial.Text = "未检测到串口";
			}
			//对波特率的combobox项使用代码进行设置, 一般在控件上直接设置就好了
			string[] baudData = new String[] {"9600", "19200", "38400","57600", "115200","Custom"};
			cbBaudRate.Items.AddRange(baudData);
			cbBaudRate.SelectedIndex = 0;//作用:下拉列表框里会默认显示9600
			//对其他几个也进行默认设置
			cbDataBits.SelectedIndex = 3;//数据位列表框
            cbStop.SelectedIndex = 0;//停止位列表框
            cbParity.SelectedIndex = 0;//校验位列表框
            //所有的下拉框都不能随意输入内容,只能当选中特定项时才能输入
            cbSerial.DropDownStyle = ComboBoxStyle.DropDownList;
            cbBaudRate.DropDownStyle = ComboBoxStyle.DropDownList;
            cbDataBits.DropDownStyle = ComboBoxStyle.DropDownList;
            cbStop.DropDownStyle = ComboBoxStyle.DropDownList;
            cbParity.DropDownStyle = ComboBoxStyle.DropDownList;

			//默认状态下,编码方式设为ASCII
			radioButton1.Checked = true;

			SerialPort.DataReceived += new SerialDataReceivedEventHandler(Com_DataReceived);
		}
		
		private void Com_DataReceived(object sender, SerialDataReceivedEventArgs e)
		{
			//当这个事件解决器响应后,不要让它立刻去读缓冲区的内容,等50ms再读,
			//否则内容还没完全写到缓冲区内就被读走了,就会出现我开头出现的状况
			//添加了这个等待时间再去读取就不会出现一个完整的内容要读两次;一定要写在开头,不然也没用
            System.Threading.Thread.Sleep(50);
            从缓冲区读取数据到byte[]
            byte[] reDatas = new byte[SerialPort.BytesToRead];//BytesToRead字段:获取接收缓冲区中数据的字节数
            SerialPort.Read(reDatas, 0, reDatas.Length);
            //实现数据解码
            AddData(reDatas);
		}
		
		public void AddData(byte[] Data)
		{
			if(radioButton1.Checked)
			{
				AddContent(new ASCIIEncoding().GetString(Data));
			}
			else if(radioButton2.Checked)
			{
				StringBuilder sb = new StringBuilder();
				for(int i=0 ; i<Data.Length; i++)
				{
					sb.AppendFormat("{0:x2}" + " ", Data[i]);
				}
				//你若把上面的x换成X,下面这句中就不需要ToUpper()再去转换成大写了
				AddContent(sb.ToString().ToUpper());
			}
		}
		
		private void AddContent(string content)
        {
            BeginInvoke(new MethodInvoker(delegate
            {
            	//txtRecv是我控件的name
                txtRecv.AppendText(content + "\r\n");
                SerialPort.DiscardInBuffer();
            }));
        }
        
        private void start_button_Click(object sender, EventArgs e)
        {
        	if(SerialPort.IsOpen == false)
        	{
        		//把串口的属性配置好后,才能连接通信
                SerialPort.PortName = cbSerial.SelectedItem.ToString();
                SerialPort.BaudRate = Convert.ToInt32(cbBaudRate.Text.ToString());
                SerialPort.DataBits = Convert.ToInt32(cbDataBits.SelectedItem.ToString());
                SerialPort.StopBits =(StopBits)Convert.ToInt32(cbStop.SelectedItem.ToString());
                SerialPort.Parity = (Parity)Convert.ToInt32(cbParity.SelectedIndex.ToString());
                try
                {
                	SerialPort.Open();
                    send_button.Enabled = true;
                }
                catch(Exception ex)
                {
                    MessageBox.Show("未能成功开启串口");
                    return;
                }
                start_button.Text = "关闭";
           	}
        	else
        	{
        		try
                {
                    SerialPort.Close();
                    send_button.Enabled = false;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("关闭失败");
                    
                }
                start_button.Text = "开启";
        	}
        	cbSerial.Enabled = !SerialPort.IsOpen;
            cbBaudRate.Enabled = !SerialPort.IsOpen;
            cbDataBits.Enabled = !SerialPort.IsOpen;
            cbStop.Enabled = !SerialPort.IsOpen;
            cbParity.Enabled =!SerialPort.IsOpen;
        }
        
        private void send_button_Click(object sender, EventArgs e)
        {
            byte[] sendData = null;
            if(radioButton1.Checked)
            {
                sendData = Encoding.ASCII.GetBytes(txtSend.Text.Trim());
            }
            else if(radioButton2.Checked)
            {
                sendData = ToHexFromString(txtSend.Text.Trim());
            }
            SerialPort.Write(sendData, 0, sendData.Length);
        }
        //这个函数我写的有些问题,后面再完善,不过对现在使用没影响
        private byte[] ToHexFromString(string str)
        {
            byte[] data = Encoding.ASCII.GetBytes(str);
            StringBuilder builder = new StringBuilder();
            for(int i=0;i<data.Length; i++)
            {
                builder.AppendFormat("{0:X2}" + " ", data[i]);
            }
            string strTemp = builder.ToString().Trim();
            string[] chars = strTemp.Split(new char[] {' '});

            byte[] hexByte = new byte[chars.Length];
            for(int i=0; i<chars.Length; i++)
            {
                hexByte[i] = Convert.ToByte(chars[i],16);
            }
            return hexByte;
        }
        
		private void clear_btn_Click(object sender, EventArgs e)
        {
            txtRecv.Clear();
        }
	}
	
}

##问题
编写的时候参考内容链接:link

你可能感兴趣的:(笔记,c#,开发语言)