c#如何实现串口通信读取数据

c#如何实现串口通信读取数据,第1张

使用System.IO.Port.SerialPort类实现串口通信

System.IO.Port.SerialPort类介绍

System.IO.Port.SerialPort是.NET Framework提供的 *** 作串行端口的类,里面提供宽槐行了一些方法、属性和和事件供开发者调用 *** 作串口。

调用流程

1. 直接调用SerialPort的静态方法GetPortNames()获取当前计算机的串行端口名称数组

2.根据串口名称,初始化SerialPort对象,设置参数,调用Open()方法打开串口

3.调用Write()方法发明伏送数据

4.注册接收数据的监听,获取数据(或者另起线程循环读取接收数据,本文使用注册监听方式接收数据)

具体代码实现

using System 

using System.IO.Ports 

using System.Text

namespace PortControlDemo  

{

public class PortControlHelper

{

#region 字段/属性/委托

/// <summary>

/// 串行端口对象

/// </summary>

private SerialPort sp

/// <summary>

/// 串口接收数据委托

/// </summary>

public delegate void ComReceiveDataHandler(string data)

public ComReceiveDataHandler OnComReceiveDataHandler = null

/// <summary>

/// 端口名称数组

/// </summary>

public string[] PortNameArr { getset}

/// <summary>

/// 串口通信开启状态慎哗

/// </summary>

public bool PortState { getset} = false

/// <summary>

/// 编码类型

/// </summary>

public Encoding EncodingType { getset} = Encoding.ASCII

#endregion

#region 方法

public PortControlHelper()

{

PortNameArr = SerialPort.GetPortNames()

sp = new SerialPort()

sp.DataReceived += new SerialDataReceivedEventHandler(DataReceived)

}

/// <summary>

/// 打开端口

/// </summary>

/// <param name="portName">端口名称</param>

/// <param name="boudRate">波特率</param>

/// <param name="dataBit">数据位</param>

/// <param name="stopBit">停止位</param>

/// <param name="timeout">超时时间</param>

public void OpenPort(string portName , int boudRate = 115200, int dataBit = 8, int stopBit = 1, int timeout = 5000)

{

try

{

sp.PortName = portName

sp.BaudRate = boudRate

sp.DataBits = dataBit

sp.StopBits = (StopBits)stopBit

sp.ReadTimeout = timeout

sp.Open()

PortState = true

}

catch (Exception e)

{

throw e

}

}

/// <summary>

/// 关闭端口

/// </summary>

public void ClosePort()

{

try

{

sp.Close()

PortState = false

}

catch (Exception e)

{

throw e

}

}

/// <summary>

/// 发送数据

/// </summary>

/// <param name="sendData"></param>

public void SendData(string sendData)

{

try

{

sp.Encoding = EncodingType

sp.Write(sendData)

}

catch (Exception e)

{

throw e

}

}

/// <summary>

/// 接收数据回调用

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void DataReceived(object sender, SerialDataReceivedEventArgs e)

{

byte[] buffer = new byte[sp.BytesToRead]

sp.Read(buffer, 0, buffer.Length)

string str = EncodingType.GetString(buffer)

if (OnComReceiveDataHandler != null)

{

OnComReceiveDataHandler(str)

}

}

#endregion

}  

}

View Code

三、编写Winform串口通信工具界面

界面预览

直接上参考程序:

Dim av As Variant

Dim datacount As Long

Private Sub cmdClear_Click()

    txtData.Text = ""

End Sub

Private Sub cmdStop_Click()

   

    '关闭端口

    If MSComm.PortOpen = True Then

        MSComm.InBufferCount = 0    '清空缓冲区

        MSComm.PortOpen = False

    End If

   

    cmdReceive.Enabled = True

    lblStatus.Caption = "停止接收,空闲"

   

End Sub

Private Sub cmdReceive_Click()

   

    '串口设置

    With MSComm

        .CommPort = 1

        .Settings = "9600,N,8,1"

        .RThreshold = 1         '接收1字节触发oncomm事件

        .InputMode = comInputModeBinary

        .InputLen = 1           '输入长度为1

        .InBufferCount = 0      '清除接收缓冲区

    End With

    '打开端口

    If MSComm.PortOpen = False Then

       族仿 MSComm.PortOpen = True

        If Err Then

            MsgBox (Err.Description)

            Exit Sub

        End If

    End If

        

    lblStatus.Caption = "打开端口,等待接收"

    datacount = 0

    cmdReceive.Enabled = False

End Sub

