C#实现简单串口通讯实例
作者:未来无限 发布时间:2022-06-18 11:29:42
标签:C#,串口通讯
本文实例为大家分享了C#实现简单串口通讯的具体代码,供大家参考,具体内容如下
参数设置界面代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace ComDemo
{
public partial class ComSet : Form
{
public ComSet()
{
InitializeComponent();
}
private void ComSet_Load(object sender, EventArgs e)
{
//串口
string[] ports = SerialPort.GetPortNames();
foreach (string port in ports)
{
cmbPort.Items.Add(port);
}
cmbPort.SelectedIndex = 0;
//波特率
cmbBaudRate.Items.Add("110");
cmbBaudRate.Items.Add("300");
cmbBaudRate.Items.Add("1200");
cmbBaudRate.Items.Add("2400");
cmbBaudRate.Items.Add("4800");
cmbBaudRate.Items.Add("9600");
cmbBaudRate.Items.Add("19200");
cmbBaudRate.Items.Add("38400");
cmbBaudRate.Items.Add("57600");
cmbBaudRate.Items.Add("115200");
cmbBaudRate.Items.Add("230400");
cmbBaudRate.Items.Add("460800");
cmbBaudRate.Items.Add("921600");
cmbBaudRate.SelectedIndex = 5;
//数据位
cmbDataBits.Items.Add("5");
cmbDataBits.Items.Add("6");
cmbDataBits.Items.Add("7");
cmbDataBits.Items.Add("8");
cmbDataBits.SelectedIndex = 3;
//停止位
cmbStopBit.Items.Add("1");
cmbStopBit.SelectedIndex = 0;
//佼验位
cmbParity.Items.Add("无");
cmbParity.SelectedIndex = 0;
}
private void bntOK_Click(object sender, EventArgs e)
{
//以下4个参数都是从窗体MainForm传入的
MainForm.strProtName = cmbPort.Text;
MainForm.strBaudRate = cmbBaudRate.Text;
MainForm.strDataBits = cmbDataBits.Text;
MainForm.strStopBits = cmbStopBit.Text;
DialogResult = DialogResult.OK;
}
private void bntCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
}
}
}
主界面代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
using System.Threading;
namespace ComDemo
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private Thread getRecevice;
protected Boolean stop = false;
protected Boolean conState = false;
private StreamReader sRead;
string strRecieve;
bool bAccpet = false;
SerialPort sp = new SerialPort();//实例化串口通讯类
//以下定义4个公有变量,用于参数传递
public static string strProtName = "";
public static string strBaudRate = "";
public static string strDataBits = "";
public static string strStopBits = "";
private void MainForm_Load(object sender, EventArgs e)
{
groupBox1.Enabled = false;
groupBox2.Enabled = false;
this.toolStripStatusLabel1.Text = "端口号:端口未打开 | ";
this.toolStripStatusLabel2.Text = "波特率:端口未打开 | ";
this.toolStripStatusLabel3.Text = "数据位:端口未打开 | ";
this.toolStripStatusLabel4.Text = "停止位:端口未打开 | ";
this.toolStripStatusLabel5.Text = "";
}
//串口设计
private void btnSetSP_Click(object sender, EventArgs e)
{
timer1.Enabled = false;
sp.Close();
ComSet dlg = new ComSet();
if (dlg.ShowDialog() == DialogResult.OK)
{
sp.PortName = strProtName;//串口号
sp.BaudRate = int.Parse(strBaudRate);//波特率
sp.DataBits = int.Parse(strDataBits);//数据位
sp.StopBits = (StopBits)int.Parse(strStopBits);//停止位
sp.ReadTimeout = 500;//读取数据的超时时间,引发ReadExisting异常
}
}
//打开/关闭串口
private void bntSwitchSP_Click(object sender, EventArgs e)
{
if (bntSwitchSP.Text == "打开串口")
{
if (strProtName != "" && strBaudRate != "" && strDataBits != "" && strStopBits != "")
{
try
{
if (sp.IsOpen)
{
sp.Close();
sp.Open();//打开串口
}
else
{
sp.Open();//打开串口
}
bntSwitchSP.Text = "关闭串口";
groupBox1.Enabled = true;
groupBox2.Enabled = true;
this.toolStripStatusLabel1.Text = "端口号:" + sp.PortName + " | ";
this.toolStripStatusLabel2.Text = "波特率:" + sp.BaudRate + " | ";
this.toolStripStatusLabel3.Text = "数据位:" + sp.DataBits + " | ";
this.toolStripStatusLabel4.Text = "停止位:" + sp.StopBits + " | ";
this.toolStripStatusLabel5.Text = "";
}
catch (Exception ex)
{
MessageBox.Show("错误:" + ex.Message, "C#串口通信");
}
}
else
{
MessageBox.Show("请先设置串口!", "RS232串口通信");
}
}
else
{
timer1.Enabled = false;
timer2.Enabled = false;
bntSwitchSP.Text = "打开串口";
if (sp.IsOpen)
sp.Close();
groupBox1.Enabled = false;
groupBox2.Enabled = false;
this.toolStripStatusLabel1.Text = "端口号:端口未打开 | ";
this.toolStripStatusLabel2.Text = "波特率:端口未打开 | ";
this.toolStripStatusLabel3.Text = "数据位:端口未打开 | ";
this.toolStripStatusLabel4.Text = "停止位:端口未打开 | ";
this.toolStripStatusLabel5.Text = "";
}
}
//发送数据
private void bntSendData_Click(object sender, EventArgs e)
{
if (sp.IsOpen)
{
try
{
sp.Encoding = System.Text.Encoding.GetEncoding("GB2312");
sp.Write(txtSend.Text);//发送数据
}
catch (Exception ex)
{
MessageBox.Show("错误:" + ex.Message);
}
}
else
{
MessageBox.Show("请先打开串口!");
}
}
//选择文件
private void btnOpenFile_Click(object sender, EventArgs e)
{
OpenFileDialog open = new OpenFileDialog();
open.InitialDirectory = "c\\";
open.RestoreDirectory = true;
open.FilterIndex = 1;
open.Filter = "txt文件(*.txt)|*.txt";
if (open.ShowDialog() == DialogResult.OK)
{
try
{
if (open.OpenFile() != null)
{
txtFileName.Text = open.FileName;
}
}
catch (Exception err1)
{
MessageBox.Show("文件打开错误! " + err1.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
//发送文件内容
private void bntSendFile_Click(object sender, EventArgs e)
{
string fileName = txtFileName.Text.Trim();
if (fileName == "")
{
MessageBox.Show("请选择要发送的文件!", "Error");
return;
}
else
{
//sRead = new StreamReader(fileName);
sRead = new StreamReader(fileName,Encoding.Default);//解决中文乱码问题
}
timer1.Start();
}
//发送文件时钟
private void timer1_Tick(object sender, EventArgs e)
{
string str1;
str1 = sRead.ReadLine();
if (str1 == null)
{
timer1.Stop();
sRead.Close();
MessageBox.Show("文件发送成功!", "C#串口通讯");
this.toolStripStatusLabel5.Text = "";
return;
}
byte[] data = Encoding.Default.GetBytes(str1);
sp.Write(data, 0, data.Length);
this.toolStripStatusLabel5.Text = " 文件发送中...";
}
//接收数据
private void btnReceiveData_Click(object sender, EventArgs e)
{
if (btnReceiveData.Text == "接收数据")
{
sp.Encoding = Encoding.GetEncoding("GB2312");
if (sp.IsOpen)
{
//timer2.Enabled = true; //使用主线程进行
//使用委托以及多线程进行
bAccpet = true;
getRecevice = new Thread(new ThreadStart(testDelegate));
//getRecevice.IsBackground = true;
getRecevice.Start();
btnReceiveData.Text = "停止接收";
}
else
{
MessageBox.Show("请先打开串口");
}
}
else
{
//timer2.Enabled = false;
bAccpet = false;
try
{ //停止主监听线程
if (null != getRecevice)
{
if (getRecevice.IsAlive)
{
if (!getRecevice.Join(100))
{
//关闭线程
getRecevice.Abort();
}
}
getRecevice = null;
}
}
catch { }
btnReceiveData.Text = "接收数据";
}
}
private void testDelegate()
{
reaction r = new reaction(fun);
r();
}
//用于接收数据的定时时钟
private void timer2_Tick(object sender, EventArgs e)
{
string str = sp.ReadExisting();
string str2 = str.Replace("\r", "\r\n");
txtReceiveData.AppendText(str2);
txtReceiveData.ScrollToCaret();
}
//下面用到了接收信息的代理功能,此为设计的要点之一
delegate void DelegateAcceptData();
void fun()
{
while (bAccpet)
{
AcceptData();
}
}
delegate void reaction();
void AcceptData()
{
if (txtReceiveData.InvokeRequired)
{
try
{
DelegateAcceptData ddd = new DelegateAcceptData(AcceptData);
this.Invoke(ddd, new object[] { });
}
catch { }
}
else
{
try
{
strRecieve = sp.ReadExisting();
txtReceiveData.AppendText(strRecieve);
}
catch (Exception ex) { }
}
}
private void bntClear_Click(object sender, EventArgs e)
{
txtReceiveData.Text = "";
}
private void button3_Click(object sender, EventArgs e)
{
try
{
string path = Directory.GetCurrentDirectory() + @"\output.txt";
string content = this.txtReceiveData.Text;
FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter write = new StreamWriter(fs);
write.Write(content);
write.Flush();
write.Close();
fs.Close();
MessageBox.Show("接收信息导出在:" + path);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
效果图
来源:https://blog.csdn.net/qq_30725967/article/details/86620150


猜你喜欢
- 本文实例讲述了Java设计模式之工厂模式实现方法。分享给大家供大家参考,具体如下:工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体
- 目前市面上流行的爬虫以python居多,简单了解之后,觉得简单的一些页面的爬虫,主要就是去解析目标页面(html)。那么就在想,java有没
- 本文总结了我在学习hibernate的过程中,解决hibernate懒加载问题的四种方式。所谓懒加载(lazy)就是延时加载,延迟加载。什么
- 本文实例讲述了Android编程实现启动界面的方法。分享给大家供大家参考,具体如下:最近在弄一个程序启动界面程序,在这里贴下代码。解释一下:
- 前言直接使用项目或直接复制libs中的so库到项目中即可(当前只构建了armeabi),需要其他ABI可检下项目另外使用CMake构建即可。
- Map接口Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据key快速查找value;Map中的
- 创建一个用户类类型的集合,手动输入用户库主要是判定输入的用户名和密码是否与库中的匹配做好区别是用户名输入错误还是密码输入错误的提示。定义用户
- 这篇文章主要介绍了MyBatis Mapper接受参数的四种方式代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考
- 1、为什么使用Spring提供的JDBC的封装?因为Spring提供了完整的模板类以及基类可以简化开发,我们只需写少量的代码即可。2、实例讲
- 一.服务层package com.demo.websocket;import java.io.IOException;import java
- 对象重复是指对象里面的变量的值都相等,并不定是地址。list集合存储的类型是基础类型还比较好办,直接把list集合转换成set集合就会自动去
- 本文讲述了Android自定义横向滑动菜单的实现。分享给大家供大家参考,具体如下:前言 开发安卓过程中,经常会用到标题栏的样式,有
- Android Lint 原理及使用详解Android Lint 是 ADT 16中引入的新工具,用于扫描 Android 项目源中的潜在错
- 最近公司要求开发工具要用Idea,作为一个eclipse的老员工,记录一下Idea中遇到的坑刚开始用Idea从Git上导入一个项目时,遇到了
- 1. 项目背景最近参加了Compose挑战赛的终极挑战,使用Compose完成了一个天气app。之前几轮挑战也都有参与,每次都学到不少新东西
- 上篇文章中我们介绍了浅谈Spring的两种配置容器,接下来我们就了解下spring中的FactoryBean的相关内容,具体如下。从Sess
- 本文实例为大家分享了Android登录邮箱自动补全功能的实现方法,供大家参考,具体内容如下效果:实现原理:1、继承重写简单控件AutoCom
- 本文实例为大家分享了Java实现置换密码加密解密,供大家参考,具体内容如下思路置换密码只不过是简单的换位而已,这里写的是一个分组长度为7的置
- 本文实例讲述了C#使用NPOI导入Excel的方法。分享给大家供大家参考,具体如下:NPOI是由国人开发的一个进行excel操作的第三方库。
- 这个是由于快捷键冲突造成的:所以可以查应用比如:1)搜狗输入法中设置的语句2)QQ音乐的快捷键3)有道词典的快键键把上面找的快键键删除,那么