使用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 VariantDim 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,如图所歼虚亏示。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)