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

论坛 期权论坛 脚本     
niminba   2021-5-23 05:08   2229   0

  实现上位机和下位机之间的通信,通常使用的是串口通信,接下来实现一个通过上位机和串口调试助手来完成串口通信测试。

  首先创建一个WInfrom窗体应用工程文件,创建过程可参考  https://www.jb51.net/article/150973.htm

  在创建好的工程下面,通过工具箱中已有的控件完成界面的搭建,如下图所示,为了方便初学者容易看懂程序,下图将控件的命名一并标注出来:

  直接进入正题,将完整的工程代码黏贴出来:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Diagnostics;

namespace Tem_Hum_Monitorring
{

 public partial class Form1 : Form
 {
 //实例化串口
 SerialPort s = new SerialPort();

 public Form1()
 {
  InitializeComponent();
  Control.CheckForIllegalCrossThreadCalls = false;
  button1.Text = "打开串口";
  int[] item = { 9600,115200}; //遍历
  foreach (int a in item)
  {
  comboBox2.Items.Add(a.ToString());
  }
  comboBox2.SelectedItem = comboBox2.Items[1];
 }

 private void Form1_Load(object sender, EventArgs e)
 {
  portInit();
 }

 /// <summary>
 /// 串口初始化
 /// </summary>
 private void portInit()
 {
  string[] ports = SerialPort.GetPortNames();
  comboBox1.Items.AddRange(ports);
  comboBox1.SelectedItem = comboBox1.Items[0];
 }

 #region 开关串口
 private void button1_Click(object sender, EventArgs e)
 {
  try
  {
  if (!s.IsOpen)
  {
   s.PortName = comboBox1.SelectedItem.ToString();
   s.BaudRate = Convert.ToInt32(comboBox2.SelectedItem.ToString());
   s.Open();
   s.DataReceived += s_DataReceived; //"+="代表指定响应事件时要调用的方法
   button1.Text = "关闭串口";
  }
  else
  {
   s.Close();
   s.DataReceived -= s_DataReceived;
   button1.Text = "打开串口";
  }
  }
  catch(Exception ee)
  {
  MessageBox.Show(ee.ToString());
  }
 }
 #endregion

 #region 串口接收
 void s_DataReceived(object sender, SerialDataReceivedEventArgs e)
 {
  int count = s.BytesToRead;
  string str = null;
  if (count == 8)
  {
  //数据解析
  byte[] buff = new byte[count];
  s.Read(buff, 0, count);
  foreach (byte item in buff)
  {
   str += item.ToString("X2") + " ";
  }
  richTextBox1.Text = "[" + System.DateTime.Now.ToString() + "] " + str + "\n" + richTextBox1.Text;
  if (buff[0] == 0x04)
  {
   ID.Text = buff[0].ToString();
   switch (buff[2])
   {
   case 0x01:
    {
    Tem.Text = (buff[5] * 4 + buff[4] * 0.05 - 30).ToString();
    Hum.Text = (buff[6] + buff[7]).ToString();
    break;
    }
   case 0x02:
    {
    Light.Text = (buff[6] + buff[7]).ToString();
    break;
    }
   case 0x04:
    {
    Dust.Text = (buff[6] + buff[7]).ToString();
    break;
    }
   default:
    break;
   }
  }
  }
  else
  {
  //当接收数据不在设定的数据位范围之内时,会出现接受到的数据一直保存在接收缓存区之内,后续每次接手数据都会将上一次的数据进行叠加,造成只能通过关闭串口的方法来清除缓冲区的数据
  s.DiscardInBuffer(); //丢弃来自串行驱动程序的接收缓冲区的数据
  }
 }
 #endregion

 #region 串口发送
 private void button3_Click(object sender, EventArgs e)
 {
  string[] sendbuff = richTextBox2.Text.Split();
  Debug.WriteLine("发送字节数:" + sendbuff.Length);
  foreach (string item in sendbuff)
  {
  int count = 1;
  byte[] buff = new byte[count];
  buff[0] = byte.Parse(item, System.Globalization.NumberStyles.HexNumber);
  s.Write(buff,0,count);
  }
 }
 #endregion

 private void button2_Click(object sender, EventArgs e)
 {
  int count = 1;
  byte[] buff = new byte[count];
  buff[0] = byte.Parse("04", System.Globalization.NumberStyles.HexNumber);
  s.Write(buff, 0, count);
 }
 }
}

  在Winfrom窗体设计中,实现串口可以通过工具箱中的串口控件来实现,不过一般推荐直接通过代码来实例化串口,实例化串口需使用如下代码来实现:

 //实例化串口
    SerialPort s = new SerialPort();

  串口初始化可以在窗体的Load函数中实现,以下初始化可以自动化取当前设备中的存在的串口,包括真实串口和虚拟串口:

private void Form1_Load(object sender, EventArgs e)
 {
  portInit();
 }

 /// <summary>
 /// 串口初始化
 /// </summary>
 private void portInit()
 {
  string[] ports = SerialPort.GetPortNames();
  comboBox1.Items.AddRange(ports);
  comboBox1.SelectedItem = comboBox1.Items[0];
 }

  通过对开关按键button1控件的点击事件,实现串口的开关,通过对控件的文字修改,可以实现一个控件机能实现开ZIiJ

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP