概述
在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信。串口通信方便易行,应用广泛。一般情况下,工控机和各智能仪表通过RS485总线进行通信。RS485的通信方式是半双工的。在Win32下,可以使用两种编程方式实现串口通信,其一是使用ActiveX控件,这种方法程序简单,但欠灵活。其二是调用Windows的API函数,这种方法可以清楚地掌握串口通信的机制,并且自由灵活。
串口通信的步骤:
(1) 打开串口
(2) 配置串口
(3) 读写串口
(4) 关闭串口
所用的技术:
从Microsoft .Net 2.0版本以后,就默认提供了System.IO.Ports.SerialPort类,用户可以非常简单地编写少量代码就完成串口的信息收发程序。
串口端口号搜索
//检查是否含有串口
string[] str = SerialPort.GetPortNames();
if (str == null)
{
MessageBox.Show("本机没有串口!", "Error");
return;
}
//添加串口
foreach (string s in str)
{
comboBoxCom.Items.Add(s);
}
初始化
Control.CheckForIllegalCrossThreadCalls = false;
serialPort.DataReceived += new SerialDataReceivedEventHandler(dataReceived);
//准备就绪
serialPort.DtrEnable = true;
serialPort.RtsEnable = true;
//设置数据读取超时为1秒
serialPort.ReadTimeout = 1000;
serialPort.Close();
打开串口
if (!serialPort.IsOpen)//串口处于关闭状态
{
try
{
if (comboBoxCom.SelectedIndex == -1)
{
MessageBox.Show("Error: 无效的端口,请重新选择", "Error");
return;
}
string strSerialName = comboBoxCom.SelectedItem.ToString();
string strBaudRate = comboBoxBaudRate.SelectedItem.ToString();
string strDataBit = comboBoxDataBit.SelectedItem.ToString();
string strCheckBit = comboBoxCheckBit.SelectedItem.ToString();
string strStopBit = comboBoxStopBit.SelectedItem.ToString();
Int32 iBaudRate = Convert.ToInt32(strBaudRate);
Int32 iDataBit = Convert.ToInt32(strDataBit);
serialPort.PortName = strSerialName;//串口号
serialPort.BaudRate = iBaudRate;//波特率
serialPort.DataBits = iDataBit;//数据位
serialPort.StopBits = StopBits.One; //停止位
serialPort.Parity = Parity.Odd;//校验位
if (saveDataFile != null)
{
saveDataFS = File.Create(saveDataFile);
}
//打开串口
serialPort.Open();
//打开串口后设置将不再有效
comboBoxCom.Enabled = false;
comboBoxBaudRate.Enabled = false;
comboBoxDataBit.Enabled = false;
comboBoxCheckBit.Enabled = false;
comboBoxStopBit.Enabled = false;
radioButtonSendDataASCII.Enabled = false;
radioButtonSendDataHex.Enabled = false;
radioButtonReceiveDataASCII.Enabled = false;
radioButtonReceiveDataHEX.Enabled = false;
buttonSendData.Enabled = true;
Button_Refresh.Enabled = false;
buttonOpenCloseCom.Text = "关闭串口";
}
catch(System.Exception ex)
{
MessageBox.Show("Error:" + ex.Message, "Error");
return;
}
关闭串口
else //串口处于打开状态
{
serialPort.Close();//关闭串口
//串口关闭时设置有效
comboBoxCom.Enabled = true;
comboBoxBaudRate.Enabled = true;
comboBoxDataBit.Enabled = true;
comboBoxCheckBit.Enabled = true;
comboBoxStopBit.Enabled = true;
radioButtonSendDataASCII.Enabled = true;
radioButtonSendDataHex.Enabled = true;
radioButtonReceiveDataASCII.Enabled = true;
radioButtonReceiveDataHEX.Enabled = true;
buttonSendData.Enabled = false;
Button_Refresh.Enabled = true;
buttonOpenCloseCom.Text = "打开串口";
if (saveDataFS != null)
{
saveDataFS.Close(); // 关闭文件
saveDataFS = null;//释放文件句柄
}
}
接收数据
if (radioButtonReceiveDataASCII.Checked == true) //接收格式为ASCII
{
try
{
String input = serialPort.ReadLine();
textBoxReceive.Text += input + "\r\n";
// save data to file
if (saveDataFS != null)
{
byte[] info = new UTF8Encoding(true).GetBytes(input + "\r\n");
saveDataFS.Write(info, 0, info.Length);
}
}
catch(System.Exception ex)
{
MessageBox.Show(ex.Message, "你波特率是不是有问题???");
return;
}
发送数据
if (!serialPort.IsOpen)
{
MessageBox.Show("请先打开串口", "Error");
return;
}
String strSend = textBoxSend.Text;//发送框数据
if (radioButtonSendDataASCII.Checked == true)//以字符串 ASCII 发送
{
serialPort.WriteLine(strSend);//发送一行数据
}
else
{
//16进制数据格式 HXE 发送
char[] values = strSend.ToCharArray();
foreach (char letter in values)
{
// Get the integral value of the character.
int value = Convert.ToInt32(letter);
// Convert the decimal value to a hexadecimal value in string form.
string hexIutput = String.Format("{0:X}", value);
serialPort.WriteLine(hexIutput);
}
}