串口连接有几个必须要设置的值:串口,波特率,校验位,数据位,停止位
目录
一、实例化串口通讯类
二、打开串口/关闭串口
三、发送数据:hex十六进制发送或ascll发送
四、十六进制字符串转byte【】
五、接收数据:hex十六进制接收或ascll接收
六、定时发送
七、将接收到的消息导出txt文件
简单串口通讯效果图
串口:获取串口
string[] ports = SerialPort.GetPortNames();
foreach (string port in ports)
{
CbCom.Items.Add(port);
}CbCom.SelectedIndex = 0;
波特率: 波特率单位是bit/s,代表是每秒传递多少个bit,也就是多少个位。一般使用9600
波特率代表串口的传输数据能力,波特率越高传输数据越快,但是太高会出现传输数据不稳定的问题;发送方与接收方波特率要保持一致。 CbBaudRate.SelectedIndex = 5;
校验位: C#中有Parity枚举类型设置校验位。一般使用None无校验,Odd奇校验,Even偶检验。
comboBox4.SelectedIndex = 0;
数据位:一般情况下使用8,其他的也可以设置 CbDataBits.SelectedIndex = 3;
停止位: C#中StopBits枚举类型设置停止位,默认值设置1 StopBits.One CbStopBits.SelectedIndex = 1;
SerialPort sp = new SerialPort();//实例化串口通讯类
private System.Timers.Timer tmr = new System.Timers.Timer();//实例化定时发送定时器
private object obj = new object();//锁
页面初次加载时
sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);//接收数据事件
sp.Encoding = System.Text.Encoding.GetEncoding("GB2312");//编码类型tmr.Elapsed += new System.Timers.ElapsedEventHandler(OnTmrTrg);定时事件
tmr.Interval =(double)numericUpDown4.Value;//定时发送间隔时间
tmr.AutoReset = true; //true-一直循环 ,false-循环一次
tmr.Enabled = false;
if (button1.Text == "打开串口")
{
sp.PortName = CbCom.Text;//串口
sp.BaudRate =int.Parse(CbBaudRate.Text);//波特率
sp.DataBits=int.Parse(CbDataBits.Text);//数据位
sp.StopBits=(StopBits)int.Parse(CbStopBits.Text);//停止位
if (sp.IsOpen)
{
sp.Close();
sp.Open();
}
else
{
sp.Open();
}
textBox2.AppendText("[" + DateTime.Now + "]串口已打开:" + CbCom.Text + "\r\n");
comboBox4.Enabled = false;
CbBaudRate.Enabled = false;
CbCom.Enabled = false;
CbDataBits.Enabled = false;
CbStopBits.Enabled = false;
button1.Text = "关闭串口";}
else
{
if (sp.IsOpen)
sp.Close();
textBox2.AppendText("[" + DateTime.Now + "]串口已关闭:" + CbCom.Text + "\r\n");
button1.Text = "打开串口";
comboBox4.Enabled = true;
CbBaudRate.Enabled = true;
CbCom.Enabled = true;
CbDataBits.Enabled = true;
CbStopBits.Enabled = true;
}
if (sp.IsOpen)
{
try
{
if (radioSendHex.Checked)//十六进制发送数据
{
Byte[] strbyte = HexStringToBytes(textBox1.Text);
sp.Write(strbyte, 0, strbyte.Length);//发送数据
}
else//ascll发送数据
{
sp.Write(textBox1.Text);//发送数据
}
textBox2.AppendText("[" + DateTime.Now + "]发送→:" + textBox1.Text+ "\r\n");
}
catch (Exception ex)
{
MessageBox.Show("错误:" + ex.Message);
}
}
else
{
MessageBox.Show("请先打开串口!");
}
private byte[] HexStringToBytes(string hs)//十六进制字符串转byte
{
string a = hs.Replace(" ", "");
int bytelength = 0;
if (a.Length % 2 == 0)
{
bytelength = a.Length / 2;
}
else
{
bytelength = a.Length / 2 + 1;
}
byte[] b = new byte[bytelength];
//逐个字符变为16进制字节数据
for (int i = 0; i < bytelength; i++)
{
if (i == bytelength - 1)
{
b[i] = Convert.ToByte(a.Substring(i * 2), 16);
}
else
{
b[i] = Convert.ToByte(a.Substring(i * 2, 2), 16);
}
}
//按照指定编码将字节数组变为字符串
return b;
}
private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)//接收数据
{
int len = sp.BytesToRead;//获取可以读取的字节数byte[] buff = new byte[len];//创建缓存数据数组
sp.Read(buff, 0, len);//把数据读取到buff数组
Invoke((new Action(() => {//C# 3.0以后代替委托的新方法
if (radioRecvHex.Checked)//hex接收数据
{
textBox2.AppendText("[" + DateTime.Now + "]接收←:" + BitConverter.ToString(buff, 0, buff.Length).Replace("-", " ") + "\r\n");
}
else
{
textBox2.AppendText("[" + DateTime.Now + "]接收←:" + Encoding.Default.GetString(buff)+"\r\n");//对话框追加显示数据
}})));
}
private void OnTmrTrg(object sender, System.Timers.ElapsedEventArgs e)
{
lock (obj)
{
if (textBox1.Text.Length > 0)
{
if (sp.IsOpen)
{
Invoke((new Action(() => {//C# 3.0以后代替委托的新方法
if (radioSendHex.Checked)//十六进制发送数据
{
Byte[] strbyte = HexStringToBytes(textBox1.Text);
sp.Write(strbyte, 0, strbyte.Length);//发送数据
}
else//ascll发送数据
{
sp.Write(textBox1.Text);//发送数据
}
textBox2.AppendText("[" + DateTime.Now + "]定时发送→:" + textBox1.Text + "\r\n");
})));
}
}
}
}private void checkBox1_CheckedChanged(object sender, EventArgs e)//定时发送复选框改变
{
if(checkBox1.Checked)
{
tmr.Interval = (double)numericUpDown4.Value;
tmr.Enabled = true;
}
else
{
tmr.Enabled = false;
}
}
SaveFileDialog saveFileDialog = new SaveFileDialog();
//设置文件标题
saveFileDialog.Title = "导出CSV文件";
//设置文件类型
saveFileDialog.Filter = "txt文件(*.txt)|*.txt";
//设置默认文件类型显示顺序
saveFileDialog.FilterIndex = 1;
//是否自动在文件名中添加扩展名
saveFileDialog.AddExtension = true;
//是否记忆上次打开的目录
saveFileDialog.RestoreDirectory = true;
//设置默认文件名
saveFileDialog.FileName = "";
//按下确定选择的按钮
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
FileStream fs = new FileStream(saveFileDialog.FileName.ToString(), FileMode.Append);
StreamWriter sw = new StreamWriter(fs, Encoding.Default);
sw.Write(textBox2.Text);
//释放资源
sw.Close();
fs.Close();
MessageBox.Show("导出成功");
}