zoukankan      html  css  js  c++  java
  • 串口通信

    SerialPort类

    SerialPort sp = new SerialPort("COM1"); 或者 SerialPort sp = new SerialPort();sp.PortName = "COM1";

    这两种写法是等效的;获得串口“COM1”的操作权,就是创建一个SerialPort对象,然后对象的属性PortName初始化为指定的串口名“COM1”,即可用该对象操作串口“COM1”,如:设置串口的通信参数,打开串口,发送数据,接收数据,关闭串口等;

    SerialPort类的重要属性:

    (1)PortName   

        赋予哪个串口名字,就是操作哪个串口;

    (2)DataBits   

          数据位的位数,有7,8,9三种情况,计算机编程语言认为8bit为一个字节,所以一般我们用8bit做为一帧数据帧的数据部分,这样数据帧到达接收方,接收方解析一个数据帧提取出数据位即是一个字节;

    (3)Parity       

         奇偶校验的方式,Parity.Even 奇校验;Parity.Odd 偶校验;Parity.None 不校验;不校验数据帧,能增加传输数据的效率,但是通信的可靠性降低;

    (4)StopBits     

        停止位的位数,StopBits.One    StopBits.OnePointFive    Two    指的是停止位持续几个电平;

    (5)BaudRate   

        波特率,串口通信的速率,值越大串口传输数据越快;如果是异步串口通信的话,二者的波特率应该尽可能无限接近,允许有细微误差;同步串口通信的话,双方一般使用同一个时钟,保证通信双方的波特率严格一致;

    检查机器上有无串口,串口的数量,具体串口名字

    string[] GetPortName()
    //返回的数组的Length ==0,表示无串口
    //Length > 0时候,表示有串口,Length的大小就是串口的数量
    //字符串数组的每一个元素就是串口的名字

    打开串口和关闭串口

    sp.IsOpen
    //指示串口是否处于打开状态,true打开,false未打开;打开已经打开过的串口会抛出异常;
    sp.Open()
    //打开串口
    sp.Close()
    //关闭串口

     向串口写数据

    public void Write(string)   //发送字符串
    //假设sp的Encoding属性是ASCII,写入字符串“abc”,那么实际写入发送缓存3个字节;
    //如果Encoding属性是Unicode,那么实际写入发送缓存6个字节;
    
    public void Write(byte[],int32,int32) //发送字节数组
    //第一个参数是函数外已经创建好的字节数组的引用,第二个参数是从字节数组的第几个字节开始写,一般为0,第三个参数表示本次要写入几个字节;
    
    public void Write(char[],int32,int32)  //发送字符数组
    //用法参考上述两个重载;特别说明,Encoding属性同样影响写入发送缓存的字节数量,不同的编码方式,虽然发送的是同一个字符数组,但是实际上写入发送缓存的字节数量不同!
    
    public void WriteLine(string)  //发送一行字符串
    //发送完string,紧接着向发送缓存写入一个NewLine字符串;

    从串口读数据

    public int Read (byte[] buffer, int offset, int count);
    //返回读到的字节数量
    public int Read (char[] buffer, int offset, int count);
    //返回读到的字节数量
    public int ReadByte();
    //从SerialPort输入缓冲区同步读取一个字节
    //如果读到末尾,返回-1
    public int ReadChar()
    //从SerialPort输入缓冲区同步读取一个字符

     读取数据可比发送数据复杂多了!

    接收方接收到的数据都在接收缓存中,ReadBufferSize是设定的缓存的大小,默认是4096;BytesToRead表示缓存中暂存到的已经收到的字节数量;

    当串口检查到有字节到达时,会触发DataReceived事件,ReceivedBytesThreshold属性能设置缓存中接收到多少字节后才触发该事件,默认是1。

    值得注意的是,该事件在辅助线程中触发,所以并不能保证每个字节到达都能触发一次该事件。所以假设:

    我收到10个字节,却只触发了2次;如果这两次读不干净缓存中的所有数据,那么剩下的数据在你下一次read()之前就一直留在缓存中而无法利用。

    解决方案:

    1,开辟一个线程,该线程实时检查BytesToRead,不为0就读取;

    2,制定通信协议,在触发事件中,一直检查到结束字节,再停止

        private static void DataReceivedHandler(
                            object sender,
                            SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            string indata = sp.ReadExisting();
            Console.WriteLine("Data Received:");
            Console.Write(indata);
        }
  • 相关阅读:
    DZY Loves Sequences
    Boredom easy dp
    floyd算法 poj1125
    poj3259 Bellman_Ford算法
    poj1860 Bellman_Ford算法
    Java 获取资源文件路径
    CLion 2020.1.2 激活
    Kotlin学习笔记
    Kotlin Hello World
    WebStorm 2020.1.2 激活
  • 原文地址:https://www.cnblogs.com/maoshuyi/p/9938349.html
Copyright © 2011-2022 走看看