C#winform上位机开发学习笔记1-串口助手的ModbusCRC功能

1.首先自定义CRC校验函数

private UInt16 Crc_Check(byte[] Data, byte DataLEN)
        {
            UInt16 CRC = 0xFFFF;

            for (byte i = 0; i < DataLEN; i++)
            { 
                CRC ^= Data[i];
                for(byte j = 0; j < 8; j++)
                {
                    if((CRC & 0x0001) == 0x0001)
                    {
                        CRC = (UInt16)((CRC >> 1) ^ 0xA001);
                    }
                    else
                    {
                        CRC = (UInt16)(CRC >> 1);
                    }
                }
            }
            CRC = (UInt16)((CRC >> 8) + (CRC<<8));
            return CRC;
        }

2.在HEX发送函数中增加CRC缓存数组变量声明

byte[] Calculate_CRC = new byte[(Buf.Length - Buf.Length % 2) / 2];//CRC缓存区
               
Calculate_CRC[i] = data[0];//CRC参数赋值
                
                 //发送CRC
                if (checkBox25.Checked)
                {
                    UInt32 CRC = Crc_Check(Calculate_CRC, (byte)Calculate_CRC.Length);//crc计算
                    byte CRC_H = (byte)(CRC >> 8);
                    byte CRC_L = (byte)CRC;

                    try
                    {
                        data[0] = CRC_L;
                        serialPort1.Write(data, 0, 1);//发送低位
                        data[0] = CRC_H;
                        serialPort1.Write(data, 0, 1);//发送高位
                    }
                    catch
                    {
                        textBox1.AppendText("\r\n串口数据发送错误!\r\n");
                        //textBox5.Text = "";//若出现错误不清空发送框的内容
                        //串口按钮显示为关闭
                        serialPort1.Close();
                        button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                        button2.Tag = "OFF";
                    }
                }

3.完整串口发送代码

 //串口发送按钮
        private void button29_Click(object sender, EventArgs e)
        {
            byte[] data = new byte[1];//发送函数需要定义数组首地址
            //发送格式为ASCII
            if (!checkBox24.Checked)//复用框没有被选择时
            {
                try
                {
                    //遍历用法
                    foreach (byte Member in textBox5.Text)//循环函数
                    {
                        data[0] = Member;
                        serialPort1.Write(data, 0, 1);//单字节发送
                    }
                    //发送回车换行
                    if (checkBox26.Checked)//发空复选框
                    {
                        data[0] = 0x0D;//发送回车
                        serialPort1.Write(data, 0, 1);
                        data[0] = 0x0A;//发送换行
                        serialPort1.Write(data, 0, 1);
                    }
                }
                catch
                {
                    textBox1.AppendText("\r\n串口数据发送错误!\r\n");
                    //textBox5.Text = "";//若出现错误不清空发送框的内容

                    //串口按钮显示为关闭
                    serialPort1.Close();
                    button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                    button2.Tag = "OFF";
                }
            }
            //发送格式为HEX
            else
            {
                //处理字符串
                string Buf = textBox5.Text;
                Buf = Buf.Replace("0x", string.Empty);//将buf中的0x替换为空格,消除0x的不规范书写方式
                Buf = Buf.Replace("0X", string.Empty);
                Buf = Buf.Replace(" ", string.Empty);
                byte[] Calculate_CRC = new byte[(Buf.Length - Buf.Length % 2) / 2];//CRC缓存区

                textBox5.Text = " ";
                //循环发送
                for (int i = 0; i < (Buf.Length - Buf.Length % 2) / 2; i++)//取余运算作用是防止用户输入的字符为奇数个
                {

                    textBox5.AppendText(Buf.Substring(i * 2, 2) + " ");//Buf.Substring为Buf的子字符串,长度为2
                    try
                    {
                            data[0] = Convert.ToByte(Buf.Substring(i*2,2),16);//将字符串转换为十六进制的整型
                            serialPort1.Write(data, 0, 1);//单字节发送
                            Calculate_CRC[i] = data[0];//CRC参数赋值
                    }
                    catch
                    {
                        textBox1.AppendText("\r\n串口数据发送错误!\r\n");
                        //textBox5.Text = "";//若出现错误不清空发送框的内容
                        //串口按钮显示为关闭
                        serialPort1.Close();
                        button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                        button2.Tag = "OFF";
                    }
                }
                //发送CRC
                if (checkBox25.Checked)
                {
                    UInt32 CRC = Crc_Check(Calculate_CRC, (byte)Calculate_CRC.Length);//crc计算
                    byte CRC_H = (byte)(CRC >> 8);
                    byte CRC_L = (byte)CRC;

                    try
                    {
                        data[0] = CRC_L;
                        serialPort1.Write(data, 0, 1);//发送低位
                        data[0] = CRC_H;
                        serialPort1.Write(data, 0, 1);//发送高位
                    }
                    catch
                    {
                        textBox1.AppendText("\r\n串口数据发送错误!\r\n");
                        //textBox5.Text = "";//若出现错误不清空发送框的内容
                        //串口按钮显示为关闭
                        serialPort1.Close();
                        button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                        button2.Tag = "OFF";
                    }
                }
            }
            //发送完清空
            if (checkBox23.Checked)//发空复选框
            {
                textBox5.Text = "";
            }
        }

4.结果测试

自定义的串口助手与SSCOM互为通信,发送相同十六进制数据情况下,查看两者CRC校验码是否相同,相同说明CRC校验成功

C#winform上位机开发学习笔记1-串口助手的ModbusCRC功能_第1张图片

你可能感兴趣的:(学习,笔记,C#,winform,嵌入式,上位机)