参考地址:https://blog.csdn.net/memgxingfeixiang/article/details/52513970

     https://blog.csdn.net/kevin_iot/article/details/53926599

一、需求概述

     应用场景:winform中能接收到串口发送的数据。

所需软件: Configure Virtual Serial Port Driver(虚拟串口模拟软件)、串口调试助手。

二、效果展示(很简陋,捂脸中......)

  

说明:cmbPort是电脑上所有串口的列表,txtReciveData是每次该串口接收的数据,btnOpenOrClose按钮是控制打开/关闭串口。

三、具体实现:

(1)先在Load事件里将comPort控件绑定电脑串口列表,代码如下:

             #region 初始化电脑上的串口列表
foreach (string sPort in SerialPort.GetPortNames())
{
cmbPort.Items.Add(sPort);
} //串口设置默认选项
if (cmbPort.Items.Count>)
{
cmbPort.SelectedIndex = ;
}
#endregion

(2)编写btnOpenOrClose点击事件

         /// <summary>
/// 打开/关闭串口
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpenOrClose_Click(object sender, EventArgs e)
{
try
{
if (btnOpenOrClose.Text == "打开串口")
{
btnOpenOrClose.Text = "关闭串口";
//设置串口的基本属性
serialPort.PortName = cmbPort.SelectedItem.ToString();
serialPort.BaudRate = ;
serialPort.Parity = Parity.None;
serialPort.DataBits = ;
serialPort.StopBits = StopBits.One;
serialPort.Open();
}
else
{
btnOpenOrClose.Text = "打开串口";
serialPort.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}

(3)编写接收串口数据方法

         void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
Byte[] InputBuf = new Byte[];
serialPort.Read(InputBuf, , serialPort.BytesToRead); ASCIIEncoding encoding = new ASCIIEncoding();
data = encoding.GetString(InputBuf);
new Thread(SetReceiveData).Start();
//直接调用会报错-------从不是创建控件”txtContent”的线程访问它
//SetReceiveData();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}

接收数据成功,调用下面的方法,将发送的数据显示到文本框中。

         /// <summary>
/// (将接收的数据显示到文本框中)不懂这一块的实现逻辑,需要加深理解线程的相关概念
/// </summary>
public void SetReceiveData()
{
lock (this) Invoke(new MethodInvoker(delegate () { this.txtReciveData.Text = data; })); }

在load事件中将订阅该事件

            //为串口加上数据接收事件
serialPort.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);

四:模拟串口发送数据

(1)打开vspd软件,虚拟出两个COM1和COM2两个串口

(2)打开串口调试助手,一个是COM1,另外一个是COM2,将两个串口的波特率设置为一样。

测试一下,两个串口是否能正常通讯。

(3)关掉其中的一个串口调试助手,留下COM2的串口调试助手,我们在程序中用COM1口接收数据。(winform中要先点击“打开串口”按钮)

 五、完整代码

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading; namespace ComDataTest
{
public partial class ComData : Form
{
private SerialPort serialPort=new SerialPort();
string data = string.Empty;
public ComData()
{
InitializeComponent();
} private void ComData_Load(object sender, EventArgs e)
{
#region 初始化电脑上的串口列表
foreach (string sPort in SerialPort.GetPortNames())
{
cmbPort.Items.Add(sPort);
} //串口设置默认选项
if (cmbPort.Items.Count>)
{
cmbPort.SelectedIndex = ;
}
#endregion //为串口加上数据接收事件
serialPort.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);
} /// <summary>
/// 打开/关闭串口
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpenOrClose_Click(object sender, EventArgs e)
{
try
{
if (btnOpenOrClose.Text == "打开串口")
{
btnOpenOrClose.Text = "关闭串口";
//设置串口的基本属性
serialPort.PortName = cmbPort.SelectedItem.ToString();
serialPort.BaudRate = ;
serialPort.Parity = Parity.None;
serialPort.DataBits = ;
serialPort.StopBits = StopBits.One;
serialPort.Open();
}
else
{
btnOpenOrClose.Text = "打开串口";
serialPort.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
} /// <summary>
/// (将接收的数据显示到文本框中)不懂这一块的实现逻辑,需要加深理解线程的相关概念
/// </summary>
public void SetReceiveData()
{
lock (this) Invoke(new MethodInvoker(delegate () { this.txtReciveData.Text = data; })); } void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
Byte[] InputBuf = new Byte[];
serialPort.Read(InputBuf, , serialPort.BytesToRead); ASCIIEncoding encoding = new ASCIIEncoding();
data = encoding.GetString(InputBuf);
new Thread(SetReceiveData).Start();
//直接调用会报错-------从不是创建控件”txtContent”的线程访问它
//SetReceiveData();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
}

六、写在后面的话:

初次接触串口编程,作为码农多年,确实有些汗颜。从最初下载vspd和串口调试软件,根本不知如何用,到慢慢的了解一些,会简单的一些操作,着实也费了一点时间。目前对于串口编程,还是有一些云里雾里,似乎缺少一根主线把他们串起来一般,还是需要再进行摸索和探究,继续加油~

Winform串口编程---接收数据demo(VSPD虚拟串口)的更多相关文章

  1. Qt串口通信接收数据不完整的解决方法

    在使用串口接收数据时,当数据量大的时候会出现数据接收不完整的情况.因为串口数据获取函数readAll()由readyRead()信号触发,但readyRead()信号在串口读到起始标志时立即发送,并不 ...

  2. Qt串口通信接收数据不完整的解决方法(传输图片)

    在使用串口接收数据时,当数据量大的时候会出现数据接收不完整的情况.因为串口数据获取函数readAll()由readyRead()信号触发,但readyRead()信号在串口读到起始标志时立即发送,并不 ...

  3. c# 串口发送接收数据

    /********************** 串口数据接收事件 *****************************/ private void SerialPort_DataReceived ...

  4. Linux/windows com串口 java 接收数据 并解析 web程序

    1.首先应公司要求再 com 口本来使用 .net 由于 .net 适用 linux 太麻烦 改为java 准备工作 准备 RXTXconmm.jar(版本很重要) 因为版本问题我搞了一天. 主要讲述 ...

  5. <QT障碍之路>qt中使用串口类接收数据不完整

    问题:当用QT中的serial->readAll()的时候,不会把全部的数据一次性都读取出来,而是阶段性的.原因是因为当串口有信号时候,readyRead()信号就会被抛出,那么一帧完整的数据帧 ...

  6. STM32串口DMA接收数据错位——暴力解决方法

    背景:两片STM32通过串口通信,为了减小CPU负担,采用DMA进行通信,发送端为STM32F103C8T6,接收端为STM32F407VET6.在调试的过程中发现,一直出现数据错位的问题,接收端尝试 ...

  7. 【转】虚拟串口VSPM解决串口编程问题

    通过串口调试软件 UartAssist.exe 和虚拟串口软件 VSPM,可以解决串口编程时没用硬件调试的问题,通过VSPM虚拟出串口设备,让程序发送信息到 VSPM 设备后通过 UartAssist ...

  8. STM32之串口DMA接收不定长数据

    STM32之串口DMA接收不定长数据 引言 在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段数据是不定长的有如何高效接收呢? 同学A:数据来了就会进入串口 ...

  9. C#串口编程测试收发

    原文:http://www.cnblogs.com/vsdot/archive/2013/04/23/3263348.html   基本传递方法:RS232传输要有1位起始位,8位数据位.1位校验位( ...

随机推荐

  1. 《linux就该这么学》课堂笔记17 分离解析、DHCP、电子邮件系统

    1.动态主机配置协议(DHCP,Dynamic Host Configuration Protocol) 自动管理局域网内主机的IP地址.子网掩码.网关地址及DNS地址等参数,可以有效地提升IP地址的 ...

  2. Redis开启远程访问及密码

    一.开启远程访问 1.开放端口 firewall-cmd --zone=public --add-port=6379 firewall-cmd --zone=public --add-port=637 ...

  3. Ubuntu 出现access denied by server while mounting

    3516cv500板端nfst调试时如此配置 虚拟机: #vi /etc/exports  添加 /home/"待分享文件路径"   *(rw,sync,no_root_squas ...

  4. mdk编译器学习笔记(1)——序

    这两天,学习了keil-mdk编译器的特性,这基本上独立于c语言语法,平时基本上都在强调c语言的学习,但是编译器的学习我们也要注重,类似于gcc一样,不也有很多网上的资料,讲述gcc的特性和用法吗.作 ...

  5. java spring框架的定时任务

    由于测试的原因,最近有接触java spring  @Scheduled的定时任务,当时还以为配置起来表达式和crontab是完全一样的,没想到还有些许不一样. 在spring中,一个cron表达式至 ...

  6. Rotor里的异常处理

    我看到了一些关于Rotor(和CLR)中使用的异常处理机制的问题.下面是关于Rotor异常处理的另一个注意事项列表.目的是帮助Rotor开发人员调试和理解CLR中的异常. 异常生成和抛出 此步骤在很大 ...

  7. tornado表单和模板

    模板渲染,指定模板路径: app = tornado.web.Application( handlers=[(r'/my', Myrequest),('/myweb',MywebRequest)], ...

  8. 阿里云物联网平台: Android 连接阿里云物联网平台

    说明 这节是是为下一节做铺垫的 只要是按照我提供的学习路线一节一节的认认真真学过来的,这节就十分的简单 有了前两节的基础,这节呢咱让Android 连接阿里云物联网平台 使用这节的代码  https: ...

  9. localStorage二次封装-----设置过期时间

    export default{ set(key,data,time){ let obj={ data=data, ctime:(new Date()).getTime(),//时间戳,同Date.no ...

  10. 【LG3322】[SDOI2015]排序

    [LG3322][SDOI2015]排序 题面 洛谷 题解 交换顺序显然不影响答案,所以每种本质不同的方案就给答案贡献次数的阶乘. 从小往大的交换每次至多\(4\)中决策,复杂度\(O(4^n)\). ...