1.窗体设计
2.串口设置事件
2.1 扫描串口
private void SearchAndSerialComboBox(SerialPort MyPort, ComboBox MyBox)
{
//定义20个串口信息,太多会影响调试效率
//string[] MyString = new string[20];
//定义一个内存缓存变量
string Buffer;
//清空ComboBox下拉控件内容
MyBox.Items.Clear();
//遍历20个串口
for (int i = 1; i < 20; i++)
{
//如果运行成功,就将相应的串口信息添加至ComboBox。
try
{
//将读取的串口信息存在内存中
Buffer = "COM" + i.ToString();
//将内存中的串口信息给相应的控件
MyPort.PortName = Buffer;
//打开串口如果运行失败,后面的代码就不执行了,直接跳转至catch。
MyPort.Open();
//将内存中的串口信息放在字符串数组中
//MyString[i - 1] = Buffer;
//将获取的串口添加到ComboBox
MyBox.Items.Add(Buffer);
//关闭串口
MyPort.Close();
}
catch
{
}
}
//初始化串口
//MyBox.Text = MyString[0];
}
1.扫描串口,不是将1-20个串口全部显示出来,而是只扫描有用的串口。扫描串口其实就是,将可用的串口号添加到ComboBox。
2.我们封装了一个函数。
private void SearchAndSerialComboBox(SerialPort MyPort, ComboBox MyBox)
SerialPort是一个串口类,对象为MyPort
ComboBox是一个控件类,对象为MyBox
扫描串口的核心是:巧妙的使用try{}catch,进行串口扫描。因MyPort.Open();如果运行失败,后面的代码就不执行了,直接跳转至catch。
2.2 在主窗体函数中调用该函数或者在扫描按钮下调用该函数。
private void button1_Click(object sender, EventArgs e)
{
//扫描串口信息,为了之后方便使用,此处进行封装一个串口扫描的函数
SearchAndSerialComboBox(serialPort1, comboBox1);
}
2.3 打开串口,关闭串口按钮事件
private void button2_Click(object sender, EventArgs e)
{
//串口打开
if (serialPort1.IsOpen)
{
try
{
//关闭串口
serialPort1.Close();
//将打开串口按钮置为打开串口
button2.Text = "打开串口";
}
catch
{
MessageBox.Show("串口关闭·1失败", "错误提示");
}
}
//关闭串口
else
{
try
{
//获取串口号
serialPort1.PortName = comboBox1.Text;
//打开串口
serialPort1.Open();
//将打开串口按钮置为关闭串口
button2.Text = "关闭串口";
}
catch
{
MessageBox.Show("串口打开失败","错误提示");
}
}
}
通过扫描串口,可以获取可用的串口,然后选择串口号,打开串口。
打开串口和关闭串口在一个按钮上同时可以实现。
2.4 ovalShape1控件的设计,让打开串口变成绿色,让关闭串口变成灰色。
2.4.1 选择控件。在Visual Basic PowerPacks中选择OvalShape控件。
2.4.2 在属性设置中,选择FillStyle —》 solid,即就是将控件进行填充。
2.4.3 在属性FileColor中,对控件的颜色进行设置。或者程序中设计。因为这个跟串口的打开操作有关,所以我们在程序中设计。
2.4.4 程序中设计如下。需要先在窗体函数中,初始化控件的图标颜色。
//窗口事件
private void Form1_Load(object sender, EventArgs e)
{
//设置ovalShape1控件为灰色,注意该控件刚开始时没有填充,需要在属性中选择FillStyle ---》 solid ---》其次可以修改FileColor的颜色/在程序中修改
//由于VS2013没有相关控件,暂时屏蔽掉
//ovalShape1.FillColor = Color.Gray;
}
2.4.5 因为该控件跟串口打开事件相关,因此,在打开串口按钮中实现。
private void button2_Click(object sender, EventArgs e)
{
//串口打开
if (serialPort1.IsOpen)
{
//点击关闭串口按钮后,ovalShape1控件颜色为灰色
ovalShape1.FillColor = Color.Gray;
try
{
//关闭串口
serialPort1.Close();
//将打开串口按钮置为打开串口
button2.Text = "打开串口";
}
catch
{
MessageBox.Show("串口关闭·1失败", "错误提示");
}
}
//关闭串口
else
{
try
{
//获取串口号
serialPort1.PortName = comboBox1.Text;
//打开串口
serialPort1.Open();
//点击打开串口按钮后,将ovalShape1控件编成绿色。
//放在打开串口按钮后进行操作。因为如果打开失败就无法将ovalShape1控件编成绿色。
//ovalShape1.FillColor = Color.Green;
//将打开串口按钮置为关闭串口
button2.Text = "关闭串口";
}
catch
{
MessageBox.Show("串口打开失败","错误提示");
}
}
}
3.控制下位机程序
3.1 定义全局变量,需要跟下位机保持一致
//定义全局变量--需要跟下位机保持一致
//device 1
const byte DeviceOpen1 = 0x01;
const byte DeviceClose1 = 0x81;
//device 2
const byte DeviceOpen2 = 0x02;
const byte DeviceClose2 = 0x82;
//device 3
const byte DeviceOpen3 = 0x03;
const byte DeviceClose3 = 0x83;
//定义一个串口写内存
byte[] SerialPortDataBuffer = new byte[1];
3.2 自定义一个单字节写入串口
//封装一个单字节写入串口
private void WriteByteToSerialPort(byte data)
{
//定义一个缓冲区数组,里面两个字节,一个是0x00头码, 一个是data
byte[] Buffer = new byte[2]{0x00, data};
if (serialPort1.IsOpen)
{
try
{
//串口写数据:将缓冲区的数组内容全部写入。
serialPort1.Write(Buffer, 0, 2);
}
catch
{
MessageBox.Show("串口发送数据错误", "错误提示");
}
}
else
{
MessageBox.Show("串口未打开", "提示");
}
}
Write(): 使用缓冲区的数据将指定数量的字节写入串行端口。
参数:
1.buffer:
包含要写入端口的数据的字节数组。
2.offset:
buffer 参数中从零开始的字节偏移量,从此处开始将字节复制到端口。
3.count:
要写入的字节数。
3.3 控制下位机
private void button3_Click(object sender, EventArgs e)
{
WriteByteToSerialPort(DeviceOpen1);//N0.1开
}
private void button4_Click(object sender, EventArgs e)
{
WriteByteToSerialPort(DeviceClose1);//N0.1关
}
private void button5_Click(object sender, EventArgs e)
{
WriteByteToSerialPort(DeviceOpen2);//N0.2开
}
private void button6_Click(object sender, EventArgs e)
{
WriteByteToSerialPort(DeviceClose2);//N0.2关
}
private void button7_Click(object sender, EventArgs e)
{
WriteByteToSerialPort(DeviceOpen3); //N0.3开
}
private void button8_Click(object sender, EventArgs e)
{
WriteByteToSerialPort(DeviceClose3);//N0.3关
}
上述控制下位机的程序,这个根据自己的情况自己设计。