首页 > 其他分享 >RS232串口专题

RS232串口专题

时间:2023-08-27 18:22:07浏览次数:43  
标签:专题 return string 16 Text System 串口 byte RS232

启动串口调试助手

项目运行截图

基础类封装

数据类型转换类

using System;
using System.Text;

namespace SerialPortHelperDemo
{
    /// <summary>
    /// 16进制使用的隔离符枚举
    /// </summary>
    public enum Enum16Hex
    {
        None,//无
        Blank,//空格
        OX,  //OX
        Ox   //Ox
    }

    /// <summary>
    /// 计算进制类助手
    /// </summary>
    public class AlgorithmHelper
    {
        #region 十进制转十六进制
        public string From10To16(int d)
        {
            string hex = "";
            if (d < 16)
            {
                hex = BeginChange(d);
            }
            else
            {
                int c;
                int s = 0;
                int n = d;
                int temp = d;
                while (n >= 16)
                {
                    s++;
                    n = n / 16;
                }
                string[] m = new string[s];
                int i = 0;
                do
                {
                    c = d / 16;
                    m[i++] = BeginChange(d % 16);//判断是否大于10,如果大于10,则转换为A~F的格式
                    d = c;
                } while (c >= 16);
                hex = BeginChange(d);
                for (int j = m.Length - 1; j >= 0; j--)
                {
                    hex += m[j];
                }
            }
            return hex;
        }
        //判断是否为10~15之间的数,如果是则进行转换
        public string BeginChange(int d)
        {
            string hex = "";
            switch (d)
            {
                case 10:
                    hex = "A";
                    break;
                case 11:
                    hex = "B";
                    break;
                case 12:
                    hex = "C";
                    break;
                case 13:
                    hex = "D";
                    break;
                case 14:
                    hex = "E";
                    break;
                case 15:
                    hex = "F";
                    break;
                default:
                    hex = d.ToString();
                    break;
            }
            return hex;
        }
        #endregion

        #region 其他函数【16进制中的隔离符处理】

        /// <summary>
        /// 把16进制隔离符转换成实际的字符串
        /// </summary>
        /// <param name="enum16">16进制隔离符枚举</param>
        /// <returns></returns>
        private string AddSplitString(Enum16Hex enum16)
        {
            switch (enum16)
            {
                case Enum16Hex.None:
                    return "";
                case Enum16Hex.Ox:
                    return "0x";
                case Enum16Hex.OX:
                    return "0X";
                case Enum16Hex.Blank:
                    return " ";
                default:
                    return "";
            }
        }
        /// <summary>
        /// 去掉16进制字符串中的隔离符【 如:" ", "0x", "0X"】
        /// </summary>
        /// <param name="inString">需要转换的字符串数据</param>
        /// <returns></returns>
        private string DeleteSplitString(string inString)
        {
            string outString = string.Empty;
            string[] delArray = { " ", "0x", "0X" };
            if (inString.Contains(" ") || inString.Contains("0x") || inString.Contains("0X"))//存在隔离符
            {
                string[] str = inString.Split(delArray,
                    System.StringSplitOptions.RemoveEmptyEntries);//以隔离符进行转换数组,去掉隔离符,去掉空格。
                for (int i = 0; i < str.Length; i++)
                {
                    outString += str[i].ToString();
                }
                return outString;
            }
            else//不存在隔离符就直接返回
            {
                return inString;
            }
        }
        #endregion

        #region 汉字、英文、纯16进制数、byte[]之间的各种转换方法

