C#实现串口调试工具

前文

由于经常用到串口调试, 尽管有现成的软件, 因为前端时间涉及一个二次开发, 就因为一个RtsEnable设置, 折腾半天, 网上各种版本的也很多, 功能扩展的很开也多。所以现在自己做了一个够用版,基于自己的需求,简单的实现发送接收功能, 至于那些扩展功能可以自己根据需求添加。

正文

先上个运行效果图:

项目架构

该实例用的GalaSoft.Mvvm, 该插件可以直接在NuGet中并且添加。

1.串口参数 , 为了方便, 端口号并没有用动态加载的方式, 如下枚举结构:

namespace System.Windows.Data
{
    //
    // 摘要:
    //     提供将自定义逻辑应用于绑定的方法。
    public interface IValueConverter
    {
        //
        // 摘要:
        //     转换值。
        //
        // 参数:
        //   value:
        //     绑定源生成的值。
        //
        //   targetType:
        //     绑定目标属性的类型。
        //
        //   parameter:
        //     要使用的转换器参数。
        //
        //   culture:
        //     要用在转换器中的区域性。
        //
        // 返回结果:
        //     转换后的值。 如果该方法返回 null,则使用有效的 null 值。
        object Convert(object value, Type targetType, object parameter, CultureInfo culture);
        //
        // 摘要:
        //     转换值。
        //
        // 参数:
        //   value:
        //     绑定目标生成的值。
        //
        //   targetType:
        //     要转换为的类型。
        //
        //   parameter:
        //     要使用的转换器参数。
        //
        //   culture:
        //     要用在转换器中的区域性。
        //
        // 返回结果:
        //     转换后的值。 如果该方法返回 null,则使用有效的 null 值。
        object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
    }
}

2.串口参数配置类 ,

作用: 主要用于绑定界面的参数选项。

