• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

C#串口读取

武飞扬头像
suixinger_lmh
帮助1

using System.IO.Ports;

此类位于System.IO.Ports命名空间下。用于控制串行端口文件资源,此类提供同步I/O和事件驱动的I/O、对管脚和中断状态的访问以及对串行驱动程序的访问。

SerialPort常用属性

  • BaudRate 获取或设置串行波特率
  • BreakState 获取或设置中断信号状态
  • BytesToRead 获取接收缓冲区中数据的字节数
  • BytesToWrite 获取发送缓冲区中数据的自己数
  • DataBits 获取或设置每个字节的标准数据位长度(默认为8)
  • DtrEnable 获取或设置一个值,该值指示Null字节在端口和接收缓冲区之间传输时是否被忽略
  • Encoding 获取或设置传输前后的文本转换的字节编码
  • IsOpen 获取一个值,该值指示SerialPort对象的打开或关闭状态
  • NewLine 获取或设置用于解释ReadLine和WriteLine方法调用结束的值
  • Parity 获取或设置奇偶校验检查协议
  • PortName 获取或设置通信端口,包括但不限于所有可用的COM端口
  • ReadBufferSize 获取或设置SerialPort输入缓冲区的大小
  • ReadTimeOut 获取或设置读取操作未完成时发生超时之前的毫秒数
  • ReceivedBytesThreshold 获取或设置DataReceived事件发生前内部输入缓冲区中的字节数
  • RtsEnable 获取或设置一个值,该值指示在串行通信中是否启用请求发送RTS信号
  • StopBits 获取或设置每个字节的标准停止位数
  • WriteBufferSize 获取或设置串行端口输出缓冲区的大小
  • WriteTimeout 获取或设置写入操作未完成时发生超时之前的毫秒数

SerialPort的主要方法

  • Close 关闭端口连接,将IsOpen属性设置成为false,并释放内部Stream对象
  • Dispose 释放SerialPort对象使用的非托管资源
  • GetPortNames 获取当前计算机的串行端口名称数组
  • Open 打开一个新的串行端口连接
  • Read 从SerialPort输入缓冲区中读取
  • ReadByte 从SerialPort输入缓冲区中同步读取一个字节
  • ReadChar 从SerialPort输入缓冲区中同步读取一个字符
  • ReadExisting 在编码的基础上,读取SerialPort对象的流和输入缓冲区中所有立即可用的字节
  • ReadLine 一直读取到输入缓冲区中的NewLine值
  • ReadTo 一直读取到输入缓冲区中指定value的字符串
  • Write 将数据写入到串行端口输出缓冲区
  • WriteLine 将指定的字符串和NewLine值写入到输出缓冲区
  • DataReceived 表示将处理SerialPort对象的数据接收事件的方法
  • ErrorReceived 表示处理Serialport对象的错误事件的方法

串口使用

串口使用需要一些相关设置:

.PortName 串口名称,COM1, COM2等。
.BaudRate 波特率,也就是串口通讯的速度,进行串口通讯的双方其波特率需要相同,如果用PC连接其他非PC系统,一般地,波特率由非PC系统决定。
.Parity 奇偶校验。可以选取枚举Parity中的值
.DataBits 数据位
.StopBits 停止位,可以选取枚举StopBits中的值
.Handshake 握手方式,也就是数据流控制方式,可以选取枚举Handshake中的值

打开和关闭串口

在创建一个SerialPort 对象,设置串口属性后,可以通过 Open()方法打开串口。数据读写完成后,可以通过Close()方法关闭串口。
根据经验,对于有些系统,在打开串口后,还需要将RtsEnable设置为True,这样才能读写数据,否则不能正常读写数据。

DataReceived

SerialPort 提供了DataReceived事件。当有数据进入时,该事件被触发。该事件的触发由操作系统决定,当有数据到达时,该事件在辅助线程中被触发。辅助线程的优先级比较低,因此并不能确保每个字节的数据到达时,该事件都被触发。

使用过程中问题:

DataReceived 和 自己写线程监听

项目中遇到的是不调用DataReceived而是自己写线程监听事件;

一个简单的串口解析模板:

using Assets.Scripts.Configuration;
using Assets.Scripts.EntityModel;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO.Ports;
using System.Threading;
using UnityEngine;

/// <summary>
/// 转盘监听,
/// 传输结果,监听线程,
/// </summary>
public static class ConnectTurntable
{
    //监听串口线程
    static Thread dataReceiveThread_1, dataReceiveThread_2;



   static SerialPort serialPort = new SerialPort();

    public static void StartSerialPortListen()
    {
        //设定
        serialPort.PortName = "COM1";
        serialPort.BaudRate = 1000;
        serialPort.ReadTimeout = 500;
        serialPort.WriteTimeout = 500;
        serialPort.DataReceived  = null;

        //不使用DataReceived,自己写线程监听
        //开启线程监听串口
        try
        {
        	//串口数据解析方法(忽视第二个参数,根据自己的解析方式自己写,这里放一个公司的串口解析)
            dataReceiveThread_1 = new Thread(() => DataReceiveFunction(serialPort, xuanzhuan));
            if (dataReceiveThread_1 != null && dataReceiveThread_1.IsAlive)
            {
                dataReceiveThread_1.Abort();
            }
            dataReceiveThread_1.Start();
        }
        catch (Exception ex)
        {
            Debug.LogError("监听事件打开失败!ex="   ex.Message);
        }
    }
    
    

    

