学习记录之基于C#的串口助手以及GPS数据解析和保存

学习记录之基于C#的串口助手以及GPS数据解析和保存

一.声明

这是一篇学习记录,可能与很多大牛的代码相似,因为我的代码也是copy加各种整合,存在很多不严谨的地方,为了更好的学习而将学习到的东西记录下来,若有幸被人浏览到文章,希望能够指正。

二.功能介绍

我需要做一个串口通信界面来接收GPS模块发送过来的数据并且解析得到日期、时间、经度和纬度,并且保存到txt文本中。

三.串口助手界面

接收GPS数据并且解析在右下角
接收到GPS数据并且我在右下角用了四个label方便查看解析后的结果是否正确。串口助手做的比较简单,只有一些基础功能,打开关闭串口,发送和接收,解析数据保存,清空接收框,计字节数。

四. 代码实现

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;
using System.IO;

namespace 串口助手2
{
    public partial class 串口助手 : Form
    {
        public 串口助手()
        {
            InitializeComponent();
        }
        private long receive_count = 0; //接收字节计数, 作用相当于全局变量
        private long send_count = 0;
        SerialPort sp1 = new SerialPort();
       // private StringBuilder builder = new StringBuilder();
        private DateTime current_time = new DateTime();    //为了避免在接收处理函数中反复调用,依然声明为一个全局变量
        //rivate DataTime current_time = new DataTime(); //为了避免在接收处理函数中反复调用,依然声明为一个全局变量
        private StringBuilder sb = new StringBuilder();//为了避免在接收处理函数中反复调用,依然声明为一个全局变量

        private void Form1_Load(object sender, EventArgs e)
        {
            //设置默认值
            timer2.Enabled = true;
            comboBox2.Text = "9600";
            comboBox3.Text = "8";
            comboBox4.Text = "None";
            comboBox5.Text = "1";
            //获取电脑当前可用串口并添加到选项列表中
            comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
            sp1.BaudRate = 9600;
            sp1.Parity = Parity.None;
            sp1.StopBits = StopBits.One;
            sp1.DataBits = 8;
            sp1.Handshake = Handshake.None;
            sp1.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataRecived);//注册DataReceived事件,当受到数据时调用sp1_DataReceived
            sp1.Close();

        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }

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