/// <summary>
    /// 串口参数设置类
    /// </summary>
    public class ComParameterConfig : ViewModelBase
    {
        public ComParameterConfig()
        {
            Port = System.Enum.GetValues(typeof(Port));
            CheckMode = System.Enum.GetValues(typeof(CheckMode));
            StopBit = System.Enum.GetValues(typeof(StopBit));
            BaudRate = new List<int>() { 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 56000, 57600, 115200, };
            DataBit = new List<int>() { 6, 7, 8 };
        }

        private Array port;
        private Array checkMode;
        private Array stopBit;
        private List<int> dataBit;
        private List<int> baudRate;

        /// <summary>
        /// 端口
        /// </summary>
        public Array Port
        {
            get { return port; }
            set { port = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 校验模式
        /// </summary>
        public Array CheckMode
        {
            get { return checkMode; }
            set { checkMode = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 停止位
        /// </summary>
        public Array StopBit
        {
            get { return stopBit; }
            set { stopBit = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 波特率
        /// </summary>
        public List<int> BaudRate
        {
            get { return baudRate; }
            set { baudRate = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 数据位
        /// </summary>
        public List<int> DataBit
        {
            get { return dataBit; }
            set { dataBit = value; RaisePropertyChanged(); }
        }

    }

3.当前配置参数类

作用: 用于保存当前的串口参数、串口功能开关接收数据等业务。

核心代码:

/// <summary>
    /// 当前配置参数
    /// </summary>
    public class CurrentParameter : ViewModelBase
    {
        #region Private

        private int baudRdate = 9600;
        private int dataBit = 8;
        private Port port;
        private CheckMode checkMode;
        private StopBit stopBit = StopBit.One;
        private SerialPort serialPort;

        private string dataReceiveInfo;
        private string sendData;
        private bool isOpen;
        private bool receiveFormat16 = true;
        private bool sendFormat16 = true;

        private int sendCount;
        private int receiveCount;

        #endregion

        #region UI绑定参数

        /// <summary>
        /// 发送数量
        /// </summary>
        public int SendCount
        {
            get { return sendCount; }
            set { sendCount = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 接收数量
        /// </summary>
        public int ReceiveCount
        {
            get { return receiveCount; }
            set { receiveCount = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 接收区16进制
        /// </summary>
        public bool ReceiveFormat16
        {
            get { return receiveFormat16; }
            set { receiveFormat16 = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 接收区数据
        /// </summary>
        public string DataReceiveInfo
        {
            get { return dataReceiveInfo; }
            set { dataReceiveInfo = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        public string SendData
        {
            get
            {
                return sendData;
            }
            set { sendData = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 发送区16进制
        /// </summary>
        public bool SendFormat16
        {
            get { return sendFormat16; }
            set { sendFormat16 = value; RaisePropertyChanged(); }
        }

        #endregion

        #region 串口参数信息

        /// <summary>
        /// 开关
        /// </summary>
        public bool IsOpen
        {
            get { return isOpen; }
            set { isOpen = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 数据位
        /// </summary>
        public int DataBit
        {
            get { return dataBit; }
            set { dataBit = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 波特率
        /// </summary>
        public int BaudRdate
        {
            get { return baudRdate; }
            set { baudRdate = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 端口
        /// </summary>
        public Port Port
        {
            get { return port; }
            set { port = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 校验
        /// </summary>
        public CheckMode CheckMode
        {
            get { return checkMode; }
            set { checkMode = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 停止位
        /// </summary>
        public StopBit StopBit
        {
            get { return stopBit; }
            set { stopBit = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// COM
        /// </summary>
        public SerialPort SerialPort
        {
            get { return serialPort; }
            set { serialPort = value; RaisePropertyChanged(); }
        }

        #endregion

        #region 串口操作方法

        /// <summary>
        /// 开启串口
        /// </summary>
        /// <returns></returns>
        public bool Open()
        {
            if (serialPort != null && serialPort.IsOpen)
            {
                return Close();
            }
            try
            {
                serialPort = new SerialPort();
                serialPort.DataBits = this.DataBit;
                serialPort.StopBits = ComHelper.GetStopBits(this.StopBit.ToString());
                serialPort.Parity = ComHelper.GetParity(this.CheckMode.ToString());
                serialPort.PortName = this.Port.ToString();
                serialPort.RtsEnable = true;
                serialPort.DataReceived += SerialPort_DataReceived;
                serialPort.Open();

                if (serialPort.IsOpen)
                    return IsOpen = true;
                else
                    return IsOpen = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            return IsOpen = false;
        }

        /// <summary>
        /// 关闭串口
        /// </summary>
        /// <returns></returns>
        public bool Close()
        {
            try
            {
                if (serialPort.IsOpen)
                {
                    serialPort.Close();
                    return IsOpen = serialPort.IsOpen;
                }
                else
                {
                    return IsOpen = serialPort.IsOpen;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return IsOpen = false;
            }
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        public void Send()
        {

            if (SendFormat16)
            {
                byte[] bytes = CRC.StringToHexByte(SendData);
                this.SerialPort.Write(bytes, 0, bytes.Length);
                SendCount = bytes.Length; //不做增量
            }
            else
            {
                this.SerialPort.Write(SendData);
                SendCount = SendData.Length;
            }
            Messenger.Default.Send("", "PlaySendFlashing");
        }

        /// <summary>
        /// 清空接收区
        /// </summary>
        public void Clear()
        {
            this.DataReceiveInfo = string.Empty;
        }

        /// <summary>
        /// 清空发送区和缓存区
        /// </summary>
        public void ClearText()
        {
            this.SendData = string.Empty;
            this.SendCount = 0;
            this.ReceiveCount = 0;
        }

        #endregion

        /// <summary>
        /// 返回事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Messenger.Default.Send("", "PlayReciveFlashing");

            byte[] readBuffer = new byte[SerialPort.ReadBufferSize];
            SerialPort.Read(readBuffer, 0, readBuffer.Length);

            ReceiveCount = SerialPort.ReceivedBytesThreshold; //不做增量

            if (ReceiveFormat16)
            {
                //不做增量
                DataReceiveInfo = CRC.ByteToString(readBuffer, true);
            }
            else
            {
                DataReceiveInfo = Encoding.ASCII.GetString(readBuffer);
            }

        }
    }

4.核心MainViewModel类

作用: 关联首页的上下文, 通过DataContext绑定, 关联界面元素、命令等作用。

public class MainViewModel : ViewModelBase
    {
        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            ComParameterConfig = new ComParameterConfig();
            CurrentParameter = new CurrentParameter();
        }

        private ComParameterConfig comParameter;

        /// <summary>
        /// 参数类
        /// </summary>
        public ComParameterConfig ComParameterConfig
        {
            get { return comParameter; }
            set { comParameter = value; RaisePropertyChanged(); }
        }

        private CurrentParameter currentParameter;

        /// <summary>
        /// 当前配置参数
        /// </summary>
        public CurrentParameter CurrentParameter
        {
            get { return currentParameter; }
            set { currentParameter = value; RaisePropertyChanged(); }
        }

        #region Command

        private RelayCommand _ToOpen;
        public RelayCommand ToOpen
        {
            get
            {
                if (_ToOpen == null)
                {
                    _ToOpen = new RelayCommand(Open);
                }
                return _ToOpen;
            }
            set
            {
                _ToOpen = value;
            }
        }
        /// <summary>
        /// 根据配置打开端口
        /// </summary>
        public void Open()
        {
            this.CurrentParameter.Open();
        }

        private RelayCommand _ToClick;
        public RelayCommand ToClick
        {
            get
            {
                if (_ToClick == null)
                {
                    _ToClick = new RelayCommand(Click);
                }
                return _ToClick;
            }
            set
            {
                _ToClick = value;
            }
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        public void Click()
        {
            this.CurrentParameter.Send();
        }

        private RelayCommand _ToClear;

        public RelayCommand ToClear
        {
            get
            {
                if (_ToClear == null)
                {
                    _ToClear = new RelayCommand(Clear);
                }
                return _ToClear;
            }
            set
            {
                _ToClear = value;
            }
        }

        /// <summary>
        /// 清空接收区
        /// </summary>
        public void Clear()
        {
            this.CurrentParameter.Clear();
        }

        private RelayCommand _ToClearText;

        public RelayCommand ToClearText
        {
            get
            {
                if (_ToClearText == null)
                {
                    _ToClearText = new RelayCommand(ClearText);
                }
                return _ToClearText;
            }
            set
            {
                _ToClearText = value;
            }
        }

        /// <summary>
        /// 清空界面值
        /// </summary>
        public void ClearText()
        {
            this.CurrentParameter.ClearText();
        }

        #endregion
    }

5.CRC校验核心类

作用:主要实现数据校验, 含ModbusCR标准校验

/// <summary>
    /// CRC校验
    /// </summary>
    public class CRC
    {

        #region  CRC16

        public static byte[] CRC16(byte[] data)
        {
            int len = data.Length;
            if (len > 0)
            {
                ushort crc = 0xFFFF;

                for (int i = 0; i < len; i++)
                {
                    crc = (ushort)(crc ^ (data[i]));
                    for (int j = 0; j < 8; j++)
                    {
                        crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ 0xA001) : (ushort)(crc >> 1);
                    }
                }
                byte hi = (byte)((crc & 0xFF00) >> 8);  //高位置
                byte lo = (byte)(crc & 0x00FF);         //低位置

                return new byte[] { hi, lo };
            }
            return new byte[] { 0, 0 };
        }
        #endregion

        #region  ToCRC16

        public static string ToCRC16(string content)
        {
            return ToCRC16(content, Encoding.UTF8);
        }

        public static string ToCRC16(string content, bool isReverse)
        {
            return ToCRC16(content, Encoding.UTF8, isReverse);
        }

        public static string ToCRC16(string content, Encoding encoding)
        {
            return ByteToString(CRC16(encoding.GetBytes(content)), true);
        }

        public static string ToCRC16(string content, Encoding encoding, bool isReverse)
        {
            return ByteToString(CRC16(encoding.GetBytes(content)), isReverse);
        }

        public static string ToCRC16(byte[] data)
        {
            return ByteToString(CRC16(data), true);
        }

        public static string ToCRC16(byte[] data, bool isReverse)
        {
            return ByteToString(CRC16(data), isReverse);
        }
        #endregion

        #region  ToModbusCRC16

        public static string ToModbusCRC16(string s)
        {
            return ToModbusCRC16(s, true);
        }

        public static string ToModbusCRC16(string s, bool isReverse)
        {
            return ByteToString(CRC16(StringToHexByte(s)), isReverse);
        }

        public static string ToModbusCRC16(byte[] data)
        {
            return ToModbusCRC16(data, true);
        }

        public static string ToModbusCRC16(byte[] data, bool isReverse)
        {
            return ByteToString(CRC16(data), isReverse);
        }
        #endregion

        #region  ByteToString

        public static string ByteToString(byte[] arr, bool isReverse)
        {
            try
            {
                byte hi = arr[0], lo = arr[1];
                return Convert.ToString(isReverse ? hi + lo * 0x100 : hi * 0x100 + lo, 16).ToUpper().PadLeft(4, '0');
            }
            catch (Exception ex) { throw (ex); }
        }

        public static string ByteToString(byte[] arr)
        {
            try
            {
                return ByteToString(arr, true);
            }
            catch (Exception ex) { throw (ex); }
        }

        #endregion

        #region  StringToHexString

        public static string StringToHexString(string str)
        {
            StringBuilder s = new StringBuilder();
            foreach (short c in str.ToCharArray())
            {
                s.Append(c.ToString("X4"));
            }
            return s.ToString();
        }

        #endregion

        #region  StringToHexByte

        private static string ConvertChinese(string str)
        {
            StringBuilder s = new StringBuilder();
            foreach (short c in str.ToCharArray())
            {
                if (c <= 0 || c >= 127)
                {
                    s.Append(c.ToString("X4"));
                }
                else
                {
                    s.Append((char)c);
                }
            }
            return s.ToString();
        }

        private static string FilterChinese(string str)
        {
            StringBuilder s = new StringBuilder();
            foreach (short c in str.ToCharArray())
            {
                if (c > 0 && c < 127)
                {
                    s.Append((char)c);
                }
            }
            return s.ToString();
        }

        /// <summary>
        /// 字符串转16进制字符数组
        /// </summary>
        /// <param name="hex"></param>
        /// <returns></returns>
        public static byte[] StringToHexByte(string str)
        {
            return StringToHexByte(str, false);
        }

        /// <summary>
        /// 字符串转16进制字符数组
        /// </summary>
        /// <param name="str"></param>
        /// <param name="isFilterChinese">是否过滤掉中文字符</param>
        /// <returns></returns>
        public static byte[] StringToHexByte(string str, bool isFilterChinese)
        {
            string hex = isFilterChinese ? FilterChinese(str) : ConvertChinese(str);

            //清除所有空格
            hex = hex.Replace(" ", "");
            //若字符个数为奇数,补一个0
            hex += hex.Length % 2 != 0 ? "0" : "";

            byte[] result = new byte[hex.Length / 2];
            for (int i = 0, c = result.Length; i < c; i++)
            {
                result[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
            }
            return result;
        }
        #endregion

    }

WPF技术点:

1.自定义样式按钮

<Style x:Key="CommonButtonBase" TargetType="{x:Type Button}">
                <Setter Property="BorderBrush" Value="Transparent"/>
                <Setter Property="BorderThickness" Value="0"/>
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                <Setter Property="HorizontalContentAlignment" Value="Center"/>
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="Padding" Value="1"/>
                <Setter Property="Cursor" Value="Hand"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}"
                                            CornerRadius="4"
                                            BorderThickness="{TemplateBinding BorderThickness}"
                                             Background="{TemplateBinding Background}"
                                             SnapsToDevicePixels="true">
                                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                              Margin="{TemplateBinding Padding}" RecognizesAccessKey="True"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsEnabled" Value="False">
                                    <Setter Property="Background" Value="#000000"/>
                                    <Setter Property="Opacity" Value="0.1"/>
                                </Trigger>
                                <Trigger Property="IsMouseOver" Value="true">
                                    <Setter Property="Foreground" Value="#FFFF00"/>
                                </Trigger>
                                <Trigger Property="IsMouseOver" Value="false">
                                    <Setter Property="Foreground" Value="White"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

            <Style TargetType="{x:Type Button}" x:Key="Btn0093EABase" BasedOn="{StaticResource CommonButtonBase}">
                <Setter Property="Background" Value="#0093EA"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="FontSize" Value="22"/>
                <Setter Property="Height" Value="40"/>
                <Setter Property="Margin" Value="5"/>
            </Style>

2.转换器用于绑定按钮

public class FontConverters : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null && bool.TryParse(value.ToString(), out bool result))
            {
                if (result)
                {
                    return "关闭串口";
                }
            }
            return "打开串口";
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
//用于绑定UI的颜色状态显示    public class ColorConverters : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null && bool.TryParse(value.ToString(), out bool result))
            {
                if (result)
                {
                    return new SolidColorBrush((Color)System.Windows.Media.ColorConverter.ConvertFromString("#2E8B57"));
                }
            }
            return new SolidColorBrush((Color)System.Windows.Media.ColorConverter.ConvertFromString("#FF6347"));
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

3.引用字体

   <TextBlock Text="" Margin="20 5 0 5" FontFamily="pack://application:,,,/Font/#iconfont"
                                   Foreground="White" FontSize="30" VerticalAlignment="Center"/>

4.绑定命令和元素

<TextBlock Text="端     口:"  Style="{DynamicResource TxtComStyle}"/>
                        <ComboBox  Grid.Row="0" Grid.Column="2" Style="{StaticResource ComboBoxStyle}" SelectedItem="{Binding CurrentParameter.Port}"
                                  ItemsSource="{Binding ComParameterConfig.Port}"
                                   />
                        <TextBlock Text="波 特 率:" Style="{DynamicResource TxtComStyle}"/>
                        <ComboBox  Grid.Row="0" Grid.Column="2" Style="{StaticResource ComboBoxStyle}" SelectedItem="{Binding CurrentParameter.BaudRdate}"
                                   ItemsSource="{Binding ComParameterConfig.BaudRate}"
                                   />
                        <TextBlock Text="数 据 位:" Style="{DynamicResource TxtComStyle}"/>
                        <ComboBox  Grid.Row="0" Grid.Column="2" Style="{StaticResource ComboBoxStyle}"  SelectedItem="{Binding CurrentParameter.DataBit}"
                                   ItemsSource="{Binding ComParameterConfig.DataBit}"
                                   />
                        <TextBlock Text="校 验 位:" Style="{DynamicResource TxtComStyle}"/>
                        <ComboBox  Grid.Row="0" Grid.Column="2" Style="{StaticResource ComboBoxStyle}"  SelectedItem="{Binding CurrentParameter.CheckMode}"
                                   ItemsSource="{Binding ComParameterConfig.CheckMode}"
                                   />
                        <TextBlock Text="停 止 位:" Style="{DynamicResource TxtComStyle}"/>
                        <ComboBox  Grid.Row="0" Grid.Column="2" Style="{StaticResource ComboBoxStyle}"  SelectedItem="{Binding CurrentParameter.StopBit}"
                                   ItemsSource="{Binding ComParameterConfig.StopBit}"
                                   />
                        <TextBlock Text="状     态:" Style="{DynamicResource TxtComStyle}"/>
                        <TextBlock Text="" Style="{DynamicResource TxtComStyle1}"  Foreground="{Binding CurrentParameter.IsOpen,Converter={StaticResource ColorConverters}}" />

写在最后

主项目的结构图 , 如下:

到此这篇关于C#实现串口调试工具的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#串口通信模块使用方法示例

    C#串口模块的使用.使用VS .net框架下WinForm程序应用开发. C#开发的串口通信小工具. 相比于QT添加的串口类,WinForm是通过组件的形式将串口加入到程序中.. 在创建完windows窗体之后,添加组件类,就可以将串口加入到其中. 然后就需要写数据成员,初始化和方法,实现串口的读写功能. 串口类数据成员 SerialPort SComm; // 使用构造函数取串口控件 TextBox MsgRc; // 接收数据成员 //构造函数初始化 public SerialComm(Se

  • C#实现把指定数据写入串口

    public static bool WriteToSerialPort(byte[]byteArr) { SerialPort Com = newSerialPort(); try { Com.ReadTimeout = 5000; Com.WriteTimeout = 5000; Com.PortName = "Com1"; Com.BaudRate = 9600; Com.StopBits = StopBits.One; Com.Parity = Parity.None; Com

  • C#串口连接的读取和发送详解

    一.串口连接的打开与关闭 串口,即COM口,在.NET中使用 SerialPort 类进行操作.串口开启与关闭,是涉及慢速硬件的IO操作,频繁打开或关闭会影响整体处理速度,甚至导致打开或关闭串口失败.非特殊情况,串口一次性打开后,在退出程序时关闭串口即可.在打开串口前,可以设置一些常用的参数.常用的参数如下: (1)串口的接受/发送超时时间:ReadTimeout/WriteTimeout. (2)  串口的接受/发送缓存区大小:ReadBufferSize/WriteBufferSize. 具

  • C#获取串口列表实现实时监控串口

    常用的两种方法 方法一: using Microsoft.Win32; RegistryKey keyCom = Registry.LocalMachine.OpenSubKey("Hardware//DeviceMap//SerialComm"); if (keyCom != null) { string[] sSubKeys = keyCom.GetValueNames(); foreach (string sName in sSubKeys) { string sValue =

  • C# 串口接收数据中serialPort.close()死锁的实例

    最近在做一个有关高铁模拟仓显示系统的客户端程序,在这个程序中要运用串口serialPort传输数据,因为每次接收数据结束后要更新UI界面,所以就用到了的Invoke,将更新UI的程序代码封装到一个方法中,然后通过Incoke调用,程序跑起来没有任何问题,但是当你执行serialPort.close()是程序就会发生死锁,整个程序卡在那里动都动不了. 上网查了很多资料,有各种这样的说法,有的说定义一个接收数据的标志,如果在执行关闭程序是进行判断,如果数据接收完了就关闭串口,没有的话继续执行,但是经

  • C#中的串口通信SerialPort详解

    今天这篇文章带大家学习下C#中的串口通讯.在日常的开发工作中,如果工作内容是CS方向的同学应该很容易接触到串口通讯方面的业务需求.那么也就很容易想到C#中SerialPort类,它就是专门来处理串口通讯相关的. 了解什么是串口通讯 串口通讯是指外设和计算机间通过数据信号线,地线,控制线等,按位进行传输数据的一种通讯方式. 这种通讯方式使用的数据线少,在远距离通信中可以节约成本,但其传输速度比并行通讯慢. 串口是计算机上一种非常通用的设备通讯协议.大多数计算机包含两个基于RS-232的串口. 串口

  • C# 实现简易的串口监视上位机功能附源码下载

    实现上位机和下位机之间的通信,通常使用的是串口通信,接下来实现一个通过上位机和串口调试助手来完成串口通信测试. 首先创建一个WInfrom窗体应用工程文件,创建过程可参考  https://www.jb51.net/article/150973.htm 在创建好的工程下面,通过工具箱中已有的控件完成界面的搭建,如下图所示,为了方便初学者容易看懂程序,下图将控件的命名一并标注出来: 直接进入正题,将完整的工程代码黏贴出来: using System; using System.Collection

  • C#串口通信程序实例详解

    创建C#串口通信程序之命名空间 System.IO.Ports命名空间中最重用的是SerialPort 类. 创建C#串口通信程序之创建SerialPort 对象 通过创建SerialPort 对象,我们可以在程序中控制串口通信的全过程. 我们将要用到的SerialPort 类的方法: ReadLine():从输入缓冲区读一新行的值,如果没有,会返回NULLWriteLine(string):写入输出缓冲Open():打开一个新的串口连接Close():关闭 复制代码 代码如下: SerialP

  • c# 实现简单的串口通讯

    本文提供一个用C#实现串口通讯实例,亲自编写,亲测可用! 开发环境: VS2008+.net FrameWork3.5(实际上2.0应该也可以) 第一步 创建一个WinForm窗体,拉入一些界面元素 重点就是,图中用红框标出的,工具箱--组件--SerialPort,做.net串口通讯,这是必备控件 第二步 设置SerialPort控件属性 用C#向串口发送数据没什么特别的,就是调用SerialPort的Write方法往串口写数据就行 但是从串口那里接收数据的方式就比较特别了 首先,需要在代码里

  • C#串口通信实现方法

    本文实例讲述了C#串口通信实现方法.分享给大家供大家参考.具体方法如下: 通过COM1发送数据,COM2接收数据.当COM2接收完本次发送的数据后,向COM1发送信息通知COM1本次数据已发完,COM1接到通知后,再发下一段数据.这样可以确保每次发送的数据都可以被正确接收. 代码如下: 复制代码 代码如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data;

  • C#串口通讯概念及简单的实现方法

    前言 最近在研究串口通讯,其中有几个比较重要的概念,RS-232这种适配于上位机和PC端进行连接,RS-232只限于PC串口和设备间点对点的通信.它很简单的就可以进行连接,由于串口通讯是异步的,也就是说你可以同时向两端或者更多进行数据发送,它们之间的传输数据类型是byte,串口通信最重要的参数是波特率.数据位.停止位和奇偶校验.对于两个进行通信的端口,这些参数必须匹配. 听大佬说的几个关于串口通讯的术语,啥?啥,这是啥? 就让我这个"小白"给你说说:第一个波特率,这个东西在不同领域都有

  • C#串口编程实例代码

    由于工作需要,第一次接触串口编程.所以不得不在网上查阅各种编程实例.最后结合自己的理解与实践,最终有了如下代码. 本代码只经过了简单的软件测试,与简单的硬件测试. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Threading; using System.IO.Port

随机推荐