C#对串口数据接收、发送的处理
2021/10/14 17:16:07
本文主要是介绍C#对串口数据接收、发送的处理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
最近在做与设备进行串口通信交互的项目,然后简单记录一下过程
使用的winform应用程序
1.在工具箱拖拽SerialPort控件
引用串口命名控件
using System.IO.Ports;
2.先获取电脑所有串口列表
获取到列表后绑定给conboBox,以便选择串口打开
String[] portnames = SerialPort.GetPortNames(); foreach (var item in portnames) { comboBox1.Items.Add(item); }
3.实例化串口打开串口
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("打开失败"); }
4.在控件的接收数据事件中获取串口发送来的数据
private List<byte> buffer = new List<byte>(4096); private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { string receive = "";//数据接收 try { Thread.Sleep(50); //(毫秒)等待一定时间,确保数据的完整性 int len int length = serialPort11.BytesToRead; if (length != 0) { byte[] buff = new byte[length]; serialPort11.Read(buff, 0, length); //receive = Encoding.Default.GetString(buff);//数据接收内容 //textBox1.Text = receive + "\r\n"; //1.缓存数据 buffer.AddRange(buff); //2.完整性判断 while (buffer.Count >= 4) //至少包含帧头(2字节)、长度(1字节)、校验位(1字节);根据设计不同而不同 { //2.1 查找数据头 if (buffer[0] == 0x01) //传输数据有帧头,用于判断 { int len = buffer[2]; if (buffer.Count < len + 4) //数据区尚未接收完整 { break; } receive = Encoding.Default.GetString(buff);//数据接收内容 writetxt(receive); textBox1.Text = receive + "\r\n"; buffer.RemoveRange(0, len + 4); } else //帧头不正确时,记得清除 { buffer.RemoveAt(0); } } } } catch { return; } }
发送接收 完整代码示例
源码下载地址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()); } } } }
这篇关于C#对串口数据接收、发送的处理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-12-06使用Microsoft.Extensions.AI在.NET中生成嵌入向量
- 2024-11-18微软研究:RAG系统的四个层次提升理解与回答能力
- 2024-11-15C#中怎么从PEM格式的证书中提取公钥?-icode9专业技术文章分享
- 2024-11-14云架构设计——如何用diagrams.net绘制专业的AWS架构图?
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#