国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設(shè)計 > 正文

C#串口通信—向串口發(fā)送數(shù)據(jù),同步接收返回數(shù)據(jù)

2019-11-17 02:37:45
字體:
供稿:網(wǎng)友

C#串口通信—向串口發(fā)送數(shù)據(jù),同步接收返回數(shù)據(jù)

最近寫C#串口通信程序,系統(tǒng)是B/S架構(gòu)。SerialPort類有一個DataReceived事件,用來接收串口返回的數(shù)據(jù),但這種方式在C/S架構(gòu)下很好用,但B/S就不好處理了。所以寫了一個同步模式接收返回數(shù)據(jù)的方法,不使用DataReceived事件。經(jīng)過測試,可以正常使用。

一、MachineFactory類

為什么使用工廠類:售貨機由不止一個廠家提供,接口協(xié)議都不一樣。

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Reflection;using System.IO;using System.IO.Ports;namespace IMachineDll{    /// <summary>    /// 售貨機工廠類    /// </summary>    public class MachineFactory    {        /// <summary>        /// 貨機接口緩存        /// </summary>        PRivate static Dictionary<string, IMachine> dicMachine = new Dictionary<string, IMachine>();        /// <summary>        /// 鎖變量        /// </summary>        public static object _lock = new object();        /// <summary>        /// 創(chuàng)建售貨機類        /// </summary>        /// <param name="path">DLL物理路徑</param>        /// <param name="dllName">DLL名稱(不含擴展名),命名空間必須為DLL名稱加“Dll”后綴,類名必須和DLL名稱相同</param>        ///  <param name="com">串口名稱,如:COM1</param>        public static IMachine Create(string path, string dllName, string com)        {            if (!dicMachine.ContainsKey(dllName)                || dicMachine[dllName] == null)            {                using (FileStream fs = new FileStream(path + dllName + ".dll", FileMode.Open, Fileaccess.Read))                {                    using (MemoryStream ms = new MemoryStream())                    {                        byte[] byteArray = new byte[4096];                        while (fs.Read(byteArray, 0, byteArray.Length) > 0)                        {                            ms.Write(byteArray, 0, byteArray.Length);                        }                        Assembly assembly = Assembly.Load(ms.ToArray());                        dicMachine[dllName] = (IMachine)assembly.CreateInstance(dllName + "Dll." + dllName, false, BindingFlags.Default, null, new object[] { com }, null, null);                    }                }            }            return dicMachine[dllName];        }    }}
View Code

二、Machine類

1、變量與構(gòu)造函數(shù)

/// <summary>/// 串口資源/// </summary>private SerialPort serialPort = null;public Machine(string com){    serialPort = new SerialPort(com, 9600, Parity.None, 8, StopBits.One);    serialPort.ReadBufferSize = 1024;    serialPort.WriteBufferSize = 1024;}
View Code

2、向串口發(fā)送數(shù)據(jù),同步接收返回數(shù)據(jù)的方法:

/// <summary>/// 向串口發(fā)送數(shù)據(jù),讀取返回數(shù)據(jù)/// </summary>/// <param name="sendData">發(fā)送的數(shù)據(jù)</param>/// <returns>返回的數(shù)據(jù)</returns>private byte[] ReadPort(byte[] sendData){    lock (MachineFactory._lock)    {        //打開連接        if (!serialPort.IsOpen) serialPort.Open();        //發(fā)送數(shù)據(jù)        serialPort.Write(sendData, 0, sendData.Length);        //讀取返回數(shù)據(jù)        DateTime dt = DateTime.Now;        while (serialPort.BytesToRead == 0)        {            Thread.Sleep(1);            if (DateTime.Now.Subtract(dt).TotalMilliseconds > 5000) //如果5秒后仍然無數(shù)據(jù)返回,則視為超時            {                throw new Exception("主版無響應(yīng)");            }        }        Thread.Sleep(50);        byte[] recData = new byte[serialPort.BytesToRead];        serialPort.Read(recData, 0, recData.Length);        //關(guān)閉連接        if (serialPort.IsOpen) serialPort.Close();        return recData;    }}
View Code

優(yōu)化版:

/// <summary>/// 向串口發(fā)送數(shù)據(jù),讀取返回數(shù)據(jù)/// </summary>/// <param name="sendData">發(fā)送的數(shù)據(jù)</param>/// <returns>返回的數(shù)據(jù)</returns>private byte[] ReadPort(byte[] sendData){    lock (MachineFactory._lock)    {        //打開連接        if (!serialPort.IsOpen) serialPort.Open();        //發(fā)送數(shù)據(jù)        serialPort.Write(sendData, 0, sendData.Length);        //讀取返回數(shù)據(jù)        DateTime dt = DateTime.Now;        while (serialPort.BytesToRead < 2)        {            Thread.Sleep(1);            if (DateTime.Now.Subtract(dt).TotalMilliseconds > 5000) //如果5秒后仍然無數(shù)據(jù)返回,則視為超時            {                throw new Exception("主版無響應(yīng)");            }        }        List<byte> recList = new List<byte>();        byte[] recData = new byte[serialPort.BytesToRead];        serialPort.Read(recData, 0, recData.Length);        recList.AddRange(recData);        int length = recData[1] + 3; //報文數(shù)據(jù)總長度        while (recList.Count < length)        {            if (serialPort.BytesToRead > 0)            {                recData = new byte[serialPort.BytesToRead];                serialPort.Read(recData, 0, recData.Length);                recList.AddRange(recData);            }            Thread.Sleep(1);        }        //關(guān)閉連接        if (serialPort.IsOpen) serialPort.Close();        return recList.ToArray();    }}
View Code

3、發(fā)送聯(lián)機指令:

/// <summary>/// 聯(lián)機/// </summary>/// <param name="msg">傳出錯誤信息</param>/// <returns>聯(lián)機是否成功</returns>public bool Connect(out string msg){    byte[] sendData = new byte[] { 0x01, 0x01, 0x00, 0x00 };    CommonUtil.CalCheckCode(sendData);    byte[] recData = ReadPort(sendData);    if (recData.Length >= 4        && recData[0] == 0x01        && recData[1] == 0x02        && recData[2] == 0x00        && CommonUtil.ValidCheckCode(recData))    {        switch (recData[3])        {            case 0x00:                msg = "控制主板正在重啟";                return false;            case 0x01:                msg = "聯(lián)機成功";                return true;            case 0x02:                msg = "控制主板正在維護";                return false;            case 0x03:                msg = "控制主板收到的數(shù)據(jù)格式不正確";                return false;            default:                msg = "未知狀態(tài)";                return false;        }    }    else if (IsRunning(recData, out msg) || !IsConnected(recData, out msg))    {        return false;    }    else    {        throw new Exception("貨機返回的數(shù)據(jù)格式不正確");    }}
View Code

三、如何使用

1、Controller層代碼(還不完善,僅測試,真實情況是根據(jù)硬件信息,確定調(diào)用哪個Dll使用哪個串口):

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 木里| 新乡市| 兖州市| 宁化县| 扎赉特旗| 卢龙县| 阿克苏市| 积石山| 磐石市| 都匀市| 康定县| 东丽区| 宿迁市| 滨州市| 吉林省| 阿巴嘎旗| 资兴市| 邳州市| 九江市| 斗六市| 无极县| 逊克县| 舟曲县| 延庆县| 门头沟区| 沈丘县| 德令哈市| 松潘县| 靖江市| 夏邑县| 罗甸县| 旬阳县| 丹江口市| 枝江市| 平顶山市| 凭祥市| 清水河县| 上虞市| 呼玛县| 加查县| 监利县|