欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c# 模擬串口通信 SerialPort的實現(xiàn)示例

 更新時間:2022年05月11日 16:03:10   作者:hey_lie  
本文主要介紹了c# 模擬串口通信 SerialPort的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、前導知識

串行口是計算機的標準接口,現(xiàn)在的PC機(個人電腦)一般至少有兩個串行口COM1和COM2。串行口應用廣泛,在數(shù)據(jù)通信、計算機網(wǎng)絡(luò)以及分布式工業(yè)控制系統(tǒng)中,經(jīng)常采用串行通信來交換數(shù)據(jù)和信息

電氣標準及協(xié)議來分包括RS-232-C、RS-422、RS485、USB(Universal Serial Bus)等

實現(xiàn)串口通信的必要設(shè)置

串口通信最重要的參數(shù)是波特率、數(shù)據(jù)位、停止位和奇偶校驗。

對于兩個進行通行的端口,這些參數(shù)必須匹配:

波特率

這是一個衡量通信速度的參數(shù)。它表示**每秒鐘傳送的bit的個數(shù)**。例如300波特表示每秒鐘發(fā)送300個bit,波特率和距離成反比。高波特率常常用于放置的很近的儀器間的通信,典型的例子就是GPIB設(shè)備的通信

數(shù)據(jù)位

這是衡量通信中實際數(shù)據(jù)位的參數(shù)。當計算機發(fā)送一個信息包,實際的數(shù)據(jù)不會是8位的,標準的值是5、7和8位,如何設(shè)置取決于你想傳送的信息。比如,標準的ASCII碼是0~127(7位)。擴展的ASCII碼是0~255(8位)。如果數(shù)據(jù)使用簡單的文本(標準 ASCII碼),那么每個數(shù)據(jù)包使用7位數(shù)據(jù)。每個包是指一個字節(jié),包括開始/停止位,數(shù)據(jù)位和奇偶校驗位。由于實際數(shù)據(jù)位取決于通信協(xié)議的選取,術(shù)語“包”指任何通信的情況。

停止位

用于表示單個包的最后一位。典型的值為1,1.5和2位。由于數(shù)據(jù)是在傳輸線上定時的,并且每一個設(shè)備有其自己的時鐘,很可能在通信中兩臺設(shè)備間出現(xiàn)了小小的不同步。因此停止位不僅僅是表示傳輸?shù)慕Y(jié)束,并且提供計算機校正時鐘同步的機會。適用于停止位的位數(shù)越多,不同時鐘同步的容忍程度越大,但是數(shù)據(jù)傳輸率同時也越慢

奇偶校驗位

 在串口通信中一種簡單的檢錯方式。有四種檢錯方式:偶、奇、高和低。當然沒有校驗位也是可以的。對于偶和奇校驗的情況,串口會設(shè)置校驗位(數(shù)據(jù)位后面的一位),用一個值確保傳輸?shù)臄?shù)據(jù)有偶個或者奇?zhèn)€邏輯高位。例如,如果數(shù)據(jù)是011,那么對于偶校驗,校驗位為0,保證邏輯高的位數(shù)是偶數(shù)個。如果是奇校驗,校驗位位1,這樣就有3個邏輯高位。高位和低位不真正的檢查數(shù)據(jù),簡單置位邏輯高或者邏輯低校驗。這樣使得接收設(shè)備能夠知道一個位的狀態(tài),有機會判斷是否有噪聲干擾了通信或者是否傳輸和接收數(shù)據(jù)是否不同步

二、實驗

我們將通過模擬串口通信,在pc機上進行兩個串口(COM1、COM2)的交互

需要用到的軟件:

Launch Virtual Serial Port Driver Pro:虛擬串口。使用它來模擬兩個串口的連接

繪制窗口

 代碼實現(xiàn)

1.使用SerialPort控制串口

private SerialPort sp1 = new SerialPort();

2.打開串口

        private void button2_Click(object sender, EventArgs e)
        {
            if (!sp1.IsOpen)
            {
                try
                {
                    //串口號
                    sp1.PortName = "COM1";
                    //波特率
                    sp1.BaudRate = 115200;
                    //數(shù)據(jù)位
                    sp1.DataBits = 8;
                    //停止位
                    sp1.StopBits = StopBits.One;
                    //奇偶校驗位
                    sp1.Parity = Parity.Even;
                    //DataReceived事件發(fā)送前,內(nèi)部緩沖區(qū)里的字符數(shù)
                    sp1.ReceivedBytesThreshold = 1;
                    sp1.RtsEnable = true; sp1.DtrEnable = true; sp1.ReadTimeout = 3000;
                   // Control.CheckForIllegalCrossThreadCalls = false;
                    //表示將處理 System.IO.Ports.SerialPort 對象的數(shù)據(jù)接收事件的方法。
                    sp1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(sp1_DataReceived_1);
                    //打開串口
                    sp1.Open();
                    MessageBox.Show("COM1打開成功!");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("COM1打開失敗!");
                }
            }
            else
            {
                MessageBox.Show("COM1打開成功!");
            }
        }

3.關(guān)閉串口

        private void button3_Click(object sender, EventArgs e)
        {
            if (sp1.IsOpen)
            {
                sp1.Close();
                MessageBox.Show("COM1關(guān)閉成功!");
            }
        }

串口2的打開和關(guān)閉同理串口1實現(xiàn)

4.發(fā)送

        private void button1_Click(object sender, EventArgs e)
        {
            if (sp1.IsOpen)
            {
                if (!string.IsNullOrEmpty(this.textBox1.Text))
                {
                    sp1.WriteLine(this.textBox1.Text+"\r\n");
 
                }
                else
                {
                    MessageBox.Show("發(fā)送數(shù)據(jù)為空");
                }
            }
            else
            {
                MessageBox.Show("COM1未打開!");
            }
 
 
        }

5.接收

        StringBuilder builder1 = new StringBuilder();
        //在接收到了ReceivedBytesThreshold設(shè)置的字符個數(shù)或接收到了文件結(jié)束字符并將其放入了輸入緩沖區(qū)時被觸發(fā)
        public void sp1_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
        {
            Console.WriteLine("接收中...");
            int n = sp1.BytesToRead;      //先記錄下來,避免某種原因,人為的原因,操作幾次之間時間長,緩存不一致
            byte[] buf = new byte[n];   //聲明一個臨時數(shù)組存儲當前來的串口數(shù)據(jù)
            sp1.Read(buf, 0, n);      //讀取緩沖數(shù)據(jù)
            builder1.Remove(0, builder1.Length); //清除字符串構(gòu)造器的內(nèi)容
            builder1.Append(Encoding.ASCII.GetString(buf));
            string comdata = builder1.ToString();
            Console.WriteLine("data: + " + comdata);
            this.Invoke(settextevent,comdata);
        }

這里僅僅實現(xiàn)了一般的接收方式,并不嚴謹和健壯

測試

使用軟件模擬串口連接

 打開兩個程序

 在一程序中打開串口1,在二程序中打開串口2,發(fā)送消息

在一程序中輸入字符"hello,HanHanCheng!",發(fā)現(xiàn)在二程序中接收到,同樣,在二程序中輸入,在一中也能收到

 三、總結(jié)

1.由于是異步線程接收,在接收中需要使用委托來跨線程調(diào)用組件

        public delegate void settext(string text);
        public event settext settextevent;
        public void set(string text)
        {
            this.textBox2.Text = text;
        }
        //再注冊
        settextevent += set;

2.DataReceived事件觸發(fā)條件需要注意,可能在實現(xiàn)時,無法觸發(fā)導致無法接收。

觸發(fā)條件是:在接收到了ReceivedBytesThreshold設(shè)置的字符個數(shù)或接收到了文件結(jié)束字符并將其放入了輸入緩沖區(qū)時被觸發(fā)

四、附件完整代碼

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 System.IO.Ports;
 