        /// <summary>
        /// 字符串转换成16进制
        /// </summary>
        /// <param name="inSting"></param>
        /// <param name="enum16"></param>
        /// <returns></returns>
        public string StringTo16(string inSting, Enum16Hex enum16)
        {
            string outString = "";
            byte[] bytes = Encoding.Default.GetBytes(inSting);
            for (int i = 0; i < bytes.Length; i++)
            {
                int strInt = Convert.ToInt16(bytes[i] - '\0');
                string s = strInt.ToString("X");
                if (s.Length == 1)
                {
                    s = "0" + s;
                }
                s = s + AddSplitString(enum16);
                outString += s;
            }
            return outString;
        }
        /// <summary>
        /// 字符串转换成byte[]
        /// </summary>
        /// <param name="inSting"></param>
        /// <returns></returns>
        public byte[] StringToBtyes(string inSting)
        {
            inSting = StringTo16(inSting, Enum16Hex.None);//把字符串转换成16进制数
            return From16ToBtyes(inSting);//把16进制数转换成byte[]
        }
        /// <summary>
        /// 把16进制字符串转换成byte[]
        /// </summary>
        /// <param name="inSting"></param>
        /// <returns></returns>
        public byte[] From16ToBtyes(string inSting)
        {
            inSting = DeleteSplitString(inSting);//去掉16进制中的隔离符
            byte[] stringByte = new byte[inSting.Length / 2];
            for (int a = 0, b = 0; a < inSting.Length; a = a + 2, b++)
            {
                try
                {
                    string str = inSting.Substring(a, 2);
                    stringByte[b] = (byte)Convert.ToInt16(str, 16);
                }
                catch (Exception ex)
                {
                    throw new Exception("输入的数据不是纯16进制数!  参考错误信息:" + ex.Message);
                }
            }
            return stringByte;
        }
        /// <summary>
        /// 把16进制字符串转换成英文数字和汉字混合格式
        /// </summary>
        /// <param name="inSting">需要转换的16进制字符串</param>
        /// <returns></returns>
        public string From16ToString(string inSting)
        {
            inSting = DeleteSplitString(inSting);
            return Encoding.Default.GetString(From16ToBtyes(inSting));
        }
        /// <summary>
        /// 把byte[]转换成String
        /// </summary>
        /// <param name="bytes">需要转换的byte[]</param>
        /// <param name="enum16">隔离符</param>
        /// <returns></returns>
        public string BytesToString(byte[] bytes, Enum16Hex enum16)
        {
            return From16ToString(BytesTo16(bytes, enum16));
        }
        /// <summary>
        /// byte[]转换成16进制字符串
        /// </summary>
        /// <param name="bytes">需要转换的byte[]</param>
        /// <param name="enum16"></param>
        /// <returns></returns>
        public string BytesTo16(byte[] bytes, Enum16Hex enum16)
        {
            string outString = "";
            for (int i = 0; i < bytes.Length; i++)
            {
                if (bytes[i].ToString("X").Length < 2)//16进制数为一位时前面填充0
                {
                    outString += "0" + bytes[i].ToString("X") + AddSplitString(enum16);//转成16进制数据
                }
                else
                {
                    outString += bytes[i].ToString("X") + AddSplitString(enum16);//转成16进制数据
                }
            }
            return outString;
        }
        /// <summary>
        /// 把byte[]直接转换成字符串,直接以2进制形式显示出来。
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public string BytesTo2String(byte[] bytes, Enum16Hex enum16)
        {
            string outString = "";
            for (int i = 0; i < bytes.Length; i++)
            {
                string tempString = Convert.ToString(bytes[i], 2);
                if (tempString.Length != 8)
                {
                    string add0 = "";
                    for (int j = 0; j < 8 - tempString.Length; j++)
                    {
                        add0 += "0";
                    }
                    outString += add0 + tempString + AddSplitString(enum16);
                }
                else
                {
                    outString += tempString + AddSplitString(enum16);
                }
            }
            return outString;
        }

        /// <summary>
        /// 把字符串传进来,输出一个byte数组【可以把此byte数组直接发送到串口中】
        /// </summary>
        /// <param name="inString">要转换的字符串</param>
        /// <param name="is16">是否已经是16进制数据,true时已经是(已经转换好的数据),false时不是(需要内部转换)</param>
        /// <returns>输出一个byte数组</returns>
        public byte[] StringToBytes(string inString, bool is16)
        {
            if (is16)
            {
                return From16ToBtyes(inString);
            }
            else
            {
                return StringToBtyes(inString);
            }
        }

        #endregion
    }
}

窗体后台代码

using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

using System.IO.Ports;


namespace SerialPortHelperDemo
{
    public partial class FrmHelper : Form
    {
        //创建串口操作助手对象
        private SerialPortHelper serialPortHelper = new SerialPortHelper();

        #region  系统初始化
        public FrmHelper()
        {
            InitializeComponent();

            //串口基本参数初始化
            this.cboBaudRrate.SelectedIndex = 5;   //波特率默认9600
            this.cboCheckBit.SelectedIndex = 0;      //校验位默认NONE
            this.cboDataBit.SelectedIndex = 2;         //数据位默认8
            this.cboStopBit.SelectedIndex = 0;         //停止位默认1

            //获取当前计算机的端口
            if (this.serialPortHelper.PortNames.Length == 0)
            {
                MessageBox.Show("当前计算机上没有找到可用的端口!", "警告信息");
                this.btnOperatePort.Enabled = false;//禁用打开端口按钮
            }
            else
            {
                //将端口添加到下拉框
                this.cboCOMList.Items.AddRange(this.serialPortHelper.PortNames);
                this.cboCOMList.SelectedIndex = 0;
            }

            //串口对象委托和串口接收数据事件关联
            this.serialPortHelper.SerialPortObject.DataReceived +=
                new SerialDataReceivedEventHandler(this.SerialPort_DataReceived);
        }

