在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#语言基础 → C#串口通信(含发送与接收串口数据)

C#串口通信(含发送与接收串口数据)

C#语言基础

下载此实例
  • 开发语言:C#
  • 实例大小:0.19M
  • 下载次数:195
  • 浏览次数:1106
  • 发布时间:2020-03-02
  • 实例类别:C#语言基础
  • 发 布 人:lt32210529
  • 文件格式:.rar
  • 所需积分:2

实例介绍

【实例简介】

【实例截图】

from clipboard

【核心代码】


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 Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
using System.IO;
using System.Diagnostics;
using System.IO.Ports;
using System.Threading;

namespace Project1
{
    // 显示窗口
    public enum WindowShowStatus 
    {   
        // 隐藏窗口
        SW_HIDE = 0,
        // 最大化窗口
        SW_MAXIMIZE = 3,
        // 最小化窗口
        SW_MINIMIZE = 6,
        // 用当前的大小和位置显示一个窗口,同时令其进入活动状态
        SW_SHOW = 5,
        // 用最近的大小和位置显示一个窗口,同时不改变活动窗口
        SW_SHOWNOACTIVATE = 4
    }
    
    public partial class Form1 : Form
    {   
        // 窗口初始化
        public Form1()
        {
            InitializeComponent();
        }

        Int32 ReceiveByte_Cnt = 0;  // 串口操作,接收字节计数
        Int32 SendByte_Cnt = 0;  // 串口操作,发送字节计数
        bool serialPort_Closing = false;  // 串口正在关闭标志
        public List<byte> BufferData = new List<byte>();  // 串口数据帧缓存空间
        public Thread thrd = null;  // 线程
        public FileStream writefile = null;  //文件输入

        private void Form1_Load(object sender, EventArgs e)
        { 
            // 串口设置初始状态
            try
            {
                // 默认串口设置显示
                for (int i = 1; i < 9; i  )
                {
                    cmbboxCom.Items.Add("COM"   i);  // 初始化串口号
                }
                
                cmbBaudRate.Items.Add("4800");  // 初始化波特率
                cmbBaudRate.Items.Add("9600");
                cmbBaudRate.Items.Add("19200");
                cmbBaudRate.Items.Add("38400");
                cmbBaudRate.Items.Add("115200");

                cmbDataBit.Items.Add("5");     // 初始化数据位
                cmbDataBit.Items.Add("6");
                cmbDataBit.Items.Add("7");
                cmbDataBit.Items.Add("8");

                foreach (string s in Enum.GetNames(typeof(Parity)))  
                {
                    cmbCheckBit.Items.Add(s);    // 初始化校验位
                }

                foreach (string s in Enum.GetNames(typeof(StopBits)))  
                {
                    cmbStopBit.Items.Add(s);    // 初始化停止位
                }

                // 下拉默认选择项
                cmbboxCom.SelectedIndex = 0;    // 串口号索引值
                cmbBaudRate.SelectedIndex = 4;  // 波特率索引值
                cmbDataBit.SelectedIndex = 3;  // 数据位索引值
                cmbCheckBit.SelectedIndex = 1;  // 校验位索引值
                cmbStopBit.SelectedIndex = 1;  // 停止位索引值
            }
            catch
            {
                MessageBox.Show("找不到串口连接!","Error");
            }
        }
        
