⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpssoftware.cs

📁 用C#语言编写
💻 CS
字号:
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;
using System.Threading;

namespace GPSIOSerialPort
{
    public partial class GPSSoftware : Form
    {
        private SerialPort myPort;
        private EventHandler updateDataHandle;
        private string currentData;

        public GPSSoftware()
        {
            InitializeComponent();

            this.selectedPort.SelectedIndex = 5;
            this.selectedRate.SelectedIndex = 0;

            myPort = new SerialPort("COM6", 4800);
            myPort.Parity = Parity.None;
            myPort.StopBits = StopBits.One;
            myPort.DataBits = 8;
            myPort.ReadTimeout = 1000;

            #region 线程中调用控件的两种方法
            //以下为线程调用控件的两种办法:
            //法一:(可用于PC和PDA两种情况,可见于本程序)
            /*虽然多线程处理最适于运行过程和类方法,它也可以用于窗体和控件。使用时,请注意以下几点:

            (1)只要有可能,便仅在用来创建它的线程上执行控件的各种方法。若须从另一线程调用控件的方法,则必须使用 Invoke 来调用该方法。

            (2)不要使用 SyncLock 语句锁定操作控件或窗体的线程。由于控件和窗体的方法有时回调到调用过程,因此可能会因无意中创建了死锁而终止运行(死锁是指两个线程都等待对方释放锁定,从而导致应用程序暂停的情况)。*/

            //法二:(只可用于PC,2003版本的vs不需要)
            //Control.CheckForIllegalCrossThreadCalls = false;
            #endregion

            updateDataHandle = new EventHandler(updateGpsData);
        }

        private void open_Click(object sender, EventArgs e)
        {
            gpsInfo.Text = "正在打开串口!\r\n";
            myPort.Open();

            if (myPort.IsOpen)
            {
                gpsInfo.Text += "串口已打开,正在等待GPS数据!\r\n";
                myPort.DataReceived += new SerialDataReceivedEventHandler(myPort_DataReceived);
            }
            else
            {
                gpsInfo.Text += "串口打开失败!\r\n";
            }
        }

        public void myPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //说明:可能读取到的数据长度不定,若直接读取512字节,则可能造成各次触发都等待读取512字节数据。,所以安全的措施是读取myPort.BytesToRead这么长。
            int len = myPort.BytesToRead;
            Byte[] buffer = new Byte[len];
            myPort.Read(buffer, 0, len);
            if (len == 0)
            {
                return;
            }
            else
            {
                currentData = Encoding.ASCII.GetString(buffer, 0, buffer.Length);
                //这里使用gpsInfo.Text += Encoding.ASCII.GetString(buffer, 0, buffer.Length);是错误的.因为CE不允许子线程调用控件
                Invoke(updateDataHandle);
            }
        }

        private void updateGpsData(object sender, EventArgs e)
        {
            gpsInfo.Text += currentData;
            if (gpsInfo.Text.Length > 5000)
            {
                gpsInfo.Text = gpsInfo.Text.Substring(5000, gpsInfo.Text.Length - 5000);
                System.GC.Collect();
            }
        }

        private void close_Click(object sender, EventArgs e)
        {
            if (myPort.IsOpen)
            {
                myPort.DataReceived -= new SerialDataReceivedEventHandler(myPort_DataReceived);
                myPort.Close();
            }
        }

        private void exit_Click(object sender, EventArgs e)
        {
            if (myPort.IsOpen)
            {
                myPort.DataReceived -= new SerialDataReceivedEventHandler(myPort_DataReceived);
                myPort.Close();
            }
            Close();
        }

    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -