最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用c#進行串口通信的實現(xiàn)示例

 更新時間:2025年08月13日 11:18:13   作者:互聯(lián)網(wǎng)打工人no1  
本文主要介紹了使用c#進行串口通信的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、串口通信協(xié)議

1.串口通信協(xié)議簡介

串口通信(serial communication)是一種設備間非常常用的串行通信方式,大部分電子設備都支持,電子工程師再調(diào)試設備時也經(jīng)常使用該通信方式輸出調(diào)試信息。講到某一種通信協(xié)議,離不開的就是物理層,物理層主要表現(xiàn)形式是電平信號的高低幅值,分別代表的狀態(tài)。 串口的物理層有很多標準,主要包含RS232標準,該標準規(guī)定了信號的用途、通信接口以及信號的電平標準;

在上面的通訊方式中,兩個通訊設備的“DB9接口”之間通過串口信號線建立起連接,串口信號線中使用“RS-232標準”傳輸數(shù)據(jù)信號。
由于RS-232電平標準的信號不能直接被控制器直接識別,所以這些信號會經(jīng)過一個“電平轉(zhuǎn)換芯片”轉(zhuǎn)換成控制器能識別的“TTL校準”的電平信號,才能實現(xiàn)通訊。

電平標準 根據(jù)通信使用的電平標準不同,串口通信可以分為TTL標準和RS232標準

我們常見的電子電路中使用的TTL電平標準,理想狀態(tài)下,使用5V表示二級制邏輯1,使用0V表示邏輯0,而為了增加串口通信的遠距離傳輸以及抗干擾能力,它使用-15V表示邏輯1,+15V表示邏輯0,使用RS232與TTL電平標準表示同一個信號時的對比見圖

因為控制器一般使用TTL電平標準,所以常常會使用MA3232芯片對TTL以及RS232電平信號進行互相轉(zhuǎn)換。

RS-232信號線 在最初的應用中,RS-232串口標準常用于計算機、路由與調(diào)制調(diào)解器(MODEN,俗稱“貓”)之間的通訊 ,在這種通訊系統(tǒng)中,設備被分為數(shù)據(jù)終端設備DTE(計算機、路由)和數(shù)據(jù)通訊設備DCE(調(diào)制調(diào)解器)。我們以這種通訊模型講解它們的信號線連接方式及各個信號線的作用。

在舊式的臺式計算機中一般會有RS-232標準的COM口(也稱DB9接口)

其中接線口以針式引出信號線的稱為公頭,以孔式引出信號線的稱為母頭。在計算機中一般引出公頭接口,而在調(diào)制調(diào)解器設備中引出的一般為母頭,使用上圖中的串口線即可把它與計算機連接起來。通訊時,串口線中傳輸?shù)男盘柧褪鞘褂们懊嬷v解的RS-232標準調(diào)制的。

在這種應用場合下,DB9接口中的公頭及母頭的各個引腳的標準信號線接法見圖

上表中的是計算機端的DB9公頭標準接法,由于兩個通訊設備之間的收發(fā)信號(RXD與TXD)應交叉相連,所以調(diào)制調(diào)解器端的DB9母頭的收發(fā)信號接法一般與公頭的相反,兩個設備之間連接時,只要使用“直通型”的串口線連接起來即可

串口線中的RTS、CTS、DSR、DTR及DCD信號,使用邏輯 1表示信號有效,邏輯0表示信號無效。例如,當計算機端控制DTR信號線表示為邏輯1時,它是為了告知遠端的調(diào)制調(diào)解器,本機已準備好接收數(shù)據(jù),0則表示還沒準備就緒。

在目前的其它工業(yè)控制使用的串口通訊中,一般只使用RXD、TXD以及GND三條信號線,直接傳輸數(shù)據(jù)信號。而RTS、CTS、DSR、DTR及DCD信號都被裁剪掉了,如果您在前面被這些信號弄得暈頭轉(zhuǎn)向,那就直接忽略它們吧。

協(xié)議層 

串口通訊的數(shù)據(jù)包由發(fā)送設備通過自身的TXD接口傳輸?shù)浇邮赵O備的RXD接口。在串口通訊的協(xié)議層中,規(guī)定了數(shù)據(jù)包的內(nèi)容,它由啟始位、主體數(shù)據(jù)、校驗位以及停止位組成,通訊雙方的數(shù)據(jù)包格式要約定一致才能正常收發(fā)數(shù)據(jù),其組成見下圖。

波特率

在串口異步通訊中由于沒有時鐘信號(如前面講解的DB9接口中是沒有時鐘信號的),所以兩個通訊設備之間需要約定好波特率,即每個碼元的長度,以便對信號進行解碼常見的波特率為4800、9600、115200等。

  1. 通訊的起始和停止信號 串口通訊的一個數(shù)據(jù)包從起始信號開始,直到停止信號結(jié)束。數(shù)據(jù)包的起始信號由一個邏輯0的數(shù)據(jù)位表示,而數(shù)據(jù)包的停止信號可由0.5、1、1.5或2個邏輯1的數(shù)據(jù)位表示,只要雙方約定一致即可。
  2. 有效數(shù)據(jù) 在數(shù)據(jù)包的起始位之后緊接著的就是要傳輸?shù)闹黧w數(shù)據(jù)內(nèi)容,也稱為有效數(shù)據(jù),有效數(shù)據(jù)的長度常被約定為5、6、7或8位長。
  3. 數(shù)據(jù)校驗 在有效數(shù)據(jù)之后,有一個可選的數(shù)據(jù)校驗位。由于數(shù)據(jù)通信相對更容易受到外部干擾導致傳輸數(shù)據(jù)出現(xiàn)偏差,可以在傳輸過程加上校驗位來解決這個問題。校驗方法有奇校驗(odd)、偶校驗(even)、0校驗(space)、1校驗(mark)以及無校驗(noparity),它們介紹如下:
    1. 奇校驗要求有效數(shù)據(jù)和校驗位中“1”的個數(shù)為奇數(shù),比如一個8位長的有效數(shù)據(jù)為:01101001,此時總共有4個“1”,為達到奇校驗效果,校驗位為“1”,最后傳輸?shù)臄?shù)據(jù)將是8位的有效數(shù)據(jù)加上1位的校驗位總共9位。
    2. 偶校驗與奇校驗要求剛好相反,要求幀數(shù)據(jù)和校驗位中“1”的個數(shù)為偶數(shù),比如數(shù)據(jù)幀:11001010,此時數(shù)據(jù)幀“1”的個數(shù)為4個,所以偶校驗位為“0”。
    3. 0校驗是不管有效數(shù)據(jù)中的內(nèi)容是什么,校驗位總為“0”,1校驗是校驗位總為“1”。

在無校驗的情況下,數(shù)據(jù)包中不包含校驗位。

二、程序連接串口操作

SerialPort類的常用API:
屬性:

常用方法

常用事件

代碼示例:

using System.IO.Ports;
using System.Text;

namespace SerialPortCommunication
{
    class Program
    {
        private static SerialPort serialPort;

        public static void Main()
        {
            #region 串口通信
            ConnectSerialPort("COM2");
            ClosePort();
            ReciveData();
            SendData();

            Console.ReadKey();
            #endregion
        }

        /// <summary>
        /// 接收串口數(shù)據(jù)
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        private static void ReciveData()
        {
            // 連接串口
            var result = ConnectSerialPort("COM2");
            while(true)
            {
                if (result)
                {
                    // BytesToRead 代表串口中的字節(jié)大小
                    // 串口中的數(shù)據(jù)接收后,數(shù)據(jù)就被移除了。
                    var buffer = new byte[serialPort.BytesToRead];
                    // 接收發(fā)送的數(shù)據(jù)
                    #region 主動接收
                    serialPort.Read(buffer, 0, buffer.Length);
                    var resultString = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
                    Console.WriteLine($"接收到結(jié)果: {resultString}");
                }
            }
            
            serialPort.Close();
            
            #endregion
        }

        /// <summary>
        /// 發(fā)送數(shù)據(jù)的方法
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        private static void SendData()
        {
            // 連接串口
            var result = ConnectSerialPort("COM1");
            if (result)
            {
                // 發(fā)送數(shù)據(jù)
                //serialPort.Write("Hello SerialPort");
                //var buffer = new byte[] { 0x01, 0x02,0x03 };
                // 發(fā)送數(shù)據(jù)
                var buffer = Encoding.UTF8.GetBytes("中文");
                serialPort.Write(buffer, 0, buffer.Length);
                //serialPort.WriteBufferSize = 65535; // modbus 250
                //serialPort.WriteLine("Don't type chinese");
            }
            serialPort.Close();
        }

        /// <summary>
        /// 關(guān)閉串口的方法
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        private static void ClosePort()
        {
            if (serialPort == null)
            {
                return;                                
            }
            serialPort.Close();
        }

        /// <summary>
        /// 連接串口的方法
        /// </summary>
        /// <returns></returns>
        private static bool ConnectSerialPort(string portName)
        {
            // 創(chuàng)建串口對象
            serialPort = new SerialPort();
            // 設置連接串口名稱
            serialPort.PortName = portName;
            // 設置波特率
            serialPort.BaudRate = 9600;
            // 設置數(shù)據(jù)位
            serialPort.DataBits = 8;
            // 設置停止位
            serialPort.StopBits = StopBits.One;
            // 設置校驗位
            serialPort.Parity = Parity.None;
            serialPort.DataReceived += SerialPort_DataReceived;
            // 打開串口
            serialPort.Open();
            // 判斷串口是否成功打開
            if (serialPort.IsOpen)
            {
                Console.WriteLine("串口連接成功");
                return true;
            }
            else
            {
                Console.WriteLine("串口連接失敗");
            }

            return false;
        }

        /// <summary>
        /// 接收事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <exception cref="NotImplementedException"></exception>
        private static void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            var serialPort1 = sender as SerialPort;
            var buffer = new byte[serialPort1!.BytesToRead];
            serialPort1.Read(buffer, 0, buffer.Length);
            var resultString = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
            Console.WriteLine($"接收到結(jié)果: {resultString}");

        }
    }
}

到此這篇關(guān)于使用c#進行串口通信的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)c# 串口通信內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

奉贤区| 启东市| 林芝县| 光泽县| 蓝山县| 益阳市| 凉城县| 新泰市| 仙游县| 施甸县| 大洼县| 碌曲县| 阳泉市| 鹤岗市| 偃师市| 奉节县| 分宜县| 淳安县| 乌拉特前旗| 瑞丽市| 纳雍县| 咸宁市| 西昌市| 香港 | 九龙坡区| 西畴县| 海安县| 溧水县| 湘西| 调兵山市| 环江| 辽阳县| 新邵县| 湟源县| 甘肃省| 通州市| 阿拉善左旗| 怀来县| 镇康县| 天长市| 澄江县|