C#串口通信模块使用

C#串口模块的使用。使用VS .net框架下WinForm程序应用开发。

C#开发的串口通信小工具。

6AD8CA5F-E575-AB85-B9AD-E1FF5BE44256.png

相比于QT添加的串口类,WinForm是通过组件的形式将串口加入到程序中。

3C48648A-3E24-0C52-E28E-DDF7D4EA0A5B.png

289832B2-7F0A-D1FF-AC9E-C2AB0E81C482.png

在创建完windows窗体之后,添加组件类,就可以将串口加入到其中。

40E545E7-3B3F-5728-3920-6B8A5C1AC331.png

然后就需要写数据成员,初始化和方法,实现串口的读写功能。

串口类数据成员
SerialPort SComm;            // 使用构造函数取串口控件
   TextBox MsgRc;               // 接收数据成员
   //构造函数初始化
   public SerialComm(SerialPort SerialPortx,TextBox TextMsg)
   {
       SComm = SerialPortx;    //串口模块
       MsgRc = TextMsg;        //存放接收到的消息
   }
串口初始化
public bool SeriaInit(string comx)
   {
       try
       {
           if (SComm.IsOpen)
               SComm.Close();
       }
       catch 
       {

       }
       SComm.PortName = comx;                          // 串口号
       SComm.BaudRate = 921600;                        // 波特率:1000000
       SComm.DataBits = 8;                             // 数据位数:8
       SComm.StopBits = System.IO.Ports.StopBits.One;  // 停止位
       SComm.Parity = System.IO.Ports.Parity.None;     // 奇偶校验无
       SComm.Encoding = Encoding.Default;
       SComm.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.serialPort1_Rcv);
       try
       {
           SComm.Open();                                // 打开串口
           return true;
       }
       catch 
       {
           MessageBox.Show(comx + "端口被占用","提示",MessageBoxButtons.OK,MessageBoxIcon.Error);
           return false;
       }
   }
串口写
public void SeriaWrite(byte [] data, byte len)
   {
       try
       {
           if (SComm.IsOpen)
           {
               SComm.Write(data, 0, len);    
           }
       }
       catch { }
                           
   }
串口读

串口读到的消息存放再MsgRc中, 之后显示到TextBox中。

void serialPort1_Rcv(object sender, SerialDataReceivedEventArgs e)
  {
      UInt16 bufflen = (UInt16)SComm.BytesToRead;    //返回接收到的数据个数

      byte[] dat = new byte[bufflen];
      SComm.Read(dat, 0, bufflen);
      MsgRc.AppendText(System.Text.Encoding.Default.GetString(dat));
      CommBuff = dat;    //
      GetHeadFlag = 0;
   }
自动获取端口信息

定义了一些系统和设备的信息,然后调用API函数查找串口,如果设备信息带COM字符,则认为为是串口。

之后再定义WndProc消息处理函数,如果有新的硬件插入,则开启定时器刷新端口信息

public enum HardwareEnum
 {
    // 硬件
    Win32_Processor,         // CPU 处理器
    Win32_PhysicalMemory,    // 物理内存条
    Win32_Keyboard,          // 键盘
    Win32_PointingDevice,    // 点输入设备,包括鼠标。
    Win32_FloppyDrive,       // 软盘驱动器
    Win32_DiskDrive,         // 硬盘驱动器
    Win32_CDROMDrive,        // 光盘驱动器
    Win32_BaseBoard,         // 主板
    Win32_BIOS,              // BIOS 芯片
    Win32_ParallelPort,      // 并口
    Win32_SerialPort,        // 串口
    Win32_SerialPortConfiguration,   // 串口配置
    Win32_SoundDevice,               // 多媒体设置,一般指声卡。
    Win32_SystemSlot,                // 主板插槽 (ISA & PCI & AGP)
    Win32_USBController,             // USB 控制器
    Win32_NetworkAdapter,            // 网络适配器
    Win32_NetworkAdapterConfiguration, // 网络适配器设置
    Win32_Printer,                  // 打印机
    Win32_PrinterConfiguration,     // 打印机设置
    Win32_PrintJob,                 // 打印机任务
    Win32_TCPIPPrinterPort,         // 打印机端口
    Win32_POTSModem,                // MODEM
    Win32_POTSModemToSerialPort,    // MODEM 端口
    Win32_DesktopMonitor,           // 显示器
    Win32_DisplayConfiguration,     // 显卡
    Win32_DisplayControllerConfiguration,    // 显卡设置
    Win32_VideoController,                  // 显卡细节。
    Win32_VideoSettings,                    // 显卡支持的显示模式。

    // 操作系统
    Win32_TimeZone,                    // 时区
    Win32_SystemDriver,                // 驱动程序
    Win32_DiskPartition,               // 磁盘分区
    Win32_LogicalDisk,                 // 逻辑磁盘
    Win32_LogicalDiskToPartition,      // 逻辑磁盘所在分区及始末位置。
    Win32_LogicalMemoryConfiguration,  // 逻辑内存配置
    Win32_PageFile,                    // 系统页文件信息
    Win32_PageFileSetting,             // 页文件设置
    Win32_BootConfiguration,           // 系统启动配置
    Win32_ComputerSystem,              // 计算机信息简要
    Win32_OperatingSystem,             // 操作系统信息
    Win32_StartupCommand,              // 系统自动启动程序
    Win32_Service,                     // 系统安装的服务
    Win32_Group,                       // 系统管理组
    Win32_GroupUser,                   // 系统组帐号
    Win32_UserAccount,                 // 用户帐号
    Win32_Process,                     // 系统进程
    Win32_Thread,                      // 系统线程
    Win32_Share,                       // 共享
    Win32_NetworkClient,               // 已安装的网络客户端
    Win32_NetworkProtocol,             // 已安装的网络协议
    Win32_PnPEntity,                   //all device
}


