• C#编程之串口(一)


    这一章我们开始设计串口应用程序,对于串口的设计,之前我们有讲解过,但那时是用C++进行设计的。个人感觉C++设计起来,虽然复杂一些,但灵活性更好。特别是数据处理方面,指针的运用就发挥了很大的作用。当然这并不是说C#就不能做到这一点,下面我们就一步步和大家分享一下:

    1. New Project--WPF Application---ProjectName....创建工程
    2. UI Design窗口设计,这里我们简单实现串口配置接收功能,所以只需设计一个编辑框和一个按键即可:
       1 <Window x:Class="SearilPort.MainWindow"
       2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       4         Title="MainWindow" Height="350" Width="525">
       5     <Grid>
       6         <Button Name="myBtn" Content="Open" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="75" Click="Btn1_Click"/>
       7         <TextBox HorizontalAlignment="Left" VerticalAlignment="Top" Width="400" Height="260" Name="m_textBox1"/>
       8 
       9     </Grid>
      10 </Window>
    3. 因为C#可以直接对button类内容定义,所以我们就不用像C++那样定义两个按键,一个是Open另一个是Closed,我们只需对按键name类进行操作即可: myBtn.Content = "Closed"; 或者 myBtn.Content = "Open"; ,这样就大大减少了我们的编码时间了。
    4. 串口开启由按键操作来实现,所以我们需要添加按键点击事件处理函数 Click="Btn1_Click"/> ,当然在使用串口类之前需要使用控制串口端口的类,该类包含在命名空间  System.IO.Ports; 中,所以在使用有关串口类之前需先使用该命名空间 using System.IO.Ports; 
    5. 代码:
       1  private void Btn1_Click(object sender, RoutedEventArgs e)
       2         {
       3             try
       4             {
       5                 m_textBox1.Text = "reeivcing...
      ";
       6                 myPort.BaudRate = 9600;
       7                 myPort.DataBits = 8;
       8                 myPort.PortName = "COM1";
       9                 myPort.Open();
      10                 if (myPort.IsOpen==true)
      11                 {
      12                     myBtn.Content = "Closed";
      13                 }
      14                 myPort.DataReceived += new SerialDataReceivedEventHandler(DataReceived);
      15             }
      16             catch(Exception ex)
      17             {
      18                 myPort.Close();
      19                 myBtn.Content = "Open";
      20                 MessageBox.Show(ex.Message+"SearilPort is Closed.");
      21             }
      22         }
      View Code

       代码中 myPort.DataReceived += new SerialDataReceivedEventHandler(DataReceived); 指的是创建一个自定义的接收函数,其中 DataReceived 为自定义接收函数的名称。当然也可以直接对在数据接收类赋值自定义函数名称,即: myPort.DataReceived += DataReceived; 注意这里的运算符为+=,代表为该类创建自定义函数。对于该事件类,官方也给出了一个例程,这里供大家参考一下:

       1 using System;
       2 using System.IO.Ports;
       3 
       4 class PortDataReceived
       5 {
       6     public static void Main()
       7     {
       8         SerialPort mySerialPort = new SerialPort("COM1");
       9 
      10         mySerialPort.BaudRate = 9600;
      11         mySerialPort.Parity = Parity.None;
      12         mySerialPort.StopBits = StopBits.One;
      13         mySerialPort.DataBits = 8;
      14         mySerialPort.Handshake = Handshake.None;
      15         mySerialPort.RtsEnable = true;
      16 
      17         mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
      18 
      19         mySerialPort.Open();
      20 
      21         Console.WriteLine("Press any key to continue...");
      22         Console.WriteLine();
      23         Console.ReadKey();
      24         mySerialPort.Close();
      25     }
      26 
      27     private static void DataReceivedHandler(
      28                         object sender,
      29                         SerialDataReceivedEventArgs e)
      30     {
      31         SerialPort sp = (SerialPort)sender;
      32         string indata = sp.ReadExisting();
      33         Console.WriteLine("Data Received:");
      34         Console.Write(indata);
      35     }
      36 }
      SerialPort.DataReceived 事件

      详细参考link: https://docs.microsoft.com/zh-cn/dotnet/api/system.io.ports.serialport.datareceived?view=netframework-4.8

    6. 对于自定义接收事件处理函数,我们定义为当接收到8个字节时,将8个字节按16进制格式打印到编辑框内,代码:
       1 private void DataReceived(object sender,SerialDataReceivedEventArgs e)
       2         {
       3             try
       4             {
       5                 byte[] inbuf = new byte[8];
       6                 myPort.Read(inbuf, 0, inbuf.Length);
       7                 string str = System.Text.Encoding.Default.GetString(inbuf);
       8                 this.Dispatcher.Invoke(new Action(() =>
       9                     {
      10                         foreach (byte i in inbuf)
      11                         {
      12                             m_textBox1.Text += i.ToString("X2");
      13                         }
      14                         m_textBox1.Text += "
      ";
      15                     }));
      16             }
      17             catch(Exception ex)
      18             {
      19                 MessageBox.Show(ex.Message);
      20             }
      21         }
      DataReceived

      因为我们需要在事件线程中需要处理将字符串打印到编辑框,所以这里我们需要将此操作委托给线程处理 Dispatcher.Invoke(new Action(() =>{.....})); 

    7. 完整代码:
       1 using System;
       2 using System.Collections.Generic;
       3 using System.Linq;
       4 using System.Text;
       5 using System.Threading.Tasks;
       6 using System.Windows;
       7 using System.Windows.Controls;
       8 using System.Windows.Data;
       9 using System.Windows.Documents;
      10 using System.Windows.Input;
      11 using System.Windows.Media;
      12 using System.Windows.Media.Imaging;
      13 using System.Windows.Navigation;
      14 using System.Windows.Shapes;
      15 using System.IO.Ports;
      16 
      17 namespace SearilPort
      18 {
      19     /// <summary>
      20     /// Interaction logic for MainWindow.xaml
      21     /// </summary>
      22     public partial class MainWindow : Window
      23     {
      24         SerialPort myPort = new SerialPort();
      25         public MainWindow()
      26         {
      27             InitializeComponent();
      28         }
      29 
      30         private void Btn1_Click(object sender, RoutedEventArgs e)
      31         {
      32             try
      33             {
      34                 m_textBox1.Text = "reeivcing...
      ";
      35                 myPort.BaudRate = 9600;
      36                 myPort.DataBits = 8;
      37                 myPort.PortName = "COM1";
      38                 myPort.Open();
      39                 if (myPort.IsOpen==true)
      40                 {
      41                     myBtn.Content = "Closed";
      42                 }
      43                 myPort.DataReceived += DataReceived;
      44             }
      45             catch(Exception ex)
      46             {
      47                 myPort.Close();
      48                 myBtn.Content = "Open";
      49                 MessageBox.Show(ex.Message+"SearilPort is Closed.");
      50             }
      51         }
      52         private void DataReceived(object sender,SerialDataReceivedEventArgs e)
      53         {
      54             try
      55             {
      56                 byte[] inbuf = new byte[8];
      57                 myPort.Read(inbuf, 0, inbuf.Length);
      58                 string str = System.Text.Encoding.Default.GetString(inbuf);
      59                 this.Dispatcher.Invoke(new Action(() =>
      60                     {
      61                         foreach (byte i in inbuf)
      62                         {
      63                             m_textBox1.Text += i.ToString("X2");
      64                         }
      65                         m_textBox1.Text += "
      ";
      66                     }));
      67             }
      68             catch(Exception ex)
      69             {
      70                 MessageBox.Show(ex.Message);
      71             }
      72         }
      73     }
      74 }
      View Code

      外边设备连接:

    8. 编译运行:

    自此,我们就完成了由NXP传送的序列码经主机解码后通过串口发送到我们的应用程序单向的基本操作。

    对于发送操作我们使用的是SerialPort.Write()方法,其重载函数为:

    1.  public void Write (string str); 将指定的字符串写入串行端口;
    2.  public void Write (byte[] buffer, int offset, int count); 使用缓冲区的byte类型数据将指定数量字节写入串行端口;
    3.  public void Write (char[] buffer, int offset, int count); 使用缓冲区的char类型数据将指定数量字节写入串行端口。

    其中参数:buff为缓冲区,offset为从此次开始复制字节,count为复制字节长度。

    在接下来的章节中,我们将进一步完善该程序,实现双向通行,同时调用aes加密书法,生成我们加密后的序列号。

    End.

    谢谢.

  • 相关阅读:
    css3回顾 checkbox
    mysql在linux下的安装
    LNMP(linux+nginx+mysql+php)服务器环境配置
    linux下如何查看某软件是否已安装
    Linux查看系统信息的一些命令及查看已安装软件包的命令
    正确配置nginx和php
    服务器搭建:手把手教你配置web服务之nginx1
    搭配环境一(手动搭建,重要!!)
    安装配置nginx
    nginx配置参数中文详解
  • 原文地址:https://www.cnblogs.com/lumao1122-Milolu/p/11994578.html
Copyright © 2020-2023  润新知