【转】C# 串口编程详解

转自:http://chowtrong.blog.163.com/blog/static/193026085201171932139652/

相信很多网友在学习C#编程时,遇到串口通讯的一系列问题。目前我也在学习C#串口编程类的基础知识,在网上也找了一些资料,但都存在一些问题,现在他们基础上再进行一定的修改,且更详细的表达如何实现串口编程,实现串口的发送与接收。本文目的在于:

1)总结C# 编程串口的属性定义、成员变量以及方法等问题;

2)掌握串口的发送与接收,利用虚拟串口来进行通讯,体验串口通讯;

实施步骤如下:

1、程序主界面如下:

C 串口编程详解 - chowtrong - chowtrong的博客

 2、启动VS2005编程工具,新建一个项目,并自拟定项目名称和存放路径。

 3、按主界面样式设计好各个控件。

 4、代码实施(简单介绍——具体实验请参见源码,下文可下载):

(1)在Form1.cs程序头文件处添加代码:

         using System.Threading;//用于启用线程类;

         using System.IO.Ports;//用于调用串口类函数

 (2)添加成员变量

       串口的基本参数有:串口号,波特率,数据位,停止位等,如图所示:

C 串口编程详解 - chowtrong - chowtrong的博客

 

        public string iPort = "com1"; //默认为串口1

        public int iRate = 9600; //波特率1200,2400,4800,9600
        public byte bSize = 8; //8 bits
        public int iTimeout = 1000; //延时时长
        public SerialPort serialPort1 = new SerialPort();//定义一个串口类的串口变量
        string serialReadString; //用于串口接收数据
        public bool IsCirlce;//判断是否选用循环发送数据
        public Thread Thd_Send; //开辟一个专用于发送数据的线程        
        public byte[] recb;  //用于存放接收数据的数组

 (3)程序开启,串口初始化

        private void Form1_Load(object sender, EventArgs e)
        {
            Microsoft.VisualBasic.Devices.Computer cmbCOM = new Microsoft.VisualBasic.Devices.Computer();

            foreach (string s in cmbCOM.Ports.SerialPortNames)
            {
                cmb_port.Items.Add(s);
            }
            IsCirlce = false;

        }

  (4)打开/关闭串口按钮代码

          //打开/关闭串口
        private void button5_Click(object sender, EventArgs e)
        {

            if (serialPort1.IsOpen)
            {
                serialPort1.Close();
                btnOpenCloseCOM.Text = "开启串口";
                msg.AppendText("串口被关闭……\r\n");
            }
            else
            {
                Parity myParity = Parity.None;
                StopBits MyStopBits = StopBits.One;

                serialPort1.PortName = cmb_port.Text;
                serialPort1.BaudRate = iRate;
                serialPort1.DataBits = bSize;
                serialPort1.Parity = myParity;
                serialPort1.StopBits = MyStopBits;
                serialPort1.ReadTimeout = iTimeout;

                serialPort1.Open();
                btnOpenCloseCOM.Text = "关闭串口";
                msg.AppendText("串口成功开启……\r\n");
            }
        }

        //开串口
        public bool OpenCom()
        {
            try
            {
                if (serialPort1.IsOpen)
                {
                    //mycom1.Close();
                    //mycom1.Open(); //打开串口
                    msg.AppendText("串口已打开\r\n");
                }
                else
                {
                    serialPort1.Open();//打开串口
                }
                return true;
            }
            catch (Exception e)
            {
                MessageBox.Show("错误:" + e.Message);
                return false;
            }

        }

  (5)发送按钮(主程序)

 //发送按钮
        private void button1_Click(object sender, EventArgs e)
        {
            if (t_send.Text == "")
            { MessageBox.Show("发送数据为空!"); return; }


            Thd_Send = new Thread(new ThreadStart(SendData));
            Thd_Send.Start();
        }

 

        //发送数据函数
        public void SendData()
        {
            if (System.Convert.ToBoolean(btnSend.Text == "发送"))
            {
                if (IsCirlce)
                {
                    btnSend.Invoke(new MethodInvoker(delegate { btnSend.Text="停止"; }));

                    while (true)
                    {

                        if (IsCirlce && serialPort1.IsOpen && (System.Convert.ToBoolean(btnSend.Text =="停止")))
                        {
                            SubSendData();
                        }
                        else
                        { goto L1; }
                    }
                }
                else
                {
                    SubSendData();
                }
            }
            else
            {
              btnSend.Invoke(new MethodInvoker(delegate { btnSend.Text = "发送"; }));
            }
        L1:
            btnSend.Invoke(new MethodInvoker(delegate { btnSend.Text = "发送"; }));
        }

 

        //发送数据子函数
        public void SubSendData()
        {

            //byte[] ZhengHeHouData = new byte[mycom1.ReadBufferSize];
            //定义一个无空格二位16进制排列的数组,这样可控制用户输入
            byte[] ZhengHeHouData = NoSpace_2Hex_SendData_ZhengHe(); //这里是整合后的发送的数组,每二位组成一个16进制的数排列
            int SendNumB = 0;

            try
            {
                serialPort1.WriteLine(Dis_Package(ZhengHeHouData));

                SendNumB = serialPort1.BytesToWrite;

                msg.Invoke(new MethodInvoker(delegate { msg.AppendText("\r\n发送数据!(" + serialPort1.BytesToWrite + "):" + Dis_Package(ZhengHeHouData)); }));

                Thread.Sleep(System.Convert.ToInt32(txtTimeGas.Text));
            }

            //mycom1.Read(ZhengHeHouData,1,1);

            //recb = mycom1.BytesToRead;

            //msg.AppendText("\r\n接收到数据包:" + Dis_Package(recb));

            //mycom1.Read(ZhengHeHouData, 0, ZhengHeHouData.Length);

            //if(recb.Length!=0)

            //msg.AppendText("\r\n接收到数据包:" + Dis_Package(recb));

            catch
            {
                //msg.AppendText("\r\n发送失败!");
                msg.Invoke(new MethodInvoker(delegate { msg.AppendText("\r\n发送失败!"); }));

                return;
            }
        }

        //去掉发送数组中的空格
        public string Delspace(string txt_SendData)
        {
            string Infact_SendData = "";
            for (int i = 0; i < txt_SendData.Length; i++)  //txt_SendData.Length为发送框内的数据
            {
                if (txt_SendData[i] != ' ')
                    Infact_SendData += txt_SendData[i];
            }
            return Infact_SendData;
        }
        
        //提取数据包--数组函数,返回整合后的数据,无空格二位16进制排列的数组
        public byte[] NoSpace_2Hex_SendData_ZhengHe()
        {
            string NoSpace_SendData = Delspace(t_send.Text);   //去掉所有空格,整合数据
            byte[] SendData = new byte[50];    
            int j = 0;
            for (int i = 0; i < NoSpace_SendData.Length; i = i + 2, j++) //将无空格发送的数据每二位组成一个数,存放在新的数组SendData中
                SendData[j] = Convert.ToByte(NoSpace_SendData.Substring(i, 2), 16);
            byte[] Last_SendData = new byte[j];  //Last_SendData最终返回的发送数据
            Array.Copy(SendData, Last_SendData, j); //复制整合后的数据,放入最终返回的数组里,以便调用
            return Last_SendData;  //最终返回的发送数据

        }

        //显示包信息
        public string Dis_Package(byte[] reb)
        {
            string temp = "";
            foreach (byte b in reb)
                temp += b.ToString("X2") + " "; //以每二位加一个空格显示数据
            return temp;
        }

  (6) 清空列表显示
        private void button3_Click(object sender, EventArgs e)
        {
            t_send.Text = string.Empty;  //清空发送端
            msg.Text = string.Empty;     //清空信息列表框
        }

  (7)应用设置按钮的代码

       //应用设置
        private void button2_Click(object sender, EventArgs e)
        {
            Parity myParity = Parity.None;
            StopBits MyStopBits = StopBits.One;
            if (serialPort1.IsOpen)
            {
                //msg.AppendText("串口处于开启状态,若要重新更换端口,请先关闭!\r\n");
                serialPort1.Close();
            }
            if (cmb_port.Text == "")
            {
                msg.AppendText("串口不能为空,请选择串口!\r\n");
            }
            else
            {
                serialPort1.PortName = Convert.ToString(cmb_port.Text);  //1,2,3,4

                serialPort1.BaudRate = Convert.ToInt16(t_rate.Text); //1200,2400,4800,9600
                serialPort1.DataBits = Convert.ToByte(t_bytesize.Text, 10); //8 bits
                serialPort1.Parity = myParity; // 0-4=no,odd,even,mark,space
                serialPort1.StopBits = MyStopBits;
                //iTimeout=3;
                if (this.OpenCom())
                    msg.AppendText("串口初始化成功……\r\n");
                else
                    msg.AppendText("串口初始化失败!\r\n");
            }
        }

 

 (8)  程序关闭,结束串口
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            serialPort1.Close();
        }

 (9) 用于显示接收数据
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            serialReadString = "";
            serialReadString += serialPort1.ReadExisting();
            msg.Invoke(new MethodInvoker(delegate { msg.AppendText("\r\n接收数据:" + serialReadString); }));
        }

 (10)控制输入

        //发送文本框内限制输入,须偶数位
        private void t_send_TextChanged(object sender, EventArgs e)
        {
            btnSend.Enabled = false;
            string SendDataLength = Delspace(t_send.Text);   //去掉所有空格,整合数据

            if (SendDataLength.Length % 2 != 0)
            {
                t_send.Focus();
            }
            else
            {
                btnSend.Enabled = true;
            }
        }

  (11)复选框程序(是否启用无限循环)

        private void chkCircle_CheckedChanged(object sender, EventArgs e)
        {
            if (IsCirlce)
            {
                IsCirlce = false;
            }
            else
            {
                IsCirlce = true;
            }
        }

 5、虚拟串口配置(可下载此软件,按照下载后的软件进行配置说明即可使用)