//如果是设备字符串中存在COM,则保存该字符串,则找到串口名。
private static string[] GetHarewareInfo(HardwareEnum hardType, string propKey)
{
    List<string> strs = new List<string>();
    try
    {
        using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from " + hardType))
        {
            var hardInfos = searcher.Get();
            foreach (var hardInfo in hardInfos)
            {
                if (hardInfo.Properties[propKey].Value != null)
                {
                    String str = hardInfo.Properties[propKey].Value.ToString();
                    if (str.Contains("COM"))
                    {
                        strs.Add(str);
                    }
                }
            }
        }
        return strs.ToArray();
    }
    catch
    {
        MessageBox.Show("硬件端口查找错误", "程序猿的提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return null;
    }
    finally
    {
        strs = null;
    }
}

//自动检测新的硬件插入,如果存在则开启定时器,刷新端口名
 protected override void WndProc(ref Message m)
 {
     const int WM_DEVICECHANGE = 0x219;
     if (m.Msg == WM_DEVICECHANGE)
     {
         timer3.Interval = 100;
         timer3.Enabled = true;
         DeviceTimer3Flag = true;

     }
     base.WndProc(ref m); //将系统消息传递自父类的WndProc
 }
//定时器函数,刷新端口名
private void timer3_Tick(object sender, EventArgs e)
{
    if (DeviceTimer3Flag)
    {
        DeviceTimer3Flag = false;
        RefreshComList();
        timer3.Enabled = false;
        this.comboBox1.SelectedIndex = -1;
        
    }
    if(ShowTimer3Flag)
    {
        ShowTimer3Flag = false;
        timer3.Enabled = false;
        toolStripStatusLabel4.Text = "";
    }
}
//刷新端口名信息
protected void RefreshComList()
{
    string[] str = GetHarewareInfo(HardwareEnum.Win32_PnPEntity, "Name");//获取全部驱动名称
    //foreach (string vPortName in SerialPort.GetPortNames())
    try
    {
        comboBox1.Items.Clear();
        for (byte i = 0; i < str.Length; i++)
        {
            //this.comboBox1.Text =  vPortName ;
            comboBox1.Items.Add(str[i]);
        }
    }
    catch (Exception)
    {
        ShowMessage("没有可用端口", 1000);
    }
    this.Refresh();
}
//获取端口信息后,提取出COM口,初始化端口。
 private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    if(button2.Text == "停止发送")
    {
        button2.Text = "配置发送";
        timer2.Enabled = false;
    }
    string comPortName;
    string TempByte;
    string ConstByte = "-";
    int startIndex = comboBox1.SelectedItem.ToString().LastIndexOf("(");
    int endIndex = comboBox1.SelectedItem.ToString().LastIndexOf(")");
    if ((endIndex-startIndex)>5)
    {
        TempByte = comboBox1.SelectedItem.ToString().Substring(startIndex + 6, 1);
          if (TempByte == ConstByte)
        {
           comPortName  = comboBox1.SelectedItem.ToString().Substring(startIndex + 1, 5);
        }
        else
        {
            comPortName = comboBox1.SelectedItem.ToString().Substring(startIndex + 1, 4);
        }
    }
    else
    {
       comPortName  = comboBox1.SelectedItem.ToString().Substring(startIndex + 1, 4);
    }
    if (SerialCommx.SeriaInit(comPortName))
    {
        ShowMessage(SerialCommx.GetPortName() + "已打开", 1000);
        button2.Enabled = true;
    }
    else
    {
        ShowMessage(SerialCommx.GetPortName() + "未打开",1000);
        button2.Enabled = false;
    }
    CurrentCOM = comboBox1.SelectedItem.ToString();
}
消息函数

最后WinForm窗口程序开发,可以添加很多消息,比如关闭窗口消息等,可供开发完成不同的需求任务。

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    if (thread != null)
        thread.Abort();
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
    this.Text = "1111";
}

D8178A61-0387-47FF-56F5-98DC2D6CFEFA.png

代码链接:https://download.csdn.net/download/qq_34430371/12310619

收藏 (0)
评论列表
正在载入评论列表...
我是有底线的