        #endregion

        #region 串口参数设置

        //波特率的设置
        private void cboBaudRrate_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.serialPortHelper.SerialPortObject.BaudRate = Convert.ToInt32(this.cboBaudRrate.Text);
        }
        //设置奇偶校验
        private void cboCheckBit_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cboCheckBit.Text == "EVEN")
                serialPortHelper.SerialPortObject.Parity = System.IO.Ports.Parity.Even;
            else if (cboCheckBit.Text == "NONE")
                serialPortHelper.SerialPortObject.Parity = System.IO.Ports.Parity.None;
            else if (cboCheckBit.Text == "0DD")
                serialPortHelper.SerialPortObject.Parity = System.IO.Ports.Parity.Odd;
        }
        //设置数据位
        private void cboDataBit_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.serialPortHelper.SerialPortObject.DataBits = Convert.ToInt32(cboDataBit.Text);
        }
        //设置停止位
        private void cboStopBit_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cboStopBit.Text == "1")
                serialPortHelper.SerialPortObject.StopBits = System.IO.Ports.StopBits.One;
            else if (cboStopBit.Text == "2")
                serialPortHelper.SerialPortObject.StopBits = System.IO.Ports.StopBits.Two;
        }

        #endregion

        #region 打开与关闭端口

        private void btnOperatePort_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.btnOperatePort.Text.Trim() == "打开端口")
                {
                    this.serialPortHelper.OpenSerialPort(this.cboCOMList.Text.Trim(), 1);
                    this.lblSerialPortStatus.Text = "端口已打开";
                    this.lblStatusShow.BackColor = Color.Green;
                    this.btnOperatePort.Text = "关闭端口";
                    this.btnOperatePort.Image = this.imageList.Images[0];
                }
                else
                {
                    this.serialPortHelper.OpenSerialPort(this.cboCOMList.Text.Trim(), 0);
                    this.lblSerialPortStatus.Text = "端口未打开";
                    this.lblStatusShow.BackColor = Color.Red;
                    this.btnOperatePort.Text = "打开端口";
                    this.btnOperatePort.Image = this.imageList.Images[1];
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("端口操作异常:" + ex.Message);
            }
        }

        #endregion

        #region 发送数据

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (this.txtSender.Text.Trim().Length == 0)
            {
                MessageBox.Show("发送内容不能为空!", "提示信息");
            }
            else
            {
                //开始发送
                SendData(this.txtSender.Text.Trim());
            }
        }

        //这个方法独立出来,是为了后面扩展自动定时发送数据的时候调用
        private void SendData(string data)
        {
            try
            {
                if (this.ckb16Send.Checked)//发送十六进制数据
                {
                    this.serialPortHelper.SendData(data, SendFormat.Hex);
                }
                else  //发送字符串
                {
                    this.serialPortHelper.SendData(data, SendFormat.String);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("发送数据出现错误:" + ex.Message, "错误提示!");
            }
        }

        #endregion

        #region 串口接收数据的事件

        /// <summary>
        /// 串口接收数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                ReceiveData(this.serialPortHelper.ReceiveData());
            }
            catch (Exception ex)
            {
                MessageBox.Show("接收数据出现错误:" + ex.Message);
            }
        }
        /// <summary>
        /// 接收数据的具体实现过程
        /// </summary>
        /// <param name="byteData"></param>
        private void ReceiveData(byte[] byteData)
        {
            string data = string.Empty;
            if (this.ckb16Receive.Checked)//十六机制接收
            {
                data = this.serialPortHelper.AlgorithmHelperObject.BytesTo16(byteData, Enum16Hex.Blank);
                //在这里编写具体的数据处理过程。。。可以保存到数据库,或其他文件...
            }
            else
            {
                data = this.serialPortHelper.AlgorithmHelperObject.BytesToString(byteData, Enum16Hex.None);
            }

            //显示到当年文本框中
            //因为接收数据的事件是一个独立显存,所有必须通过跨线程访问可视化控件的方法来完成展示
            //Invoke()方法的第一个参数必须是返回值为void的委托,第二个参数是给委托对应方法传递的参数
            this.txtReceiver.Invoke(new Action<string>(s => { this.txtReceiver.Text += "   " + s; }), data);
            //屏蔽跨线程访问可视化空间引发的异常(不建议使用这种方式)
            //  Control.CheckForIllegalCrossThreadCalls = false;
        }

        #endregion

        //请空数据按钮
        private void btnClear_Click(object sender, EventArgs e)
        {
            this.txtReceiver.Clear();
            this.txtSender.Clear();
        }
    }
}

 

