• C# Windows多串口绑定


    描述

    有时工作测试中遇到要一拖多去进行串口通讯,例如多串口同时进行烧录,多串口对设备进行控制,指令发送等,平时我用的串口工具都是人为的一对一手动操作,用电脑同时一对多操作串口通讯我还真没用过,但是想到平时工作使用的场景蛮多的,感觉还是很有必要研究下,对工作生产还是很有效率的

    首先做之前我们必须先了解下串口,主要了解串口在电脑重启后,COM口会不会变,插多个串口后COM口会不会变。了解这些是因为我们要依靠COM去绑定依赖关系,COM数据获取简单方便。经检验,串口插上后,更换USB插槽, COM口会跟着变;其他串口插上后不会改变之前插上去的串口的COM口,并重启后COM不会改变。所以我们绑定串口后就不要再插拔串口了,有可能会引起COM改变

    效果图

    目标

    我们要做的主要实现一下功能

    1. 监听USB设备插拔,有USB设备插拔时,更新COM口列表

    2. 绑定的串口可以保存为配置文件,下次启动根据配置文件直接加载配置并绑定

    3. 可以对目标设备绑定多个串口,可以删除绑定的COM口,绑定后COM列表将已绑定的信息移除

    4. 可以观察到哪些绑定的串口是可用的,哪些是断开的

    代码逻辑

    为了方便知道哪根线接的哪个串口,合理的连接到对应的设备上,我增加了USB设备监听功能,当串口插上时,未绑定列表就会新增一条COM信息,我就知道该串口的COM名称了,然后再做绑定,这样也不容易出错

    1. // 在生命周期loaded的时候初始化监听器
    2. // 这里的代码适用与WPF,如果你是Winform,请查看我写的USB监听的博文
    3. private void OnLayoutLoaded(object sender, RoutedEventArgs e)
    4. {
    5. HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
    6. if (null != hwndSource)
    7. hwndSource.AddHook(new HwndSourceHook(DevieceChanged));
    8. }
    9. private IntPtr DevieceChanged(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    10. {
    11. if (msg == WM_DEVICECHANGE)
    12. {
    13. switch (wParam.ToInt32())
    14. {
    15. case DBT_DEVICEARRIVAL:
    16. Console.WriteLine("串口连接成功!");
    17. break;
    18. case DBT_DEVICEREMOVECOMPLETE:
    19. Console.WriteLine("串口断开!");
    20. break;
    21. }
    22. if(wParam.ToInt32() == DBT_DEVICEARRIVAL || wParam.ToInt32() == DBT_DEVICEREMOVECOMPLETE)
    23. {
    24. // 这里用线程主要事因为,有时一个串口设备有2个COM口,在线程里面等待两个口都连接
    25. // 上后,再刷新界面,只用刷新一次
    26. Thread thread = new Thread(new ThreadStart(OnDiveceChanged));
    27. thread.Start();
    28. }
    29. }
    30. return IntPtr.Zero;
    31. }
    32. private bool isUpdataComsList = false;
    33. private object lockObj = new object();
    34. private void OnDiveceChanged()
    35. {
    36. lock (lockObj)
    37. {
    38. if (isUpdataComsList) return;
    39. isUpdataComsList = true;
    40. }
    41. Thread.Sleep(1000);
    42. m_SyncContext.Post(UpdataComsList, null);
    43. }

    设备绑定:如果单设备的话,我们只需要将COM口和设备对应即可,用键值对的方式存储,例如----->DUT1:COM3,DUT2:COM8。等你需要连接串口时, 你根据自己的编号取对应的COM口即可,比如自己的编号为“DUT2”,那我们就连接COM8的串口即可

    对于一个设备时需要连接多个串口, 而且需要控制多个设备时,我引入了Tag的概念,比如说功能1的Tag为CMS1,功能2的Tag为CMS2,在保存数据的形式还是键值对的方式,不过值变成了一个对象,对象里保存了COM口信息和TAG信息。例如DUT1:[{Serial:COM3,Tag:CMS1},{Serial:COM5,Tag:CMS2}],当某一个设备在使用某一项功能时,只要知道保存的TAG,就可以获取到配置的串口

    我保存的串口是以XML形式保存的,可以根据自己喜欢的方式进行选择

    解析保存的配置文件略

    1. public static void SaveSerialsBindInfo(Dictionary<string,List> infos)
    2. {
    3. CheckSaveConfigFilesPath();
    4. XmlDocument xmlDoc = new XmlDocument();
    5. XmlElement root = xmlDoc.CreateElement("SerialsConfig");
    6. xmlDoc.AppendChild(root);
    7. XmlElement DutBindInfoElement;
    8. foreach (KeyValuePair<string, List> kv in infos){
    9. if (kv.Value.Count == 0) continue;
    10. DutBindInfoElement = xmlDoc.CreateElement("DutBindInfo");
    11. DutBindInfoElement.SetAttribute("DutNum" , kv.Key);
    12. XmlElement SerialNameElement;
    13. XmlElement RemarkElement;
    14. foreach (SerialsBindInfo serialInfo in kv.Value)
    15. {
    16. if (serialInfo.SerialName.Trim().Length == 0 && serialInfo.Remark.Trim().Length == 0) continue;
    17. XmlElement BindInfoItemElement = xmlDoc.CreateElement("InfoItem");
    18. SerialNameElement = xmlDoc.CreateElement("SerialName");
    19. SerialNameElement.InnerText = serialInfo.SerialName;
    20. RemarkElement = xmlDoc.CreateElement("Remark");
    21. RemarkElement.InnerText = serialInfo.Remark;
    22. BindInfoItemElement.AppendChild(SerialNameElement);
    23. BindInfoItemElement.AppendChild(RemarkElement);
    24. DutBindInfoElement.AppendChild(BindInfoItemElement);
    25. }
    26. root.AppendChild(DutBindInfoElement);
    27. }
    28. xmlDoc.Save(FilePathConfig.SerialsBindConfigPath);
    29. }

    COM口绑定后,需要将已绑定的串口从待绑定的列表中删除,不然串口多了比较乱,分不清哪一个是哪一个,列表只显示待绑定的

    如果解除绑定后,也需要将解除的COM添加到待绑定列表里面

    如果从COM1切换到COM2,这里面既有添加,也有删除,为了方便和满足上面的3种需求,我就先将所有COM获取,再将已经绑定的数据从所有COM中移除,就只剩未绑定的了

    1. private void SerialsSelectionChanged(object sender, SelectionChangedEventArgs e)
    2. {
    3. ComboBox comboBox = (ComboBox)sender;
    4. Label SelectItem = (Label)comboBox.SelectedItem;
    5. if (SelectItem == null) return;
    6. string content = (string)SelectItem.Content;
    7. if (ContentNone.Equals(content))
    8. comboBox.Items.Clear();
    9. else
    10. unBindSerials.Remove(content);
    11. DockPanel itemLayout = (DockPanel)comboBox.Parent;
    12. // 先刷新刚刚选中的COM口的UI
    13. UpdataBindData(itemLayout);
    14. // 再过滤未绑定的数据
    15. FilterUnbindComs();
    16. // 刷新未绑定列表的UI
    17. UpdateComsList();
    18. }
    19. private void FilterUnbindComs()
    20. {
    21. // 清除历史数据
    22. unBindSerials.Clear();
    23. // 遍历所有的COM,包含绑定和未绑定的所有COM口
    24. foreach (string ComName in allComsList)
    25. {
    26. bool isContains = false;
    27. // 遍历查找是否该COM口已经绑定
    28. foreach (List ComsInfos in bindData.Values)
    29. {
    30. foreach (SerialsBindInfo info in ComsInfos)
    31. {
    32. if (ComName.Equals(info.SerialName))
    33. {
    34. isContains = true;
    35. break;
    36. }
    37. }
    38. }
    39. // 如果没绑定,则添加进未绑定列表
    40. if(!isContains) unBindSerials.Add(ComName);
    41. }
    42. }

    现在绑定和保存都可以了,但是有时候设备会出异常,我们首先要看看串口设备是不是正常的,串口都没接好,肯定没办法正常工作

    检测的办法就是获取当前所有串口(当前所有可用串口),对比绑定数据,看看绑定的串口是否在当前可用串口列表中,如果没有在串口列表,则用红色的图标标记,便于工程人员检修时方便观察检修

    1. //默认Image是显示的,当判断到符合条件时,将其隐藏
    2. if (serialsBindInfo == null || serialsBindInfo.SerialName == null || serialsBindInfo.SerialName.Trim().Length == 0 || allComsList.Contains(serialsBindInfo.SerialName))
    3. EnableImage.Visibility = Visibility.Hidden;

    小结

    串口绑定其实很简单的,只要是思想:如何一对多。上面逻辑可以帮助大家将多路串口连接,并可以多机控制

    如果你喜欢我的文章请长按点赞哦

  • 相关阅读:
    【主流技术】Mybatis Plus的理解与应用
    小哥用Python兼职月入过万,用Python做项目有多赚钱?
    前后端分离技术架构模式演变
    springBoot 多次请求限制
    《算法通关村——不简单的字符串转换问题》
    java计算机毕业设计智慧机场管理系统源程序+mysql+系统+lw文档+远程调试
    IBM HTTP Server ( IHS服务器)SSL证书安装教程
    python数据分析——数据可视化(图形绘制)
    秒杀系统设计
    python魔法__dir__和__dict__
  • 原文地址:https://blog.csdn.net/baoolong/article/details/127390812