在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#网络编程 → 485串口通信

485串口通信

C#网络编程

下载此实例
  • 开发语言:C#
  • 实例大小:1.96M
  • 下载次数:123
  • 浏览次数:543
  • 发布时间:2021-05-10
  • 实例类别:C#网络编程
  • 发 布 人:710327449
  • 文件格式:.zip
  • 所需积分:2
 相关标签: 串口通信 485 通信 串口

实例介绍

【实例简介】

【实例截图】

from clipboard

【核心代码】

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using Microsoft.Win32;
using System.Text.RegularExpressions;
using System.Threading;

namespace WfSerialComMater
{
    public partial class SerialComMaster : Form
    {
        SerialPort sp = new SerialPort();
        bool isOpen = false;
        bool isSetProperty = false;
        private List<byte> Recbuffer = new List<byte>();
        string StrRecData = "";

        public SerialComMaster()
        {
            InitializeComponent();
        }

        /// <summary>
        /// get com liset
        /// </summary>
        public void GetComList()
        {
            RegistryKey keyCom = Registry.LocalMachine.OpenSubKey("Hardware\\DeviceMap\\SerialComm");
            if (keyCom != null)
            {
                string[] sSubKeys = keyCom.GetValueNames();
                this.CbxComPort.Items.Clear();
                foreach (string sName in sSubKeys)
                {
                    string sValue = (string)keyCom.GetValue(sName);
                    this.CbxComPort.Items.Add(sValue);
                }
            }
        }

        private void SerialComMaster_Load(object sender, EventArgs e)
        {
            //this.MaximumSize = this.Size;
            //this.MinimumSize = this.Size;
            this.MaximizeBox  = false;

            GetComList();
            //MessageBox.Show (Convert.ToString(CbxComPort.Items.Count));
            if (CbxComPort.Items.Count != 0) CbxComPort.SelectedIndex = CbxComPort.Items.Count-1;

            lblStatus.Text = "";
            //常用波特率
            CbxBitRate.Items.Clear();
            CbxBitRate.Items.Add("4800");
            CbxBitRate.Items.Add("9600");
            CbxBitRate.Items.Add("19200");
            CbxBitRate.Items.Add("38400");
            CbxBitRate.Items.Add("57600");
            CbxBitRate.Items.Add("115200");
            CbxBitRate.SelectedIndex = 4;

            //停止位
            CbxStop.Items.Clear();
            CbxStop.Items.Add("0");
            CbxStop.Items.Add("1");
            CbxStop.Items.Add("1.5");
            CbxStop.Items.Add("2");
            CbxStop.SelectedIndex  = 1;
            //数据位
            CbxDatabits.Items.Clear();
            CbxDatabits.Items.Add("8");
            CbxDatabits.Items.Add("7");
            CbxDatabits.Items.Add("6");
            CbxDatabits.Items.Add("5");
            CbxDatabits.SelectedIndex = 0; 

            //校验
            CbxParity.Items.Clear();
            CbxParity.Items.Add("无");
            CbxParity.Items.Add("奇校验");
            CbxParity.Items.Add("偶校验");
            CbxParity.SelectedIndex = 0;

            //功能码
            CbxOrder.Items.Clear();
            CbxOrder.Items.Add("读多个寄存器");
            //CbxOrder.Items.Add("写单个寄存器");
            //CbxOrder.Items.Add("写多个寄存器");
            CbxOrder.SelectedIndex = 0;

            tbxAdr.Items.Clear();
            for (int i = 0; i < 99; i )
            {
                tbxAdr.Items.Add(string.Format("{0:X2}",i 1));
                cbxadr1.Items.Add(string.Format("{0:X2}", i));
                cbxadr2.Items.Add(string.Format("{0:X2}", i));
                cbxcount1.Items.Add(string.Format("{0:X2}", i));
                cbxcount2.Items.Add(string.Format("{0:X2}", i));
            }
            tbxAdr.SelectedIndex = 0;
            cbxadr1.SelectedIndex = 0;
            cbxadr2.SelectedIndex = 1;
            cbxcount1.SelectedIndex = 0;
            cbxcount2.SelectedIndex =1;
        }

        private bool CheckPortSetting()         
        {//检查串口是否设置              
            if (CbxComPort.Text.Trim() == "") return false;
            if (CbxBitRate.Text.Trim() == "") return false;
            if (CbxStop.Text.Trim() == "") return false;
            if (CbxParity.Text.Trim() == "") return false;
            if (CbxDatabits.Text.Trim() == "") return false;
            return true;         
        }