    #region 串口数据解析
    static void DataReceiveFunction(SerialPort serialPort, SensorResult sensorResult)
    {
        try
        {
            /** **/
            byte[] RxBuffer = new byte[1000];
            UInt16 usRxLength = 0;

            int bytes = 0;
            int flag0 = 0xFF;
            int flag1 = 0xAA;
            int index = 0;//用于记录此时的数据次序
            while (true)
            {
                if (serialPort != null && serialPort.IsOpen)
                {
                    try
                    {
                        byte[] byteTemp = new byte[1000];

                        try
                        {
                            UInt16 usLength = 0;
                            try
                            {
                                usLength = (UInt16)serialPort.Read(RxBuffer, usRxLength, 700);
                            }
                            catch (Exception err)
                            {
                                //MessageBox.Show(err.Message);
                                //return;
                                Debug.LogError("spSerialPort.Read!! ex="   err.Message);
                            }
                            usRxLength  = usLength;
                            while (usRxLength >= 11)
                            {
                                //UpdateData Update = new UpdateData(DecodeData);
                                RxBuffer.CopyTo(byteTemp, 0);
                                if (!((byteTemp[0] == 0x55) & ((byteTemp[1] & 0x50) == 0x50)))
                                {
                                    for (int i = 1; i < usRxLength; i  ) RxBuffer[i - 1] = RxBuffer[i];
                                    usRxLength--;
                                    continue;
                                }
                                if (((byteTemp[0]   byteTemp[1]   byteTemp[2]   byteTemp[3]   byteTemp[4]   byteTemp[5]   byteTemp[6]   byteTemp[7]   byteTemp[8]   byteTemp[9]) & 0xff) == byteTemp[10])
                                {
                                    Thread t = new Thread(() => XuanzhuanReceiveData(byteTemp, sensorResult));
                                    t.Start();
                                }
                                for (int i = 11; i < usRxLength; i  ) RxBuffer[i - 11] = RxBuffer[i];
                                usRxLength -= 11;
                            }

                            Thread.Sleep(10);
                        }
                        finally
                        {

                        }
                    }
                    catch (Exception ex)
                    {
                        // Debug.Log(ex.Message);
                    }
                }
                Thread.Sleep(100);
            }
        }
        catch (Exception ex)
        {

            //log.Error("DataReceiveFunction!! ex="   ex.Message);
        }
    }




   

    private static void XuanzhuanReceiveData(byte[] RxBuffer, SensorResult sensorResult)
    {
        try
        {
            DecodeData(ref sensorResult, RxBuffer);
        }
        catch (Exception ex)
        {
            Debug.LogError(" ComReceiveData ex={0}"   ex.Message);
        }
    }
    /// <summary>
    /// 输入数据解析出来到sr里
    /// </summary>
    /// <param name="sr"></param>
    /// <param name="byteTemp"></param>
    private static void DecodeData(ref SensorResult sr, byte[] byteTemp)
    {
        DateTime TimeStart = DateTime.Now;
        short sRightPack = 0;
        short[] ChipTime = new short[7];
        double Temperature;
        double Pressure, Altitude, GroundVelocity, GPSYaw, GPSHeight;
        long Longitude, Latitude;
        double[] LastTime = new double[10];



        float[] Data = new float[4];
        double TimeElapse = (DateTime.Now - TimeStart).TotalMilliseconds / 1000;

        Data[0] = BitConverter.ToInt16(byteTemp, 2);
        Data[1] = BitConverter.ToInt16(byteTemp, 4);
        Data[2] = BitConverter.ToInt16(byteTemp, 6);
        Data[3] = BitConverter.ToInt16(byteTemp, 8);
        sRightPack  ;
        switch (byteTemp[1])
        {
            case 0x52:
                //Data[3] = Data[3] / 32768 * double.Parse(textBox9.Text)   double.Parse(textBox8.Text);
                Temperature = Data[3] / 100.0;
                Data[0] = Data[0] / 32768.0f * 2000;
                Data[1] = Data[1] / 32768.0f * 2000;
                Data[2] = Data[2] / 32768.0f * 2000;
                sr.WX = Data[0];
                sr.WY = Data[1];
                sr.WZ = Data[2];
                sr.WO = Data[3];
                if ((TimeElapse - LastTime[2]) < 0.1) return;
                LastTime[2] = TimeElapse;
                break;
       
            case 0x55:
                sr.D0 = Data[0];
                sr.D1 = Data[1];
                sr.D2 = Data[2];
                sr.D3 = Data[3];
                break;
      
            default:
                break;
        }
    }



   

    #endregion




}

学新通

问题:

if (((use11byte[0]   use11byte[1]   use11byte[2]   use11byte[3]   use11byte[4]   use11byte[5]   use11byte[6]   use11byte[7]   use11byte[8]   use11byte[9]) & 0xff) == use11byte[10])

校验:前几个的和,& 0xff, 取最后8位 和校验位校验

BitConverter.ToInt16(byteTemp, 2);使用,
取byte[] 中 第2个byte和他的下一个(即第三个),然后组合成 【第三个 第二个】16位数。注意颠倒

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhghfahk
系列文章
更多 icon
同类精品
更多 icon
继续加载