需求:C#实现串口通信,输入指令获取指令结果。
导入控件SerialPort(导航栏找到工具(T)-->选择工具箱项(X)...),如下图:
![](https://img-blog.csdnimg.cn/img_convert/8392ba548bed4ad6a1cb396aa4eae53a.png)
2.编写测试类代码(模拟串口进入boot与下发指令):
string[] ports = System.IO.Ports.SerialPort.GetPortNames(); //获取电脑所有串口
InputSimulator simulator = new InputSimulator(); //好像没用到
if (ports.Length == 0)
{
MessageBox.Show("本机没有串口!");
}
Array.Sort(ports);
sp.PortName = ports[1];//串口号COM3,根据自己需要获取
sp.BaudRate = 115200;//波特率
sp.DataBits = 8;//数据位
sp.StopBits = System.IO.Ports.StopBits.One;//停止位
sp.ReadTimeout = 500;//读取数据的超时时间
sp.Encoding = System.Text.Encoding.GetEncoding("GB2312");//此行非常重要,解决接收中文乱码的问题
try
{
if (sp.IsOpen)
{
sp.Close();//关闭再打开,相当于初始化
sp.Open();//打开串口
//这里设置15秒的时间,要先执行代码再给产品上电,否则产品进入串口的窗口时间太短,可能产品已经过了进入boot的窗口,但是代码还没执行Ctrl+C的操作,导致进不了boot,时间可以根据自己需要设置,循环一次就是一秒
for (int i = 0; i < 15;i++)
{
Thread.Sleep(1000);
ToSendMessage("0x03",100); //这里只能用这种方法实现Ctrl+C进入串口boot的操作,下面两种都不行
//SendKeys.SendWait("^{c}");
//simulator.Keyboard.ModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.VK_C);
}
}
else
{
sp.Close();
sp.Open();//打开串口
//Ctrl+C
for (int i = 0; i < 15; i++)
{
Thread.Sleep(1000);
ToSendMessage("0x03",100);
//SendKeys.SendWait("^{c}");
//simulator.Keyboard.ModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.VK_C);
}
}
string strTelnetMsg = ToSendMessage("echo OK",1000); //获取发送指令结果
if (strTelnetMsg.Contains("OK"))
{
//打印获取到的正确结果
}
else
{
//获取指令结果错误
return;
}
}
catch (Exception ex)
{
MessageBox.Show("错误:" + ex.Message, "C#串口通信"); //串口异常信息提示
}
注意:InputSimulator还需要安装对应的包,如下图:
![](https://img-blog.csdnimg.cn/img_convert/a0d325c2515743769223030de051ea92.png)
3.编写发送指令方法,主测试方法调用就行了(十六进制方式没试过):
//发送数据(第一个参数是发送的指令,第二个参数是等待指令结果的时间)
private String ToSendMessage(string command,int writetime)
{
String m = "";
if (sp.IsOpen)
{
try
{
sp.Encoding = System.Text.Encoding.GetEncoding("GB2312");
//发送数据(类型:十六进制)
//sp.Write(strToHexByte(Command), 0, strToHexByte(Command).Length);
//发送数据(类型:字符串)
sp.WriteLine(command);
System.Threading.Thread.Sleep(writetime);
m = sp.ReadExisting();
if (m.Contains("ath>"))
{
//ath>是我的产品前缀部分,我下指令只想得到指令结果,所以将前缀部分去掉
string[] strValue = Regex.Split(m, "ath>", RegexOptions.IgnoreCase);
m = strValue[0];
}
//发送成功!
}
catch (Exception ex)
{
MessageBox.Show("错误:" + ex.Message); //错误信息提示
}
}
else
{
MessageBox.Show("串口未打开!");
}
return m; //返回指令结果
}
// 字符串转换成16进制编码方式
private byte[] strToHexByte(string hexString)
{
hexString = hexString.Replace(" ", "");
if ((hexString.Length % 2) != 0) hexString += " ";
byte[] returnBytes = new byte[hexString.Length / 2];
for (int i = 0; i < returnBytes.Length; i++)
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2).Replace(" ", ""), 16);
return returnBytes;
}
SerialPort详细参数解读参考:https://www.cnblogs.com/qyhe/articles/8590968.html