        private bool CheckSendData()
        {
            if (tbxSendData.Text.Trim() == "") return false;
            return true;
        }

        private void SetPortProperty()
        {   
            //sp = new SerialPort();
            sp.PortName = CbxComPort.Text.Trim();//串口名称
            sp.BaudRate = Convert.ToInt32(CbxBitRate.Text.Trim());//波特率

            //停止位
            float f = Convert.ToSingle(CbxStop.Text.Trim());
            if (f == 0)
            {
                sp.StopBits = StopBits.None;
            }
            else if (f == 1.5)
            {
                sp.StopBits = StopBits.OnePointFive;
            }
            else if (f == 1)
            {
                sp.StopBits = StopBits.One;
            }
            else
            {
                sp.StopBits = StopBits.Two;
            }

            //设置数据位
            sp.DataBits = Convert.ToInt16(CbxDatabits.Text.Trim());

            //设置奇偶
            string s = CbxParity.Text.Trim();
            if (s.CompareTo("无") == 0)
            {
                sp.Parity = Parity.None;
            }
            else if (s.CompareTo("奇校验") == 0)
            {
                sp.Parity = Parity.Odd;
            }
            else if (s.CompareTo("无") == 0)
            {
                sp.Parity = Parity.Even;
            }

            //设置超时读取时间             
            sp.ReadTimeout = -1;
            if (sp.IsOpen)
            {
                return;
            }
            //打开串口数据
            sp.DataReceived = new SerialDataReceivedEventHandler(sp_DataReceived);
            //sp = new SerialPort("COM3", 4800, Parity.None, 8, StopBits.One);
            try
            {
                sp.Open();
                lblportinfo.Text = "串口已打开";
                btOpenPort.Text = "关闭串口";

                isOpen = true;
            }
            catch (Exception)
            {
                lblportinfo.Text = "打开串口时发生错误";
            }
        }

        private void SendData()
        {
            try
            {
                //tbxRecvData.Text = "";
                DateTime dt = DateTime.Now;
                string StrSendData = tbxAdr.Text.Trim();
                string order = CbxOrder.Text.Trim();//功能
                if (order.CompareTo("读多个寄存器") == 0)
                {
                    StrSendData = StrSendData " 03";
                }
                else if (order.CompareTo("写单个寄存器") == 0)
                {
                    StrSendData = StrSendData " 06";
                }
                else if (order.CompareTo("写多个寄存器") == 0)
                {
                    StrSendData = StrSendData " 10";
                }
                StrSendData = StrSendData " " cbxadr1.Text.Trim() " " cbxadr2.Text.Trim();
                StrSendData = StrSendData " " cbxcount1.Text.Trim() " " cbxcount2.Text.Trim();

                byte[] byteChkSendData = GetStrHex(StrSendData);
                byte[] byteCRC = CRC16_C(byteChkSendData);

                byte[] byteSendData = new byte[byteChkSendData.Length 2];
                byteChkSendData.CopyTo(byteSendData,0);
                byteCRC.CopyTo(byteSendData, byteChkSendData.Length);
                //send string  05 03 00 02 00 03 a5 8f 
                //byteCRC[0].ToString("X2");

                ShowData(byteSendData, ">>", Color.RoyalBlue);
                sp.Write(byteSendData, 0, byteSendData.Length);
            }
            catch (Exception)
            {
                this.lblStatus.Text = "发送数据时发生错误!";
                return; 
            }  
        }


        private void DisPlayInfo()
        {
            string strGetData = "";
            byte[] byteRecData=new byte[Recbuffer.Count];
            for (int i = 0; i <= byteRecData.Length-1; i )
            //for (int i = 0; i <= 14; i )
            {
                byteRecData[i] = Recbuffer[i];
                //if (strGetData == "")
                //{
                //    strGetData = byteRecData[i].ToString("X2");
                //}
                //else
                //{
                //    strGetData = strGetData " " byteRecData[i].ToString("X2");
                //}
            }

            ShowData(byteRecData, "<<", Color.Black);
            //DateTime dt = DateTime.Now;
            //tbxRecvData.AppendText("\r\n" dt.ToString("HH:mm:ss:fff") " << " strGetData);
            //tbxRecvData.ScrollToCaret();
        }


