文章目录[隐藏]
最近在做与设备进行串口通信交互的项目,然后简单记录一下过程
使用的winform应用程序
方式1
1.声明串口对象 或者直接在工具箱拖拽串口控件
本篇文章不采用拖拽工具箱控件 直接声明对象
声明串口对象
SerialPort port = new SerialPort();//在选择了串口之后设置 串口、波特率、校验位等
也可以直接拖拽工具箱的串口控件SerialPort
2.引用串口命名控件 声明串口对象、声明委托
using System.IO.Ports;
SerialPort serialPort1 = new SerialPort();
public delegate void Displaydelegate(byte[] InputBuf);
public Displaydelegate disp_delegate;
public Form1()
{
InitializeComponent();
disp_delegate = new Displaydelegate(DispUI);
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
}
3.先获取电脑所有串口列表
获取到列表后绑定给conboBox,以便选择串口打开 在load事件绑定下拉框
String[] portnames = SerialPort.GetPortNames();
foreach (var item in portnames)
{
comboBox1.Items.Add(item);
}
4.实例化串口打开串口
选择串口后实例化串口
string aaa = comboBox1.SelectedItem.ToString();
serialPort11 = new SerialPort(aaa, 9600, Parity.None, 8, StopBits.One); //初始化串口设置 serialPort11 声明为全局变量
serialPort1.Open();
if (serialPort1.IsOpen)
{
MessageBox.Show("打开成功");
}
else
{
MessageBox.Show("打开失败");
}
5.写一个接收数据事件获取串口发送来的数据
//编写一个接收事件
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// writetxt("端口名称:" + serialPort1.PortName + "====" + "端口名称:" + "波特率:" + serialPort1.BaudRate + "串口状态:" + serialPort1.IsOpen + "错误信息:无");
//string receive = "";//数据接收
try
{
Thread.Sleep(100); //(毫秒)等待一定时间,确保数据的完整性 int len
int len = serialPort1.BytesToRead;
if (len != 0)
{
byte[] buff = new byte[len];
serialPort1.Read(buff, 0, len);
//receive = Encoding.Default.GetString(buff);//数据接收内容
//textBox1.Text = receive + "\r\n"; //不能直接给textbox1 不然会报错
this.Invoke(disp_delegate, buff);
}
}
catch (Exception asd)
{
//writetxt("端口名称:" + serialPort1.PortName + "====" + "端口名称:" + "波特率:" + serialPort1.BaudRate + "串口状态:" + serialPort1.IsOpen + "错误信息:" + asd.Message);
return;
}
}
public void DispUI(byte[] InputBuf)
{
//textBox1.Text = Convert.ToString(InputBuf);
string aaa = Encoding.Default.GetString(InputBuf);
textBox1.Text = aaa;
// writetxt("端口名称:" + serialPort1.PortName + "====" + "端口名称:" + "波特率:" + serialPort1.BaudRate + "串口状态:" + serialPort1.IsOpen + "错误信息:无 " + "数据:" + aaa);
}
6.模拟串口发送数据
模拟串口调试工具可参考我另一篇文章链接https://blog.csdn.net/qq_39569480/article/details/120776868
方式2
发送接收 完整代码示例
源码下载地址demo
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 ck3
{
public partial class Form1 : Form
{
private void CheckPort()//检查串口是否可用
{
ckCheckBox.Items.Clear();//清除控件中的当前值
bool havePort = false;
string[] a = SerialPort.GetPortNames();
if (a != null)
{
for (int i = 0; i < a.Length; i++)
{
bool use = false;
try
{
SerialPort t = new SerialPort(a[i]);
sp.Open();
sp.Close();
use = true;
}
catch
{
}
if (use)
{
ckCheckBox.Items.Add(a[i]);
havePort = true;
}
}
}
if (havePort)
{
ckCheckBox.SelectedIndex = 0;//??
}
else
{
MessageBox.Show("无可用串口...", "错误");
}
}
private void SetPort()//设置串口
{
try
{
sp.PortName = ckCheckBox.Text.Trim();//串口名给了串口类
sp.BaudRate = Convert.ToInt32(SendBox.Text.Trim());//Trim除去前后空格,讲文本转换为32位字符给予串口类
if (JywCheckBox.Text.Trim() == "奇校验")
{
sp.Parity = Parity.Odd;//将奇校验位给了sp的协议
}
else if (JywCheckBox.Text.Trim() == "偶校验")
{
sp.Parity = Parity.Even;
}
else
{
sp.Parity = Parity.None;
}
if (StopCheckBox.Text.Trim() == "1.5")
{
sp.StopBits = StopBits.OnePointFive;//设置停止位有几位
}
else if (StopCheckBox.Text.Trim() == "2")
{
sp.StopBits = StopBits.Two;
}
else
{
sp.StopBits = StopBits.One;
}
sp.DataBits = Convert.ToInt16(DataBox.Text.ToString().Trim());//数据位
sp.Encoding = Encoding.UTF8;//串口通信的编码格式
sp.Open();
}
catch { }
}
private string HexToASCII(string str)
{
try
{
string[] mystr1 = str.Trim().Split(' ');
byte[] t = new byte[mystr1.Length];
for (int i = 0; i < t.Length; i++)
{
t[i] = Convert.ToByte(mystr1[i], 16);
}
return Encoding.UTF8.GetString(t);
}
catch (Exception ex)
{
rbtReceicedAscii.Select();
MessageBox.Show("转换失败!" + ex.Message, "错误提示");
return str;
}
}
private string ASCIIToHex(string my2)
{
try
{
byte[] a = Encoding.UTF8.GetBytes(my2.Trim());
string mystr1 = "";
for (int i = 0; i < a.Length; i++)
{
mystr1 += a[i].ToString("X2") + " ";
}
return mystr1;
}
catch (Exception ex)
{
rbtReceicedAscii.Select();
MessageBox.Show("转换失败!" + ex.Message, "错误提示");
return my2;
}
}
private void Form1_Load(object sender, EventArgs e)
{
statusText.Text = "";//状态条初始化
//设置窗口大小
this.MaximizeBox = false;//隐藏最大化按钮
this.MaximumSize = this.Size;//固定窗口尺寸最大为当前尺寸
this.MinimumSize = this.Size;//固定窗口尺寸最小为当前尺寸
BtlCheckBox.SelectedIndex = 5;
// JywCheckBox.Items.Clear();
JywCheckBox.SelectedIndex = 1;
StopCheckBox.SelectedIndex = 1;
// DataBox.Items.Clear();
DataBox.SelectedIndex = 1;
statusText.Text = "";
rbtSendAscii.Select();//默认选择ASCII字符显示
rbtReceicedAscii.Select();//默认选择ASCII字符显示
}
private void btnChecked_Click(object sender, EventArgs e)
{
statusText.Text = "检测串口开始!";
CheckPort();
statusText.Text = "串口检测完成!";
}
private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(100);//等待
this.Invoke((EventHandler)(delegate //异步委托一个线程
{
try
{
byte[] a = new byte[sp.BytesToRead];//读出缓冲区串口通信的字节
sp.Read(a, 0, a.Length);//写入sp
string my2 = Encoding.UTF8.GetString(a);
string b = "";
if (rbtSendAscii.Checked)
{
b = ASCIIToHex(my2);
}
else
{
b = my2;
}
RecevieBox.Text += b + "\r\n";
statusText.Text = "接收成功!";
}
catch
{
statusText.Text = "接收失败!";
}
}));
}
public Form1()
{
InitializeComponent();
}
//发送按钮
private void button1_Click_1(object sender, EventArgs e)
{
try
{
string mystr1 = SendBox.Text;
if (SixtyRe.Checked)//radio如果选择十六进制 则进行转换
{
mystr1 = HexToASCII(SendBox.Text);
}
byte[] a = Encoding.UTF8.GetBytes(mystr1);
string mystr2 = Encoding.UTF8.GetString(a);
sp.Write(mystr2);//将数据写入串行端口输出缓冲区
// tbxReceivedData.Text += tbxSendData.Text + "\r\n";
statusText.Text = "发送成功!";
}
catch
{
statusText.Text = "发送失败";
}
}
private void button1_Click_2(object sender, EventArgs e)
{
RecevieBox.Text = " ";
SendBox.Text = " ";
}
private void BtnOpen_Click(object sender, EventArgs e)
{
if (BtnOpen.Text == "打开串口")
{
SetPort();
if (sp.IsOpen)
{
statusText.Text = "串口" + ckCheckBox.Text + "已打开!";
}
else
{
try
{
sp.Open();
btnChecked.Enabled = false;
ckCheckBox.Enabled = false;
BtlCheckBox.Enabled = false;
JywCheckBox.Enabled = false;
StopCheckBox.Enabled = false;
DataBox.Enabled = false;
BtnOpen.Text = "关闭串口";
statusText.Text = "串口" + ckCheckBox.Text + "打开成功!";
}
catch (Exception ex)
{
MessageBox.Show("串口" + ckCheckBox.Text + "打开失败,失败原因:" + ex.Message, "错误提示");
statusText.Text = "串口" + ckCheckBox.Text + "打开失败,失败原因:" + ex.Message;
}
}
}
else //关闭串口
{
if (sp.IsOpen) //判断串口是否打开
{
try
{
sp.Close(); //关闭串口
//启用设置控件
btnChecked.Enabled = true;
ckCheckBox.Enabled = true;
BtlCheckBox.Enabled = true;
JywCheckBox.Enabled = true;
StopCheckBox.Enabled = true;
DataBox.Enabled = true;
BtnOpen.Text = "打开串口";
statusText.Text = "串口" + ckCheckBox.Text + "关闭成功!";
}
catch (Exception ex)
{
MessageBox.Show("串口" + ckCheckBox.Text + "关闭失败,错误提示:" + ex.Message, "错误提示");
statusText.Text = "串口" + ckCheckBox.Text + "关闭失败,错误提示:" + ex.Message;
}
}
else
{
btnChecked.Enabled = true;
ckCheckBox.Enabled = true;
BtlCheckBox.Enabled = true;
JywCheckBox.Enabled = true;
StopCheckBox.Enabled = true;
DataBox.Enabled = true;
BtnOpen.Text = "打开串口";
statusText.Text = "串口未打开,无法关闭!";
MessageBox.Show("串口未打开,无法关闭!", "错误提示");
}
}
}
private void SixtySend_CheckedChanged(object sender, EventArgs e)
{
if (SixtyRe.Checked)//radio如果选择十六进制 则进行转换
{
SendBox.Text = ASCIIToHex(SendBox.Text.ToString());
}
}
}
}
版权声明:本文为CSDN博主「香煎三文鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_39569480/article/details/120765747
暂无评论