            try
            {  //将可能产生异常的代码放置在try块中
                //根据当前串口属性来判断是否打开
                if (sp1.IsOpen)
                {
                    //串口已经处于打开状态
                    sp1.Close(); //关闭串口

                    button1.Text = "打开串口";
                    button1.BackColor = Color.ForestGreen;
                    label8.Text = "窗口已关闭";
                    label8.ForeColor = Color.Red;


                    comboBox1.Enabled = true;
                    comboBox2.Enabled = true;
                    comboBox3.Enabled = true;
                    comboBox4.Enabled = true;
                    comboBox5.Enabled = true;
                 //   textBox1.Text = "";//清空接收区
                    textBox2.Text = "";//清空发送区

                }
                else
                {
                    //串口已经处于关闭状态,则设置好串口属性后打开
                    comboBox1.Enabled = false;
                    comboBox2.Enabled = false;
                    comboBox3.Enabled = false;
                    comboBox4.Enabled = false;
                    comboBox5.Enabled = false;
                    sp1.PortName = comboBox1.Text;
                    sp1.BaudRate = Convert.ToInt32(comboBox2.Text);
                    sp1.DataBits = Convert.ToInt16(comboBox3.Text);

                    if (comboBox4.Text.Equals("None"))
                        sp1.Parity = System.IO.Ports.Parity.None;
                    else if (comboBox4.Text.Equals("Odd"))
                        sp1.Parity = System.IO.Ports.Parity.Odd;
                    else if (comboBox4.Text.Equals("Even"))
                        sp1.Parity = System.IO.Ports.Parity.Even;

                    if (comboBox5.Text.Equals("1"))
                        sp1.StopBits = System.IO.Ports.StopBits.One;
                    else if (comboBox5.Text.Equals("1.5"))
                        sp1.StopBits = System.IO.Ports.StopBits.OnePointFive;
                    else if (comboBox5.Text.Equals("2"))
                        sp1.StopBits = System.IO.Ports.StopBits.Two;

                    sp1.Open();//打开串口
                    button1.Text = "关闭串口";
                    button1.BackColor = Color.Firebrick;
                    label8.Text = "窗口已打开";
                    label8.ForeColor = Color.ForestGreen ;
                }
            }
            catch
            {
                MessageBox.Show("端口打开失败", "错误");
            }
        }

        private void button2_Click(object sender, EventArgs e)   //发送按钮
        {
            int num = textBox2.Text.Length;
            
            try
            {
                //首先判断串口是否开启
                if (sp1.IsOpen)
                {
                    //串口处于开启状态,将发送区文本发送
                    sp1.WriteLine(textBox2.Text);

                }
                send_count += num;      //计数变量累加
                label9.Text = "Tx:" + send_count.ToString() + "Bytes";   //刷新界面

            }
            catch
            {
                MessageBox.Show("端口发送失败,系统将关闭当前串口", "错误");
                sp1.Close();
            }
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {


        }

        int hour, min, sec,a,  d, lon1, lon2, lon3, lat1, lat2, lat3, year, mon, day;
        string lat, lon;
        double b, c;
        string str = "";
       
        private void serialPort_DataRecived(object sender, SerialDataReceivedEventArgs e)
        {
             int sum = sp1.BytesToRead; //获取接收缓冲区中的字节数;
           byte[] received_buf = new byte[sum];//声明一个大小为num的字节数据用于存放读出的byte型数据
             sp1.Read(received_buf, 0, sum);//读取缓冲区中num个字节到byte数组中
             sb.Clear();        //防止出错,首先清空字符串构造器
            sb.Append(Encoding.ASCII.GetString(received_buf));  //将整个数组解码为ASCII数组
            str = str + sb.ToString();

           // str = str +sp1.ReadExisting();  // 读取串口数据

            //显示时间
            try
            {
                this.Invoke((EventHandler)(delegate
                {
                    if (checkBox1.Checked)
                    {
                        current_time = System.DateTime.Now; //获取当前时间
                        textBox1.AppendText(current_time.ToString("HH:mm:ss") + " " + sb.ToString());

                    }

                    else
                    {

                        textBox1.AppendText(str);
                        receive_count += sum; //接收字节计数变量增加sum
                        label10.Text = "Rx:" + receive_count.ToString() + "Bytes";
                        timer2.Start();
                        }                    
                 }));
            }
           catch
            {
                MessageBox.Show("端口接收失败,系统将关闭当前串口", "错误");
                sp1.Close();
            }
           }

        private void timer2_Tick(object sender, EventArgs e)
        {
            int i = str.IndexOf("$GPRMC");
            if (i > -1)
            {

                int j = str.IndexOf("\r\n", i);

                if (j > -1)
                {
                    string GPS_text = str.Substring(i, j - i);

                    if (GPS_text.Length > 60)
                    {
                        string[] GPS_info = GPS_text.Split(',');

                        /************时间********************/
                        a = Convert.ToInt32(Convert.ToDouble(GPS_info[1]));
                        // a = GPS_info[1];
                        hour = a / 10000;
                        min = a % 10000 / 100;
                        sec = a % 100;
                        if (16 <= hour && hour <= 24)
                        {
                            hour = 8 - (24 - hour);
                        }
                        else
                        {
                            hour = hour + 8;
                        }

                        // label6.Text = GPS_info[1];
                        label6.Text = hour.ToString().PadLeft(2, '0') + ":" + min.ToString().PadLeft(2, '0') + ":" + sec.ToString().PadLeft(2, '0');

                        /*******经度**************/
                        b = Convert.ToDouble(GPS_info[5].ToString());
                        lat1 = (int)b / 100;
                        lat2 = (int)b % 100;
                        lat3 = (int)(b % 1 * 60 * 100);
                        lat = lat1.ToString() + "." + lat2.ToString() + lat3.ToString();
                        label7.Text = lat + GPS_info[4];
                        // label7.Text = GPS_info[5];

                        /*****************纬度**************/
                        c = Convert.ToDouble(GPS_info[3].ToString());
                        lon1 = (int)c / 100;
                        lon2 = (int)c % 100;
                        lon3 = (int)(c % 1 * 60 * 100);
                        lon = lon1.ToString() + "." + lon2.ToString() + lon3.ToString();
                        label11.Text = lon + GPS_info[6];
                        //  label11.Text = GPS_info[6];
                        /************日期*****************/
                        d = Convert.ToInt32(GPS_info[9]);
                        day = d / 10000;
                        mon = d % 10000 / 100;
                        year = d % 100 + 2000;
                        label12.Text = year.ToString() + "-" + mon.ToString().PadLeft(2, '0') + "-" + day.ToString().PadLeft(2, '0');
                        //label12.Text = GPS_info[9];
                        str = "";
                        
                    }


                }

            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        //清空
        private void button3_Click(object sender, EventArgs e)
        {
            textBox1.Text = "";  //清空接收文本框
            textBox2.Text = "";     //清空发送文本框
            receive_count = 0;          //计数清零
            send_count = 0;          //计数清零
            label10.Text = "Rx:" + receive_count.ToString() + "Bytes";   //刷新界面
            label9.Text = "Tx:" + send_count.ToString() + "Bytes";   //刷新界面

        }

        private void label8_Click(object sender, EventArgs e)
        {

        }

        private void DataReceive_Click(object sender, EventArgs e)  //保存数据按钮
        {
            timer1.Interval = 60000;
            timer1.Start();
        }
        private void timer1_Tick(object sender, EventArgs e)   
        {
            FileStream fs = new FileStream("C:\\Users\\admin\\Desktop\\test.txt", FileMode.Append, FileAccess.Write); //创建读写文件
            StreamWriter sw = new StreamWriter(fs);
            sw.WriteLine(label12.Text + "," + label6.Text + "," + label7.Text + "," + label11.Text);
            sw.Close();
            fs.Close();

        }
    }

    }

串口:label1 combox1
波特率:label2 combox2
数据位:label3 combox3
校验位:label4 combox4
停止位:label5 combox5
串口已关闭:label8
TX:label9
RX:label10
接收框:textbox1
发送框:textbox2
打开串口:button1
发送:button2
清空接收:button3
保存数据:DataReceive
显示接收数据时间:checkbox1
计时器1:timer1
计时器2:timer2

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页