        public void ShowData(byte[] data, string strDirection, Color FontColor)
        {
            string strGetData = "";
            for (int i = 0; i <= data.Length - 1; i )
            //for (int i = 0; i < 14; i )
            {
                //if (strGetData == "")
                //{
                //    strGetData = data[i].ToString("X2");
                //}
                //else
                //{
                    strGetData = strGetData " " data[i].ToString("X2");
                //}
            }
            SetText(FontColor, strGetData, strDirection);
        }


        delegate void SetTextCallback(Color fontColor, string text, string strDirection);
        public void SetText(Color FontColor, string Text, string strDirection)
        {
            DateTime dt = DateTime.Now;
            if (Text != "")
            {
                if (this.tbxRecvData.InvokeRequired)
                {
                    SetTextCallback d = new SetTextCallback(SetText);
                    this.Invoke(d, new object[] { FontColor, Text, strDirection });
                }
                else
                {
                    this.tbxRecvData.SelectionColor = FontColor;
                    //if (this.tbxRecvData.Text == "")
                    //{
                    //    this.tbxRecvData.AppendText(dt.ToString("HH:mm:ss:fff") "  ===========================");
                    //    this.tbxRecvData.AppendText(dt.ToString("\r\n" "HH:mm:ss:fff") "  " dt.ToString("yyyy-MM-dd"));
                    //    this.tbxRecvData.AppendText(dt.ToString("\r\n" "HH:mm:ss:fff") "  ===========================");
                    //}
                    this.tbxRecvData.AppendText(dt.ToString("【HH:mm:ss:fff】") " " strDirection " " Text.Trim() "\r\n");
                    this.tbxRecvData.ScrollToCaret(); //滚动条 
                }
            }
        }