        // 打开串口
        private void btnOpen_Click(object sender, EventArgs e)
        {
            var btn = sender as Button;  // 将sender(object)转换成button对象
            if (btn.Text == "打开")
            {   
                // 声明串口中的各个参数
                string sComNum = cmbboxCom.Text;
                string sBaudRate = cmbBaudRate.Text;
                string sDataBit = cmbDataBit.Text;
                string sCheckBit = cmbCheckBit.Text;
                string sStopBit = cmbStopBit.Text;

                try
                {
                    serialPort1.PortName = sComNum;  // 串口号
                    serialPort1.BaudRate = Int32.Parse(sBaudRate); // 波特率
                    serialPort1.DataBits = Int32.Parse(sDataBit);  // 数据位
                    serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), sCheckBit);  // 校验位
                    serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), sStopBit);  // 停止位
                    serialPort1.ReadTimeout = 500;   // 设置超时读取时间
                    serialPort1.WriteTimeout = 500;  // 设置超时写入时间
                    serialPort1.Open();      // 打开串口操作
                    if (serialPort1.IsOpen)  // 判定串口为打开状态
                    {
                        btn.Text = "关闭";
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);  // 异常信息
                }
            }
            else                    
            {   
                // 关闭串口
                serialPort1.Close();
                if(!serialPort1.IsOpen)  // 判定串口为关闭状态
                {
                    btn.Text = "打开";
                }
            }
        }

        // 串口数据发送
        private void btnSend_Click(object sender, EventArgs e)
        {
            SendData(txtbSndArea.Text);  // 需要发送的数据处理
        }

        // 串口发送数据处理
        private void SendData(string InputString)
        {
            if (chkbHexSnd.CheckState == CheckState.Checked)  //判定数据显示格式为十六进制显示
            {
                try
                {
                    InputString = InputString.Replace("0x", "").Replace(" ", ""); // 将十六进制字符串前的“0x”去掉
                    byte[] sendData = HexStringToByte(InputString);  // 将字符串转换成byte字符串放入数组

                    SendByte_Cnt  = sendData.Length;     // 修改发计数,发送数据的长度
                    lblSndCnt.Text = SendByte_Cnt.ToString("D");  // 发计数转换成字符串类型放入发计数文本域

                    if (sendData == null)  // 判定发送的数据为空
                    {
                        MessageBox.Show("请输入数据", "提示"); 
                    }
                    else
                    {
                        if (!serialPort1.IsOpen)  // 判定串口为关闭状态
                        {
                            MessageBox.Show("串口未打开", "提示");
                        }
                        else  // 串口为打开状态
                        {
                            serialPort1.Write(sendData, 0, sendData.Length);  // 要发送的数据写入缓冲区
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    MessageBox.Show("SendData请输入以“0x00”或“00”形式输入十六进制数", "错误");
                }
            }
            else  // 直接以字符形式发送 
            {
                try
                {
                    char[] SendChars = InputString.ToCharArray();  // 将字符串转换成字符存入字符数组
                    int CharsLength = SendChars.Length;      // 声明字符数组的长度
                    SendByte_Cnt  = CharsLength;       // 修改发计数
                    for (int i = 0; i < CharsLength; i  )  // 遍历字符数组,
                    {
                        if (SendChars[i] >= 0x4e00 && SendChars[i] <= 0x9fa5)  // 判定字符不是汉字(汉字编码区间为0x4e00--0x9fa5)
                        {
                            SendByte_Cnt  ;   // 发计数自增
                        }
                    }
                    lblSndCnt.Text = SendByte_Cnt.ToString("D");
                    serialPort1.Encoding = System.Text.Encoding.GetEncoding("GB2312");  // 国标2312格式,防止出现乱码
                    serialPort1.Write(SendChars, 0, CharsLength);  // 字符数组写入缓冲区
                }
                catch (Exception ec)
                {
                    MessageBox.Show("错误:SendData"   ec.Message, "错误"); // 异常提示信息
                }
            }
        }

        // 十六进制字符串转换
        private byte[] HexStringToByte(string InString)
        { 
            if (InString.Length % 2 != 0)  // 判定字符串长度为奇数
            {
                InString = InString   "0"; // 空位补“0”
                
            }
            byte[] buffer = new byte[InString.Length / 2];  // 用字符串长度的一半初始化byte型数组
            for (int i = 0; i < InString.Length; i  = 2)
            {
                buffer[i / 2] = (byte)Convert.ToByte(InString.Substring(i, 2), 16);  // 将16进制格式的字符串强制转换成byte类型值并取指定位置的2个值存入数组
            }
            return buffer;    // 返回数组
        }

        // 数据接收
        private void ReceiveData(object sender, SerialDataReceivedEventArgs e)
        {
            if (serialPort_Closing == true)  // 如果串口正在关闭,忽略操作,直接返回,尽快完成串口监听线程的一次循环
            {
                return;
            }
            try
            {
                int ReceiveNums = serialPort1.BytesToRead;  // 声明,记录缓存数量
                ReceiveByte_Cnt  = ReceiveNums;   // 修改收计数
                this.Invoke((EventHandler)(delegate    // 跨线程访问ui资源,使用invoke方式同步ui
                {
                    lblRcvCnt.Text = ReceiveByte_Cnt.ToString("D");
                    if (chkbHexDisplay.CheckState == CheckState.Checked)  // 判定数据显示格式为十六进制
                    {
                        byte[] buf = new byte[ReceiveNums];  // 声明一个临时数组存储当前串口数据
                        serialPort1.Read(buf, 0, ReceiveNums);  // 读取缓冲数据
                        ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadSavDat), buf);  // 将方法排入队列
                        BufferData.AddRange(buf);  // 串口数据写到自定义缓冲区,准备进行数据帧识别处理

                        string tempstr = string.Empty; // 声明一个没有分配空间的变量
                        for (int i = 0; i < ReceiveNums; i  )  // 遍历缓存数据
                        {
                            tempstr  = buf[i].ToString("X2")   " ";  // 拼接十六进制字符串
                        }
                        txtbRcvArea.AppendText(tempstr);//追加到接收数据显示框中
                    }
                    else
                    {
                        serialPort1.Encoding = System.Text.Encoding.GetEncoding("GB2312");  // 国标2312格式,防止出现乱码                     
                        txtbRcvArea.AppendText(serialPort1.ReadExisting());
                    }
                }));
            }
            catch (Exception ec)
            {
                MessageBox.Show("错误:ReceiveData"   ec.Message, "错误");
            }
        }

        void ThreadSavDat(object o)
        {
            byte[] buf = o as byte[];  // 声明一个数组
            if (writefile != null && writefile.CanWrite)
            {
                writefile.Write(buf, 0, buf.Length);  // 数据写入内部缓冲区
            }
        }

        // 数据保存
        private void btnSave_Click(object sender, EventArgs e)
        {
            string sSavePath = @txtbSavePath.Text   @"\DataSave.txt";  // 声明数据保存格式及保存路径
            try
            {
                StreamWriter Savefile = File.CreateText(sSavePath);  // 文件写入流
                if (txtbRcvArea.Text != "")  // 接收数据文本区数据状态判定
                {
                    Savefile.WriteLine(DateTime.Now.ToString("yyyy/MM/dd  hh:mm:ss"));  // 保存文件当前写入时间
                    Savefile.WriteLine(txtbRcvArea.Text);            // 接收数据文本区的数据写入保存文件
                }
                Savefile.Close();
            }
            catch (Exception ec)
            {
                MessageBox.Show("错误:保存按钮"   ec.Message, "错误");
            }
        }

        // 保存路径浏览
        private void btnBrowse_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.ShowDialog();  // 弹出路径选择窗口
            txtbSavePath.Text = folderBrowserDialog1.SelectedPath.ToString();  // 当前选择的路径转换成字符串放入文本区
        }
        
        // 计数清零
        private void btnClrCnt_Click(object sender, EventArgs e)
        {
            ReceiveByte_Cnt = 0;  // 收计数初始为0
            SendByte_Cnt = 0;     // 发计数初始为0
            lblRcvCnt.Text = ReceiveByte_Cnt.ToString("D");  // 收计数转换成字符串放入接收计数标签
            lblSndCnt.Text = SendByte_Cnt.ToString("D");     // 发计数转换成字符串放入发送计数标签
        }

        // 清除数据发送区域
        private void btnClrSnd_Click(object sender, EventArgs e)
        {
            txtbSndArea.Text = string.Empty;  // 清除数据发送区(Empty为不分配存储空间)
        }

        // 清除数据接收区域
        private void btnClrRcv_Click(object sender, EventArgs e)
        {
            txtbRcvArea.Text = string.Empty;  // 清除数据接收区(Empty为不分配存储空间)
        }
    }

}


实例下载地址

C#串口通信(含发送与接收串口数据)

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警