提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
串口助手是一个很好的熟悉串口上位机的小项目,其中只包含对串口的应用,而不包含太多的复杂业务逻辑。
一、界面设计
随便打开一个现成的串口助手软件,应该都会看到这几个配置选项,这里从工具箱拖拽几个Label和ComboBox控件实现。
接下来是显示接收区域,下面的接收区域使用TextBox控件,并把Multiline(多行显示)和ReadOnly(只读,不允许用户输入,只能从程序中修改)属性设置为True。
发送区域和接收区域相同,但ReadOnly属性要设置为False。
设计完成界面
二、程序设计
串口助手的主要功能是将接收到的数据显示在接收区域里,在点击发送时将发送区域的数据通过串口发送出去。
在串口加载事件中添加以下代码,将串口配置选项添加到下拉框中。
private void Form1_Load(object sender, EventArgs e)
{
port.DataBits = 8;//设置数据位数为8位
string[] ports = SerialPort.GetPortNames();//获取已连接的串口
for(int i = 0; i < ports.Length; i++)
{
comboBox1.Items.Add(ports[i]);//添加进下拉框中
}
if(ports.Length > 0)
comboBox1.SelectedIndex = 0;//选中第一个
//添加常用波特率
comboBox2.Items.Add("9600");
comboBox2.Items.Add("38400");
comboBox2.Items.Add("115200");
comboBox2.SelectedIndex = 0;//选中第一个
//添加停止位选项
comboBox3.Items.Add("1");
comboBox3.Items.Add("2");
comboBox3.SelectedIndex = 0;//选中第一个
//添加校验选项
comboBox4.Items.Add("None");
comboBox4.Items.Add("Odd");
comboBox4.Items.Add("Even");
comboBox4.Items.Add("Mark");
comboBox4.Items.Add("Space");
comboBox4.SelectedIndex = 0;//选中第一个
//添加解析方式选项
comboBox5.Items.Add("HEX");
comboBox5.Items.Add("UTF-8");
comboBox5.SelectedIndex = 0;//选中第一个
port.DataReceived += Port_DataReceived;//绑定接收事件
port.ErrorReceived += Port_ErrorReceived;//绑定错误事件
}
修改串口接收事件处理函数
/// <summary>
/// 串口接收事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if(e.EventType == SerialData.Eof)//关闭串口
{
port.Close();
this.Invoke(new Action(() =>//不能从其他线程修改本线程UI
{
button1.Text = "关闭串口";
}));
}
else//接收到字符
{
byte[] dat = new byte[port.BytesToRead];
port.Read(dat, 0, dat.Length);
this.Invoke(new Action(() =>
{
if (comboBox5.SelectedItem.ToString() == "HEX")
{
textBox1.AppendText(BitConverter.ToString(dat).Replace('-', ' '));
textBox1.AppendText(" ");
}
else
{
textBox1.AppendText(System.Text.Encoding.UTF8.GetString(dat));
}
}));
}
}
在打开串口按钮的点击事件中加入以下代码
private void button1_Click(object sender, EventArgs e)
{
if(button1.Text == "打开串口")
{
try
{
port.PortName = comboBox1.Text;//设置端口号
port.BaudRate = int.Parse(comboBox2.SelectedItem.ToString());
port.Parity = (Parity)Enum.Parse(typeof(Parity), comboBox4.SelectedItem.ToString());
switch (comboBox3.SelectedItem.ToString())
{
case "1": port.StopBits = StopBits.One; break;
case "2": port.StopBits = StopBits.Two; break;
}
port.Open();//打开串口
button1.Text = "关闭串口";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);//弹出框显示出现的错误
}
}
else
{
if(port.IsOpen)//判断串口是否打开
{
port.Close();//关闭串口
}
button1.Text = "打开串口";
}
}
接下了是发送按钮点击事件
private void button4_Click(object sender, EventArgs e)
{
if (!port.IsOpen)
{
MessageBox.Show("请先打开串口。", "提示");
return;
}
if (comboBox5.SelectedItem.ToString() == "HEX")
{
byte[] dat = new byte[textBox2.Text.Length / 2 + textBox2.Text.Length % 2];
byte v = 0;
int i = 0, j = 0;
foreach (char c in textBox2.Text)
{
v <<= 4;
if (c >= '0' && c <= '9')
{
v += (byte)((c - '0') & 0xff);
}
else if (c >= 'a' && c <= 'f')
{
v += (byte)((c - 87) & 0xff);
}
else if (c >= 'A' && c <= 'F')
{
v += (byte)((c - 55) & 0xff);
}
else//如果不在0-9 a-f的范围报错
{
MessageBox.Show("请输入0-9,a-f的16进制数", "提示");
return;
}
if (++i == 2)//把两个组合在一起发送
{
dat[j] = v;
j++;
i = 0;
v = 0;
}
}
if (i == 1)
{
dat[j] = v;
}
port.Write(dat, 0, j);
}
else
{
byte[] dat = System.Text.Encoding.UTF8.GetBytes(textBox2.Text);
port.Write(dat, 0, dat.Length);
}
}
结果
这里通过一个USB转看出工具,TX接RX回环的方式实验。