C 串口编程详解 - chowtrong - chowtrong的博客

 

6、打开UartAssist.exe软件,运行如下所示:

C 串口编程详解 - chowtrong - chowtrong的博客

 7、在配置好VSPM后,虚拟串口有3、4、5、6共四个串口,启动VSPM后,再运行串口通讯选择串口4,此时串口通讯程序与上面的 UartAssist.exe软件串口3进行了互联,如下图所示。选择串口4后,点击[应用设置]按钮,此时文本框显示:串口初始化成功....

C 串口编程详解 - chowtrong - chowtrong的博客

  8、发送测试,在设置数据包文本框内输入:12345678

C 串口编程详解 - chowtrong - chowtrong的博客

  9、接收数据,如图:

C 串口编程详解 - chowtrong - chowtrong的博客

    10、源码下载。由于我才开通博客,在博客中没找到可以添加附件的压缩包,如有需要的朋友,请留下电子邮箱,我发送给你!

 


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C是计算机科学中的一种常见的编程语言。它是由贝尔实验室的丹尼斯·里奇和肯·汤普逊在20世纪70年代初开发的。C语言具有高效简洁、功能强大和广泛适用的特点,因此成为了广泛应用于系统级编程和应用软件开发领域的重要工具。 C语言的语法和结构相对简单,易于学习和理解。它提供了丰富的基本数据类型和运算符,并支持多种流程控制结构,使得程序员能够方便地实现各种功能和算法。此外,C语言还具有良好的可移植性,同一套C代码可以在不同计算机平台上编译和运行。 C语言的广泛应用是由其编译型的特点决定的。通过将C代码编译为机器语言,可以获得高效的执行性能。因此,C语言可以用于开发各种系统级软件,比如操作系统、编译器以及嵌入式系统等。同时,许多应用软件也是用C语言开发的,如数据库管理系统、网络服务器和图形界面应用等。 在现代计算机科学中,C语言仍然占据着重要地位。许多编程语言如C++、Java和Python都是由C语言发展而来的,因此熟悉C语言可以为学习其他语言奠定良好的基础。此外,C语言也有很多相关的工具和库,为程序员提供了丰富的资源和支持。 总之,C语言是一种功能强大、高效简洁且广泛适用的编程语言,它在计算机科学领域具有重要作用,并为开发各种应用软件提供了有力的工具和框架。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值