        /// <summary>
        /// 显示接收的数据
        /// </summary>
        private void displayReceived()
        {
            try
            {
                if (Recbuffer != null)
                {
                    StrRecData ="";
                    //获取CRC数据区
                    byte[] byteRecData=new byte[7];
                    for (int i = 0; i <= 6; i )
                    {
                        byteRecData[i] = Recbuffer[i];
                    }
                    
                    //获取字符串
                    StringBuilder strRcv = new StringBuilder(20);
                    StringBuilder strRcv2 = new StringBuilder(20);

                    foreach (var b in Recbuffer)
                    {
                        strRcv.Append(b.ToString("X2") " ");  //16进制显示 
                        strRcv2.Append(b.ToString("X2"));  //16进制显示 
                    }

                    byte[] byteCrcData = CRC16_C(byteRecData);
                    if (Recbuffer[7] != byteCrcData[0] || Recbuffer[8] != byteCrcData[1])//CRC校验
                    {
                        StrRecData = strRcv.ToString() "CRC校验错误!";
                        return;
                    }
                    else
                    {
                        var value = strRcv2.ToString();
                        string temp = value.Substring(4, 2);
                        int length = Convert.ToInt32(temp); //获取数据长度
                        string data = value.Substring(6, length * 2); //获取数据字符
                        StrRecData = strRcv.ToString();
                        StrRecData ="\r\n" "                获取值为:" Int32.Parse(data, System.Globalization.NumberStyles.AllowHexSpecifier)/1000;
                    }
                }   
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 数据到达,串口接收
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (isOpen)
            {
                try
                {//读取串口数据
                    int length=sp.BytesToRead;
                    if (length > 13)
                    {
                        byte[] GetData = new byte[length];
                        sp.Read(GetData, 0, length);
                        sp.DiscardInBuffer();// //清空SerialPort控件的Buffer
                        Recbuffer.AddRange(GetData);
                        DisPlayInfo();
                        Recbuffer.Clear();
                        //if (Recbuffer.Count == 8)
                        //if (Recbuffer.Count > 13)
                        //{
                        //    displayReceived();
                        //

                        //if (Recbuffer.Count >6)
                        //{
                            
                        //}
                    }
                }
                catch (TimeoutException ex)
                {
                    throw ex;
                }
                catch (Exception ex)
                {
                    //throw ex;
                }
            }
            else
            {
                MessageBox.Show("串口未打开!", "错误提示");
                return;
            }
        }

        public byte[] CRC16_C(byte[] data)
        {
            byte CRC16Lo;
            byte CRC16Hi;   //CRC寄存器 
            byte CL; byte CH;       //多项式码&HA001 
            byte SaveHi; byte SaveLo;
            byte[] tmpData;
            int Flag;

            CRC16Lo = 0xFF;
            CRC16Hi = 0xFF;
            CL = 0x01;
            CH = 0xA0;
            tmpData = data;
            for (int i = 0; i < tmpData.Length; i )
            {
                CRC16Lo = (byte)(CRC16Lo ^ tmpData[i]); //每一个数据与CRC寄存器进行异或 
                for (Flag = 0; Flag <= 7; Flag )
                {
                    SaveHi = CRC16Hi;
                    SaveLo = CRC16Lo;
                    CRC16Hi = (byte)(CRC16Hi >> 1);      //高位右移一位 
                    CRC16Lo = (byte)(CRC16Lo >> 1);      //低位右移一位 
                    if ((SaveHi & 0x01) == 0x01) //如果高位字节最后一位为1 
                    {
                        CRC16Lo = (byte)(CRC16Lo | 0x80);   //则低位字节右移后前面补1 
                    }             //否则自动补0 
                    if ((SaveLo & 0x01) == 0x01) //如果LSB为1,则与多项式码进行异或 
                    {
                        CRC16Hi = (byte)(CRC16Hi ^ CH);
                        CRC16Lo = (byte)(CRC16Lo ^ CL);
                    }
                }
            }
            byte[] ReturnData = new byte[2];
            ReturnData[1] = CRC16Hi;       //CRC高位 
            ReturnData[0] = CRC16Lo;       //CRC低位 
            return ReturnData;
        }
    

        /// <summary>
        /// 字符串转字节数组
        /// </summary>
        /// <param name="Cache">要转换的字符串</param>
        /// <returns></returns>
        public byte[] GetStrHex(String Cache) 
        {
            string[] temp = Cache.Split(' ');
            int len = temp.Length;
            byte[] buffer=new byte[len];

            for (int i = 0; i < len; i )
            {
                buffer[i] = Convert.ToByte(temp[i], 16);
            }
            return buffer;
        }

        /// <summary>
        /// 字节数组转字符串
        /// </summary>
        /// <param name="buffer">字节数组</param>
        /// <param name="Count">数组长度</param>
        /// <returns></returns>
        public string  GetHexStr(byte[] buffer)
        {
            string sb = "";
            string strdata = "";
            for (int i = 0; i < buffer.Length ; i )
            {
                strdata = Convert.ToString(buffer[i], 16);
                if (strdata.Length==1)  strdata="0" strdata;
                //strdata =string.Format("{0:X00}", Convert.ToInt16(buffer[i]),16);
                sb = sb strdata " ";
            }
            return sb.Trim();
        }

        /// <summary>
        /// timer1 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            DateTime dt = DateTime.Now;
            if (StrRecData!="")
            {

                tbxRecvData.AppendText("\r\n" dt.ToString("HH:mm:ss:fff") " << " StrRecData.Trim());
                //tbxRecvData.Text = "\r\n" dt.ToString("HH:mm:ss:fff") " << " StrRecData.Trim();
                tbxRecvData.ScrollToCaret();//滚动条
                StrRecData = "";
            }
        }

        /// <summary>
        /// SendData
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btSendData_Click(object sender, EventArgs e)
        {
            //Send Data

            //if (!CheckSendData())
            //{
            //    MessageBox.Show("请输入要发送的数据!", "错误提示");
            //    return;
            //}

            if (isOpen)
            {//写串口数据   
                if (Recbuffer != null) Recbuffer.Clear();// 清空缓存
                SendData();
            }
            else 
            {
                MessageBox.Show("串口未打开!", "错误提示");
                return;
            }
            tbxSendData.Text = ""; 
        }

        private void btOpenPort_Click(object sender, EventArgs e)
        {
            if (sp.IsOpen)
            {
                btOpenPort.Text = "打开串口";
                lblportinfo.Text = "串口未打开";
                isSetProperty = false;
                sp.Close();
            }
            else
            {
                if (!CheckPortSetting())
                {
                    MessageBox.Show("串口未设置!", "错误提示");
                    return;
                }

                if (!isSetProperty)
                {
                    SetPortProperty();
                    isSetProperty = true;
                }
            }
        }

        private void lblAdr_Click(object sender, EventArgs e)
        {
            
        }

    }
}


网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警