【C#】基础篇(3) C#实现串口助手,解决中文乱码

本文介绍了如何使用C#编写串口助手,解决串口通信中的中文乱码问题。通过编码转换函数将汉字与字节互相转换,并展示了串口助手的GUI设计及代码实现,确保在串口通信中正确显示汉字内容。同时,文章强调了理解和处理编码的重要性,特别是在与MCU通信时,设置串口编码为gb2312能有效避免乱码。
摘要由CSDN通过智能技术生成

大家好,我是皮皮猫吖!

每文一言:历尽千帆,归来仍是少年!


本篇文章:

主要是C#串口助手,解决上一篇文章中的串口乱码问题

功能一:编码转汉字,汉字转编码

功能二:C#实现串口助手【解决中文乱码问题】

正文如下:

一、编码转汉字,汉字转编码

1)串口视图化
  • 第一个文本框是:textbox1
  • 第二个文本框是:textbox2
  • 第三个文本框是:textbox4
  • 第四个文本框是:textbox3
  • 第一个按钮是:button1
  • 第二个按钮是:button2

在这里插入图片描述

2)相关代码:
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;

namespace SerialPort_6
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //汉字转换为字节
        private byte[] StringToByte(String TheString)
        {
            //原编码类型
            Encoding fromEncoding = Encoding.GetEncoding("utf-8");
            //需要转换成的编码类型
            Encoding toEcoding = Encoding.GetEncoding("gb2312");

            //把UTF-8的字符串转换成UTF-8的字节数组
            byte[] fromBytes = fromEncoding.GetBytes(TheString);

            //把UTF-8的字节数组转换成gb2312的字节数组
            byte[] toBytes = Encoding.Convert(fromEncoding,toEcoding,fromBytes);

            
            return toBytes;
        }


        //字节转换为汉字
        private string BytesToString(byte[] Bytes)
        {
            string myString;
            //gb2312类型编码
            Encoding fromEncoding = Encoding.GetEncoding("gb2312");
            //utf-8类型编码
            Encoding toEncoding = Encoding.GetEncoding("utf-8");

            //将gb2312的字节数组,转换为utf-8的字节数组
            byte[] toBytes = Encoding.Convert(fromEncoding, toEncoding, Bytes);

            //把uft-8的字节数组转换为utf-8的字符串
            myString = toEncoding.GetString(toBytes);

            return myString;
        }


        //utf-8转换成gb2312按钮
        private void button1_Click(object sender, EventArgs e)
        {
            //把输入的utf-8的内容转换成gb2312的字节数组
            byte[] stringToByte = StringToByte(textBox1.Text);

            //清空第二个文本框内容
            textBox2.Text = "";

           
            foreach(byte myByte in stringToByte)
            {
                //把十进制的数先转换为十六进制数,然后再转换为十六进制数的大写字符串
                string str = myByte.ToString("x").ToUpper();

                //如果str的长度为1,需要在前面加0x0
                //如果str的长度为2,只需要在前面加0x
                textBox2.Text += "0x" + (str.Length == 1 ? "0" + str : str) + " ";
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //存储字节
            byte[] data = new byte[textBox4.Text.Length/2];
            int i;
            try
            {
                //获取文本框中的内容
                string buffer = textBox4.Text;
                //使用空替换文本框中的0x
                buffer = buffer.Replace("0x", "");
                //使用空替换文本框中的空格
                buffer = buffer.Replace(" ", string.Empty);

                //循环遍历,把字符串转换成字节
                for(i = 0; i < buffer.Length/2; i++)
                {
                    //将字符串按照十六进制转换成整型字节
                    data[i] = Convert.ToByte(buffer.Substring(i * 2, 2), 16);

                }
                //将封装好的字节数组转换成字符串
                textBox3.Text = BytesToString(data);
            }
            catch
            {
                MessageBox.Show("数据转换错误,请重新输入...", "错误");
            }
        }
    }
}

3)效果展示:
  • 当你在第一个文本框中输入内容的话,在第二个文本框中将会转换成对应的字节文件,在第三个文本框中输入字节文件的时候,在第四个文本框中就会转成对应的汉字内容

二、C#实现串口助手【解决中文乱码问题】

1)串口视图化:【与上一篇博客完整版的串口助手很相似】

在这里插入图片描述

2)相关代码:
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;

namespace SerialPort_7
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //设置串口接收响应事件
            serialPort1.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);      //串口数据接收事件

            //设置串口编码格式为gb2312
            serialPort1.Encoding = Encoding.GetEncoding("GB2312");    
            
            //串口接收编码
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;                   //
        }

        //初始化串口下拉框
        private void Form1_Load(object sender, EventArgs e)
        {
            for (int i = 1; i < 20; i++)
            {
                comboBox1.Items.Add("COM" + i.ToString());                                        //添加串口
            }
            comboBox1.Text = "COM1";                                                              //默认选项
            comboBox2.Text = "9600";
        }

        //打开串口
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                serialPort1.PortName = comboBox1.Text;                                              //端口号
                serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);                             //波特率
                serialPort1.Open();                                                                 //打开串口
                button1.Enabled = false;
                button2.Enabled = true;
            }
            catch
            {
                MessageBox.Show("端口错误", "错误");
            }
        }

        //关闭串口
        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                serialPort1.Close();                                                            //关闭串口        
                button1.Enabled = true;
                button2.Enabled = false;
            }
            catch
            {

            }
        }

        //发送数据
        private void button3_Click(object sender, EventArgs e)
        {
            //发送数据的字节数组
            byte[] Data = new byte[1];                                                         //单字节发数据     
            if (serialPort1.IsOpen)
            {
                if (textBox2.Text != "")
                {
                    //发送数据类型为字符型
                    if (!radioButton1.Checked)
                    {
                        try
                        {
                            //向串口写入字符串数据
                            serialPort1.Write(textBox2.Text);
                            //serialPort1.WriteLine();                             //字符串写入
                        }
                        catch
                        {
                            MessageBox.Show("串口数据写入错误", "错误");
                        }
                    }
                    else                                                                    //数据模式
                    {//发送数据类型为数值类型
                        try                                                                 //如果此时用户输入字符串中含有非法字符(字母,汉字,符号等等,try,catch块可以捕捉并提示)
                        {
                            for (int i = 0; i < (textBox2.Text.Length - textBox2.Text.Length % 2) / 2; i++)//转换偶数个
                            {
                                Data[0] = Convert.ToByte(textBox2.Text.Substring(i * 2, 2), 16);           //转换
                                serialPort1.Write(Data, 0, 1);
                            }
                            if (textBox2.Text.Length % 2 != 0)
                            {
                                Data[0] = Convert.ToByte(textBox2.Text.Substring(textBox2.Text.Length - 1, 1), 16);//单独处理最后一个字符
                                serialPort1.Write(Data, 0, 1);                              //写入
                            }
                            //Data = Convert.ToByte(textBox2.Text.Substring(textBox2.Text.Length - 1, 1), 16);
                            //  }
                        }
                        catch
                        {
                            MessageBox.Show("数据转换错误,请输入数字。", "错误");
                        }
                    }
                }
            }
        }

        //接收数据中断函数
        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)             //串口接收事件
        {
            //如果是字符模式接收
            if (!radioButton4.Checked)
            {
                //直接输出字符串内容
                textBox1.AppendText(serialPort1.ReadExisting());                                //串口类会自动处理汉字,所以不需要特别转换
            }
            else
            {
                //数值方式接收
                byte[] data = new byte[serialPort1.BytesToRead];                                //定义缓冲区,因为串口事件触发时有可能收到不止一个字节
                serialPort1.Read(data, 0, data.Length);
                foreach (byte Member in data)                                                   //遍历用法
                {
                    string str = Convert.ToString(Member, 16).ToUpper();
                    textBox1.AppendText("0x" + (str.Length == 1 ? "0" + str : str) + " ");
                }
            }
        }
    }
}

3)效果展示:

① C#串口助手打开COM2串口,其他串口助手打开COM1串口,其他串口助手向COM2发送数据,C#串口助手监听到COM2中的数据,进行显示
在这里插入图片描述

② C#串口助手打开COM1串口,其他串口助手打开COM2串口,C#串口助手向COM2发送数据,其他串口助手监听到COM2中的数据,进行显示

在这里插入图片描述

4)注意:

① 需要在理解编码解码的基础之上对串口助手中的数据进行编码和解码操作

② MCU向上位机发送的数据一般是gb2312格式的数据。所以,在C#中设置串口助手的编码格式为gb2312即可


希望本篇文章对大家有所帮助,后续会继续分享C#串口助手相关知识…

如果文章内容有错误的地方,请在留言处留下你的见解,方便大家共同学习。谢谢。

作者:皮皮猫吖


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值