Private Sub cmdSave_Click()

    Dim outfn As String

    MsgBox ("接收了" + CStr(datacount) + "组数据")

    lblStatus.Caption = "接收完成,请选择输出文件"

   

    cmdReceive.Enabled = True

   

    '选择输出文件

    CommonDialog1.FileName = CStr(Date) + ".txt"

    CommonDialog1.Filter = "Text Files|*.txt"

    CommonDialog1.Flags = CommonDialog1.Flags Or cdlOFNOverwritePrompt

    CommonDialog1.CancelError = True

    On Error GoTo errhandler

        CommonDialog1.ShowSave

        outfn = CommonDialog1.FileName

        

        Open outfn For Output As #1

            Print #1, txtData.Text

        Close #1

   

    'txtData.SaveFile outfn

    lblStatus.Caption = "输出完成,空闲"

   

errhandler:

    Exit Sub

End Sub

Private Sub Form_Load()

    lblStatus.Caption = "空闲"

End Sub

Private Sub Form_Unload(Cancel As Integer)

    '关闭端口

    If MSComm.PortOpen = True Then

        MSComm.InBufferCount = 0    '清空缓冲区

        MSComm.PortOpen = False

    End If

   

End Sub

Private Sub MSComm_OnComm()

    Dim T1, T2 As Long

    Select Case MSComm.CommEvent

   

        Case comEvReceive       '收到Rthreshold个字节兆手纤产生的接收事件

           

            MSComm.RThreshold = 0    '关闭OnComm事件接收

            lblStatus.Caption = "接收"

            av = MSComm.Input       '读取一个接收字节

            dataframe(1) = av(0)    '转换为字节

           

            If dataframe(1) = &HA Then   '接收到T1

               

                Do

                    DoEvents

                Loop Until MSComm.InBufferCount >= 2  '循环等待接收缓冲区>=2个字节

               

                av = MSComm.Input

                dataframe(2) = av(0)

                av = MSComm.Input

                dataframe(3) = av(0)       '接收T1

                T1 = dataframe(2) + CLng(dataframe(3)) * 256    '计算T1

            End If

           

  薯销          Do

                DoEvents

            Loop Until MSComm.InBufferCount >= 1  '循环等待接收缓冲区>=1个字节

            av = MSComm.Input       '读取一个接收字节

            dataframe(4) = av(0)    '转换为字节

           

            '接收到T2

            If dataframe(4) = &HA0 Then

                'MSComm.RThreshold = 0     '关闭OnComm事件接收

               

                '循环等待接收缓冲区>=2个字节

                Do

                    DoEvents

                Loop Until MSComm.InBufferCount >= 2

               

                av = MSComm.Input

                dataframe(5) = av(0)

                av = MSComm.Input

                dataframe(6) = av(0)       '接收T2

                T2 = dataframe(5) + CLng(dataframe(6)) * 256    '计算T2

               

                '显示T1 T2 enter

                txtData.Text = txtData.Text + CStr(T1) + " " + CStr(T2) + Chr(&HD) + Chr(&HA)

               

                datacount = datacount + 1   '数据组数+1

            End If

           

            MSComm.RThreshold = 1       '打开OnComm事件接收

           

        Case Else

        

    End Select

   

End Sub

RS232串行通信的波特率设为9600,8位数据位,一位停止位,无校验位。

2. 每组数据包含T1(16位)和T2(16位),将每个数据分成2个8位的数据,先是低8位,然后是高8位。数据为无符号整型。

   先发T1,然后发T2,然后是下一组T1、T2。

   T1以头数据0x0A(16进制,10进制位10)为头字节,然后是T1的低8位,T1的高8位。

   T2以头数据0xA0(16进制,10进制位160)为头字节,然后是T2的低8位,T2的高8位。

   发送时序举例:0x0A, t1低8位,t1高8位,0xA0, t2低8位,t2高8位……

   将收到的数据T1、T2的高低8位合并,转换成10进制数,以每行T1 T2的形式存储到txt文本文件中

如果需要 做其他‘文件格式的处理, 数据已经拿到了,想怎么弄就变通下吧。

1、首先设置LED灯引脚,定义变量存储串口数誉胡据,如图所示。

2、然后打开串行通信接口并设置通信波特率,将LED管脚模式初始化为输出模式,如图所示。

3、然后检查是否有数据,并且发出控制指令,如图所示。

4、然后读取串口数据氏神,如图所示。

5、然后测试传输值是否等于K,如图所示。

6、最后测试传输值是否等于G,如图所歼虚亏示。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8226998.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存