namespace Training_USBCOM
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            settextevent += set;
        }
 
        private SerialPort sp1 = new SerialPort();
        StringBuilder builder = new StringBuilder();
        private void button1_Click(object sender, EventArgs e)
        {
            if (sp1.IsOpen)
            {
                if (!string.IsNullOrEmpty(this.textBox1.Text))
                {
                    sp1.WriteLine(this.textBox1.Text+"\r\n");
 
                }
                else
                {
                    MessageBox.Show("發(fā)送數(shù)據(jù)為空");
                }
            }
            else
            {
                MessageBox.Show("COM1未打開!");
            }
 
 
        }
 
        public delegate void settext(string text);
        public event settext settextevent;
        public void set(string text)
        {
            this.textBox2.Text = text;
        }
        
 
        StringBuilder builder1 = new StringBuilder();
        //在接收到了ReceivedBytesThreshold設(shè)置的字符個數(shù)或接收到了文件結(jié)束字符并將其放入了輸入緩沖區(qū)時被觸發(fā)
        public void sp1_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
        {
            Console.WriteLine("接收中...");
            int n = sp1.BytesToRead;      //先記錄下來,避免某種原因,人為的原因,操作幾次之間時間長,緩存不一致
            byte[] buf = new byte[n];   //聲明一個臨時數(shù)組存儲當前來的串口數(shù)據(jù)
            sp1.Read(buf, 0, n);      //讀取緩沖數(shù)據(jù)
            builder1.Remove(0, builder1.Length); //清除字符串構(gòu)造器的內(nèi)容
            builder1.Append(Encoding.ASCII.GetString(buf));
            string comdata = builder1.ToString();
            Console.WriteLine("data: + " + comdata);
            this.Invoke(settextevent,comdata);
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            if (!sp1.IsOpen)
            {
                try
                {
                    //串口號
                    sp1.PortName = "COM1";
                    //波特率
                    sp1.BaudRate = 115200;
                    //數(shù)據(jù)位
                    sp1.DataBits = 8;
                    //停止位
                    sp1.StopBits = StopBits.One;
                    //奇偶校驗位
                    sp1.Parity = Parity.Even;
                    //DataReceived事件發(fā)送前,內(nèi)部緩沖區(qū)里的字符數(shù)
                    sp1.ReceivedBytesThreshold = 1;
                    sp1.RtsEnable = true; sp1.DtrEnable = true; sp1.ReadTimeout = 3000;
                   // Control.CheckForIllegalCrossThreadCalls = false;
                    //表示將處理 System.IO.Ports.SerialPort 對象的數(shù)據(jù)接收事件的方法。
                    sp1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(sp1_DataReceived_1);
                    //打開串口
                    sp1.Open();
                    MessageBox.Show("COM1打開成功!");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("COM1打開失?。?);
                }
            }
            else
            {
                MessageBox.Show("COM1打開成功!");
            }
        }
 
        private void button3_Click(object sender, EventArgs e)
        {
            if (sp1.IsOpen)
            {
                sp1.Close();
                MessageBox.Show("COM1關(guān)閉成功!");
            }
        }
 
        private void button5_Click(object sender, EventArgs e)
        {
            if (!sp1.IsOpen)
            {
                try
                {
                    //串口號
                    sp1.PortName = "COM2";
                    //波特率
                    sp1.BaudRate = 115200;
                    //數(shù)據(jù)位
                    sp1.DataBits = 8;
                    //停止位
                    sp1.StopBits = StopBits.One;
                    //奇偶校驗位
                    sp1.Parity = Parity.Even;
                    sp1.ReceivedBytesThreshold = 1;
                    sp1.RtsEnable = true; sp1.DtrEnable = true; sp1.ReadTimeout = 3000;
                    Control.CheckForIllegalCrossThreadCalls = false;
                    //表示將處理 System.IO.Ports.SerialPort 對象的數(shù)據(jù)接收事件的方法。
                    sp1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(sp1_DataReceived_1);
                    //打開串口
                    sp1.Open();
                    MessageBox.Show("COM2打開成功!");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("COM2打開失敗!");
                }
            }
            else
            {
                MessageBox.Show("COM2打開成功!");
            }
        }
 
        private void button4_Click(object sender, EventArgs e)
        {
            if (sp1.IsOpen)
            {
                sp1.Close();
                MessageBox.Show("COM2關(guān)閉成功!");
            }
        }
    }
}

到此這篇關(guān)于c# 模擬串口通信 SerialPort的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)c# 模

相關(guān)文章

最新評論