标签:专题,return,string,16,Text,System,串口,byte,RS232
From: https://www.cnblogs.com/cxxtreasure/p/17660633.html

相关文章

  • 基于RS232的VGA图像显示(串口+ram)
    第40章、基于RS232的VGA图像显示(串口+ram)【实战】使用PC机通过UART串口传输图片像素数据(txt文件)给FPGA,FPGA将图片数据缓存到内部RAM中,再利用vga控制模块读取,在VGA显示器中心位置显示缓存到RAM中的图片。VGA显示模式为640x480@60;图片大小为100x100。基于RS232的VGA图......
  • 串口RS485
    第31章、串口RS485【理论】【RS485简介】1、RS-485是双向、半双工通信协议,允许多个驱动器和接收器挂接在总线上,其中每个驱动器都能够脱离总线。(RS232为双向,双工,单端传输)半双工:指数据可以在一个信号载体的两个方向上传输,但是不能同时传输。2、RS-485采用差分传输方式能......
  • 串口RS232
    第30章、串口RS232UART,通用异步收发传输器(UniversalAsynchronousReceiver/Transmitter),是一种通用的数据通信协议,也是异步串行通信口(串口)的总称,它在发送数据时将并行数据转换成串行数据来传输,在接收数据时将接收到的串行数据转换成并行数据。它包括了RS232、RS499、RS......
  • 【Ehcache技术专题】「入门到精通」带你一起从零基础进行分析和开发Ehcache框架的实战
    Ehcache的存储方式Ehcache中对于缓存的存储主要有三种方式:分别是堆内存、非堆内存和磁盘。其中非堆内存是针对于企业版Ehcache才有的功能,它可以不受JavaGC的影响,能够创建很大的缓存。堆内存(MemoryStore)我们通常所有的MemoryStore实际上就是堆内存存储。MemoryStore总是可用的,所有......
  • 【STM32】5_0_串口通信
    串口通信概述通用同步异步收发器(USARTUniversalSynchronousAsynchronousReceiver/Transmitter)能够灵活地与外部设备进行全双工数据交换,满足外部设备对工业标准NRZ异步串行数据格式的要求。USART通过小数波特率发生器提供了多种波特率。它支持同步单向通信和半双工单......
  • 《算法笔记》树与二叉树专题练习
    1、复原二叉树(由前序和中序求后序)题目描述小明在做数据结构的作业,其中一题是给你一棵二叉树的前序遍历和中序遍历结果,要求你写出这棵二叉树的后序遍历结果。输入输入包含多组测试数据。每组输入包含两个字符串,分别表示二叉树的前序遍历和中序遍历结果。每个字符串由不重复的大写......
  • STM32深入学习3:DMA,串口通信和看门狗
    DMADMA直接存储器存取,用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。DMA1有7个通道,DMA2有5个通道,还有一个仲裁器来协调各个DMA请求的优先权。DMA的作用是实现数据的直接传输,从地址到地址的数据传输。DMA传输的相关参数:源地址,目标地址,数据传输量,传输模式......
  • 【Maven技术专题】「实战开发系列」盘点Maven项目中打包需要注意到的那点事儿
    Maven是什么Maven是一个流行的Java构建工具,它提供了许多插件来帮助开发人员自动化构建和部署Java应用程序。其中一个重要的插件是Maven打包插件,它可以将Java项目打包成可执行的JAR或WAR文件。在本文中,我们将深入探讨Maven打包插件的技术细节和使用方法。Maven打包插件的作用Maven打......
  • 猜结论专题
    A-Non-AdjacentFliphttps://atcoder.jp/contests/arc156/tasks/arc156_a题意给定一个01串,每次可以把不相邻的两个字符进行翻转,问最少要操作多少次使得全部变为0,无解输出-1。分析记录\(1\)的数量为\(cnt\)。每次翻转不改变\(1\)的奇偶性,所以\(1\)的数量为奇数时无......
  • STM23学习记录2:外部中断,串口通信,定时器
    外部中断:向量表:异常+中断所有端口的PIN0对应着EXTI0中短线,PIN1对应EXTI1中断线,依次类推16个外部中断线,对应7个外部中断入口地址配置中断优先级的4位要同时完成抢占优先级和响应优先级(子优先级或副优先级)的配置:两组优先级2+2,2^2抢占,2^2响应比较常用使用NVIC_PriorityGroupCon......