博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c# 串口
阅读量:4334 次
发布时间:2019-06-07

本文共 8051 字,大约阅读时间需要 26 分钟。

记录一下事件经过。

现在的项目是采集仪表的数据。以前都是配置好串口,波特率,数据位,停止位,校验位然后就可以接受仪表发送来的数据进行解析了。

现在遇到了一种新的仪表,分为两个模式。一个是数据模式,像其他仪表一样,将仪表的数据主动发送给串口,但是不能接受命令数据。一种是命令模式,可以接受命令数据,但是不会主动发送数据。也就是说你想要实现远程控制仪表,给他发送命令的话,就需要主动发送获取数据的命令去主动读数。

/// <summary>

/// 串口类
/// </summary>
private SerialPort _spCom;  这是微软提供的串口类

///         ///     打开串口,并注册数据接收方法        ///         /// 
public bool Open() { var rtn = false; if (_curWeightCfg != null)//_curWeightCfg 是从配置文件中读取配置的串口信息,COM口,波特率,数据位,停止位,校验位 { WeightDeviceLogger.Debug( string.Format("设置串口参数。ComPort={0},Baudrate={1},DataBits={2}, Parity={3},StopSize={4}", _curWeightCfg.ComPort, _curWeightCfg.Baudrate, _curWeightCfg.ByteSize, _curWeightCfg.Parity, _curWeightCfg.StopSize)); _spCom = new SerialPort(_curWeightCfg.ComPort, int.Parse(_curWeightCfg.Baudrate)) { DataBits = _curWeightCfg.ByteSize, ReadBufferSize = 100 }; //奇偶校验 if (_curWeightCfg.Parity == ParityType.Even) { _spCom.Parity = Parity.Odd; } else if (_curWeightCfg.Parity == ParityType.Odd) { _spCom.Parity = Parity.Even; } else { _spCom.Parity = Parity.None; } //停止位 if (_curWeightCfg.StopSize == StopBitsType.One) { _spCom.StopBits = StopBits.One; } else if (_curWeightCfg.StopSize == StopBitsType.OnePointFive) { _spCom.StopBits = StopBits.OnePointFive; } else if (_curWeightCfg.StopSize == StopBitsType.Two) { _spCom.StopBits = StopBits.Two; } else { _spCom.StopBits = StopBits.None; } _spCom.DataReceived += new SerialDataReceivedEventHandler(_spCom_DataReceived); try { WeightDeviceLogger.Debug("表头打开串口。IsOpen=" + _spCom.IsOpen); _spCom.Open(); _closeComPort = false; ThreadStart ts1 = GetWeight;// 开启一个线程,发送读取数据命令,之后读取数据,解析数据,再通过委托事件传递给程序 _threadWeight1 = new Thread(ts1) { IsBackground = true,//表示后台线程 }; _threadWeight1.Start(); WeightDeviceLogger.Debug("启动表头获取数据线程成功。"); rtn = true; } catch (Exception ex) { WeightDeviceLogger.Error("打开表头失败。", ex); ShowErrorMsg(ErrorType.Error, "打开串口失败."); } } else { WeightDeviceLogger.Error("表头配置信息不存在。"); ShowErrorMsg(ErrorType.Error, "配置信息不存在."); } return rtn; }
///         ///     提取重量数据        ///         private void GetWeight()        {            while (true)            {                if (_spCom.IsOpen)                {                    if (isclearzero)                    {                        continue;                    }                    try                    {                        Thread.Sleep(100);                        ComSend(s1);//发送获取数据命令  s1是仪表厂家提供的读数命令16进制字符"01 03 00 01 00 04 15 C9"                        var readDataLen = _spCom.BytesToRead;//获取接受缓冲区的字节数                        var buf = new byte[readDataLen];//创建一个和接收区字节数一样的字节数组用来接收数据                        _isDataReceiving = true;                        Thread.Sleep(100);//发送读数命令之后要等一会再读取数据                        var length = _spCom.Read(buf, 0, readDataLen);//从缓冲区读取readDataLen长度的数据写入buf字节数组                        _isDataReceiving = false;                        if (length <= 0) continue;                        var aaa = System.Text.Encoding.Default.GetString(buf);//将字节数组转换成字符串                        var weightTemp = aaa.Substring(3, 7);//从字符串中截取使用的那几位数据                        if (!_canRaiseWeightDataEvent) continue;//判断程序是否暂停取数                        OnGetWeightData(weightTemp, "");//将数据发送给程序使用                    }                    catch(Exception e)                    {                        WeightDeviceLogger.Debug("读取数据线程出现错误"+e.Message);                    }                }            }                    }
private void ComSend(string obj)//发送数据 独立线程方法 发送数据时UI可以响应        {            if (Sending)            {                return;            }            //lock (this)//由于send()中的if (Sending == true) return,所以这里不会产生阻塞,如果没有那句,多次启动该线程,会在此处排队            {                Sending = true;//正在发生状态字                byte[] sendBuffer = null;//发送数据缓冲区                string sendData = obj;//复制发送数据,以免发送过程中数据被手动改变                if (true)//16进制发送                {                    try //尝试将发送的数据转为16进制Hex                    {                        sendData = sendData.Replace(" ", "");//去除16进制数据中所有空格                        sendData = sendData.Replace("\r", "");//去除16进制数据中所有换行                        sendData = sendData.Replace("\n", "");//去除16进制数据中所有换行                        if (sendData.Length == 1)//数据长度为1的时候,在数据前补0                        {                            sendData = "0" + sendData;                        }                        else if (sendData.Length % 2 != 0)//数据长度为奇数位时,去除最后一位数据                        {                            sendData = sendData.Remove(sendData.Length - 1, 1);                        }                        List
sendData16 = new List
();//将发送的数据,2个合为1个,然后放在该缓存里 如:123456→12,34,56 for (int i = 0; i < sendData.Length; i += 2) { sendData16.Add(sendData.Substring(i, 2)); } sendBuffer = new byte[sendData16.Count];//sendBuffer的长度设置为:发送的数据2合1后的字节数 for (int i = 0; i < sendData16.Count; i++) { sendBuffer[i] = (byte)(Convert.ToInt32(sendData16[i], 16));//发送数据改为16进制 } } catch //无法转为16进制时,出现异常 { WeightDeviceLogger.Debug("无法转为16进制时,出现异常"); Sending = false;//关闭正在发送状态 //_spCom.Abort();//终止本线程 return;//输入的16进制数据错误,无法发送,提示后返回 } } else //ASCII码文本发送 { sendBuffer = System.Text.Encoding.Default.GetBytes(sendData);//转码 } try//尝试发送数据 {
//如果发送字节数大于1000,则每1000字节发送一次 //int sendTimes = (sendBuffer.Length / 1000);//发送次数 //for (int i = 0; i < sendTimes; i++)//每次发生1000Bytes //{ // //_spCom.Write(sendBuffer, sendTimes * 1000, sendBuffer.Length % 1000); // _spCom.Write(sendBuffer, 0, sendBuffer.Length); //发送sendBuffer中从第i * 1000字节开始的1000Bytes //} //if (sendBuffer.Length % 1000 != 0)//发送字节小于1000Bytes或上面发送剩余的数据 //{ // //_spCom.Write(sendBuffer, sendTimes * 1000, sendBuffer.Length % 1000); // _spCom.Write(sendBuffer, 0, sendBuffer.Length); //} _spCom.Write(sendBuffer, 0, sendBuffer.Length); } catch(Exception ex)//如果无法发送,产生异常 { WeightDeviceLogger.Debug("指令发送错误"+ex.Message); } //sendScrol.ScrollToBottom();//发送数据区滚动到底部 Sending = false;//关闭正在发送状态 } }

 

转载于:https://www.cnblogs.com/big-lll/p/9235167.html

你可能感兴趣的文章
middle
查看>>
[Bzoj1009][HNOI2008]GT考试(动态规划)
查看>>
Blob(二进制)、byte[]、long、date之间的类型转换
查看>>
OO第一次总结博客
查看>>
day7
查看>>
iphone移动端踩坑
查看>>
vs无法加载项目
查看>>
Beanutils基本用法
查看>>
玉伯的一道课后题题解(关于 IEEE 754 双精度浮点型精度损失)
查看>>
《BI那点儿事》数据流转换——百分比抽样、行抽样
查看>>
哈希(1) hash的基本知识回顾
查看>>
Leetcode 6——ZigZag Conversion
查看>>
dockerfile_nginx+PHP+mongo数据库_完美搭建
查看>>
Http协议的学习
查看>>
【转】轻松记住大端小端的含义(附对大端和小端的解释)
查看>>
设计模式那点事读书笔记(3)----建造者模式
查看>>
ActiveMQ学习笔记(1)----初识ActiveMQ
查看>>
Java与算法之(2) - 快速排序
查看>>
Windows之IOCP
查看>>
机器学习降维之主成分分析
查看>>