zoukankan      html  css  js  c++  java
  • Winform 串口通讯之地磅

    继上次的读卡之后,要做一个地磅的读取。

    下面是我在读卡Demo上改的读取地磅的。

    地磅是一直向串口发送数据的,所以需要截取数据来一直判断数据是否合法,然后计算出结果。

    其中遇到了一个小问题,文末有介绍。

    本人初学菜鸟,大牛们有意见欢迎评论。

      1 using System;
      2 using System.Collections.Generic;
      3 using System.ComponentModel;
      4 using System.Data;
      5 using System.Drawing;
      6 using System.Linq;
      7 using System.Text;
      8 using System.Windows.Forms;
      9 using System.IO.Ports;
     10 using System.IO;
     11 using System.Threading;
     12 
     13 namespace WindowsFormsApplicationcs
     14 {
     15     public partial class FormMain : Form
     16     {
     17         //声明端口对象
     18         SerialPort myport = null;
     19         //处理数据的数据数组
     20         byte[] buf = new byte[50];
     21         //声明委托类型
     22         public delegate void Displaydelegate(byte[] buf);
     23         //委托变量
     24         public Displaydelegate disp_delegate;
     25 
     26         public FormMain()
     27         {
     28             InitializeComponent();
     29             //安全线程外更新空间
     30             //Form.CheckForIllegalCrossThreadCalls = false;
     31         }
     32 
     33         //窗口加载
     34         private void FormMain_Load(object sender, EventArgs e)
     35         {
     36             Form.CheckForIllegalCrossThreadCalls = false;
     37             txtPort.Text = "COM3";
     38             myport = new SerialPort();
     39             disp_delegate = new Displaydelegate(DispUI);
     40         }
     41 
     42         //打开串口按钮
     43         private void button1_Click(object sender, EventArgs e)
     44         {
     45             try
     46             {
     47                 
     48                 //设置串口端口
     49                 myport.PortName = txtPort.Text.ToString();
     50                 //设置比特率
     51                 myport.BaudRate = Convert.ToInt32(cmbBaud.Text);
     52                 //设置数据位
     53                 myport.DataBits = Convert.ToInt32(cmbBits.Text);
     54                 //设置停止位
     55                 switch (cmbStopBits.SelectedIndex)
     56                 {
     57                     case 0: myport.StopBits = StopBits.None; break;
     58                     case 1: myport.StopBits = StopBits.One; break;
     59                     case 2: myport.StopBits = StopBits.OnePointFive; break;
     60                     case 3: myport.StopBits = StopBits.Two; break;
     61                 }
     62 
     63                 //设置奇偶校验位
     64                 switch (cmbParity.SelectedIndex)
     65                 {
     66                     case 0: myport.Parity = Parity.Even; break;
     67                     case 1: myport.Parity = Parity.Mark; break;
     68                     case 2: myport.Parity = Parity.None; break;
     69                     case 3: myport.Parity = Parity.Odd; break;
     70                     case 4: myport.Parity = Parity.Space; break;
     71                 }
     72 
     73                 //缓冲区只接受一个字符
     74                 myport.ReceivedBytesThreshold = 1;
     75                 //接收事件添加委托
     76                 myport.DataReceived += new SerialDataReceivedEventHandler(this.myport_DataReceived);
     77                 //打开串口
     78                 myport.Open();
     79                 if (myport.IsOpen)
     80                 {
     81                     MessageBox.Show("端口已打开");
     82                     this.tstldqzt.Text = "当前状态:端口已打开";
     83                 }
     84                 else
     85                 {
     86                     MessageBox.Show("端口未能打开!");
     87                 }
     88             }
     89             catch (Exception ex)
     90             {
     91                 MessageBox.Show("端口打开出现错误!
    " + ex.Message.ToString());
     92             }
     93         }
     94 
     95         //委托方法
     96         //接收数据
     97         private void myport_DataReceived(object sender, SerialDataReceivedEventArgs e)
     98         {
     99             Thread.Sleep(100);
    100             if (myport.BytesToRead > 0)//如果缓冲区内有数据
    101             {
    102                 myport.Read(buf, 0, 1);//从缓冲区读取数据到buf暂存数组,
    103             }
    104 
    105             if (buf[0] == 0x02)//如果开头等于2,则表明是信息开始 0x02
    106             {
    107                 try
    108                 {
    109                     while (myport.BytesToRead == 9);
    110                     myport.Read(buf, 0, 9);//从缓冲区读取一条正确数据到buf暂存数组
    111                     string s = string.Empty;
    112 
    113                     for (int i = 0; i < 9; i++)
    114                     {
    115                         s += (char)buf[i];
    116                     }
    117 
    118                     StringBuilder b = new StringBuilder("");
    119 
    120                     if (s.Substring(0, 1) == "-")
    121                         b.Append("-");
    122 
    123                     int strint = Convert.ToInt32(s.Substring(1,7));
    124                     int dianint = Convert.ToInt32(s.Substring(8,1));
    125 
    126                     switch (dianint)
    127                     {
    128                         case 1: strint = strint / 10; break;
    129                         case 2: strint = strint / 100; break;
    130                         case 3: strint = strint / 1000; break;
    131                         case 4: strint = strint / 10000; break;
    132                     }
    133                     b.Append(strint);
    134                     txtReceive.Text += "开始" + b + "结束
    ";
    135 
    136                     //this.Invoke(disp_delegate, buf);
    137                 }
    138                 finally
    139                 {
    140                     myport.DiscardInBuffer();//清空缓冲区
    141                 }
    142             }
    143         }
    144 
    145         //更新ui方法
    146         public void DispUI(byte[] buf)
    147         {
    148 
    149         }
    150       
    151 
    152         //关闭方法
    153         private void button2_Click(object sender, EventArgs e)
    154         {
    155             myport.Close();
    156             if (!myport.IsOpen)
    157             {
    158                 this.tstldqzt.Text = "当前状态:端口已关闭";
    159                 MessageBox.Show("端口已关闭");
    160             }
    161         }
    162 
    163         //清屏按钮
    164         private void button3_Click(object sender, EventArgs e)
    165         {
    166             this.txtReceive.Clear();
    167         }
    168 
    169         //菜单栏关于
    170         private void tsmiabout_Click(object sender, EventArgs e)
    171         {
    172             frmAbout frmabout = new frmAbout();
    173             frmabout.ShowDialog();
    174         }
    175 
    176         //菜单栏保存结果
    177         private void tsmisave_Click(object sender, EventArgs e)
    178         {
    179             if (this.txtReceive.Text == "")
    180             { MessageBox.Show("当前结果为空,请先测试"); }
    181             string path = Directory.GetCurrentDirectory() + "\端口测试结果.txt";
    182             File.WriteAllText(path, this.txtReceive.Text.ToString(), Encoding.ASCII); 
    183         }
    184 
    185     }
    186 }

    这里其实有个问题,就是一个窗口一般会涉及到多个串口设备的通讯,

    公司目前的需求也不例外,可以看到我使用了一个thread.sleep,

    这样虽然当时解决了问题,但是当一个窗口有多个串口通讯更新ui的时候应该会出现问题,

    但因为当时手头没有设备也没做进一步的测试,。

    因为不加这句话就会无法实时更新ui,当时打了一个多小时的短点记了好多数据,

    才确定了不是数据处理那部分的问题,思考一下原因应该是while把线程堵死了,一直在做运算。

    但是使用invoke不是新开线程委托吗?为什么也是更新不了ui。

    百度了发现如下解释

    invoke是在拥有此控件的基础窗口句柄的线程上指定指定的委托

    begininvoke是在创建此控件的基础窗口句柄的线程上异步执行指定的委托

    使用begininvoke应该就可以不干扰其他的串口通讯更新ui了



    转载请标明出处

    作者:AaXuan

    地址:http://www.cnblogs.com/Aaxuan

    知识共享许可协议

    本作品采用  知识共享署名 3.0 未本地化版本许可协议  进行许可。

  • 相关阅读:
    Fanvas是一个把swf转为html5 canvas动画的系统
    截取中文字符防止乱码
    手机号码验证--区号验证--电话号验证--分机号验证--手机号和固定电话二选一--用户名只能为汉字或者英文请--邮箱账号
    laravel5.4学习--laravel基本路由
    laravel5.4学习--laravel目录结构
    laravel5.4学习--laravel安装
    laravel数据迁移
    laravel数据迁移的时候遇到的字符串长度的问题
    TcxLookupComboBox
    Tcxgrid使用例子
  • 原文地址:https://www.cnblogs.com/Aaxuan/p/7136123.html
Copyright © 2011-2022 走看看