C#学习之九---WinForms串口---扩展

来源:互联网 发布:ok组合三连冠数据 编辑:程序博客网 时间:2024/06/11 18:50

这部分是扩展代码的分析,分两部分的原因主要是看着乱,所以把他们分两部分,这部分里主要有定时器的应用,定时发送文本和十六进制指令,还有十进制和十六进制的转换部分,这算是一个软件的扩展,便于计算,然后就是接收数据的十六进制处理,可以选4个,可以分高低位前后,也算是扩展部分.

下面开始对这部分代码自我解析:

这部分就是接收数据的十六进制处理,一次可以选4个,可以好好揣摩下:

/// <summary>/// 数据解码/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void rtbxRecHex_MouseClick(object sender, MouseEventArgs e){    try    {        int idx = rtbxRecHex.SelectionStart / 3;        idx *= 3;        if (rtbxRecHex.Text.Length >= idx + 4 * 3)        {            rtbxRecHex.Select(idx, 4 * 3);            string SubStr = rtbxRecHex.Text.Substring(idx, 4 * 3);            lblHexData.Text = SubStr;            string[] TempStr = SubStr.Split(' ');            string[] Frm = new string[4];            if (rdBig.Checked)            {   //直接拷贝。                Array.Copy(TempStr, Frm, Frm.Length);            }            else            {   //前后交换。                Frm[0] = TempStr[3];                Frm[1] = TempStr[2];                Frm[2] = TempStr[1];                Frm[3] = TempStr[0];            }            //数据解码。            tbxByte1.Text = Convert.ToString(Convert.ToByte(Frm[0], 16), 10);            tbxByte2.Text = Convert.ToString(Convert.ToByte(Frm[1], 16), 10);            tbxByte3.Text = Convert.ToString(Convert.ToByte(Frm[2], 16), 10);            tbxByte4.Text = Convert.ToString(Convert.ToByte(Frm[3], 16), 10);            tbxUInt16L.Text = Convert.ToString(Convert.ToUInt16(Frm[0] + Frm[1], 16), 10);            tbxUInt16R.Text = Convert.ToString(Convert.ToUInt16(Frm[2] + Frm[3], 16), 10);            tbxUInt32.Text = Convert.ToString(Convert.ToUInt32(Frm[0] + Frm[1] + Frm[2] + Frm[3], 16), 10);            tbxSByte1.Text = Convert.ToString(Convert.ToSByte(Frm[0], 16), 10);            tbxSByte2.Text = Convert.ToString(Convert.ToSByte(Frm[1], 16), 10);            tbxSByte3.Text = Convert.ToString(Convert.ToSByte(Frm[2], 16), 10);            tbxSByte4.Text = Convert.ToString(Convert.ToSByte(Frm[3], 16), 10);            tbxInt16L.Text = Convert.ToString(Convert.ToInt16(Frm[0] + Frm[1], 16), 10);            tbxInt16R.Text = Convert.ToString(Convert.ToInt16(Frm[2] + Frm[3], 16), 10);            tbxInt32.Text = Convert.ToString(Convert.ToInt32(Frm[0] + Frm[1] + Frm[2] + Frm[3], 16), 10);        }        else        {            ClrEncode();        }    }    catch (Exception Err)    {        MessageBox.Show(Err.Message, "串口调试助手");    }}/// <summary>/// 高位在前private void rdBig_CheckedChanged(object sender, EventArgs e){    //重新刷新数据解码。    rtbxRecHex_MouseClick(null, null);}/// <summary>/// 低位在前private void rdLit_CheckedChanged(object sender, EventArgs e){    //重新刷新数据解码。    rtbxRecHex_MouseClick(null, null);}


这部分是自动发送文本的代码:

/// <summary>/// 自动发送文本/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void chkbxTimeStr_CheckedChanged(object sender, EventArgs e){    try    {        if (chkbxTimeStr.Checked)        {            //禁止Hex自动发送。            chkbxTimeHex.Checked = false;            int t = int.Parse(tbxTimeStr.Text);            if (t < 5)            {                t = 5;                tbxTimeStr.Text = Convert.ToString(t, 10);            }            //启动Str自动发送。            tbxTimeStr.Enabled = false;            TimeStr.Enabled = true;            TimeStr.Interval = t;            TimeStr.Start();        }        else        {            TimeStr.Stop();            TimeStr.Enabled = false;            tbxTimeStr.Enabled = true;        }    }    catch (Exception Err)    {        MessageBox.Show("定时值不正确!" + Err.Message, "串口调试助手");    }}

这部分是自动发送指令的代码:

/// <summary>/// 自动发送指令/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void chkbxTimeHex_CheckedChanged(object sender, EventArgs e){    try    {        if (chkbxTimeHex.Checked)        {            //禁止Str自动发送。            chkbxTimeStr.Checked = false;            int t = int.Parse(tbxTimeHex.Text);            if (t < 5)            {                t = 5;                tbxTimeHex.Text = Convert.ToString(t, 10);            }            //起动Hex自动发送。            tbxTimeHex.Enabled = false;            TimeHex.Enabled = true;            TimeHex.Interval = t;            TimeHex.Start();        }        else        {            TimeHex.Stop();            TimeHex.Enabled = false;            tbxTimeHex.Enabled = true;        }    }    catch (Exception Err)    {        MessageBox.Show("定时值不正确!" + Err.Message, "串口调试助手");    }}


对应的指令1-5代码:

       /// <summary>        /// 指令一        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void btnCmd1_Click(object sender, EventArgs e)        {            //发送指令            CmdClick(1);        }

这里是发送指令,含检测是否加入帧头帧尾的数据处理:

/// <summary>/// 发送指令/// </summary>/// <param name="idx"></param>private void CmdClick(int idx){   //发送指令。    try    {        //自动打开串口。        if (!serialport.IsOpen)        {            btnOpen_Click(null, null);        }        string TempStr = string.Empty;        switch (idx)        {            case 1:                TempStr = tbxCmd1.Text;                break;            case 2:                TempStr = tbxCmd2.Text;                break;            case 3:                TempStr = tbxCmd3.Text;                break;            case 4:                TempStr = tbxCmd4.Text;                break;            case 5:                TempStr = tbxCmd5.Text;                break;            default:                return;        }        TempStr = DelSpace(TempStr);        //自动添加帧头帧尾和校验        if (chkbxDefFrm.Checked)           {            //加入头。            TempStr = DelSpace(tbxStart.Text) + TempStr;                 //转换为字节数组。            //待校验的字符串长度。            int Len = TempStr.Length;                     byte[] VerBin = new byte[Len / 2];            for (int i = 0, j = 0; i < Len; i += 2, j++)            {                VerBin[j] = Convert.ToByte(TempStr.Substring(i, 2), 16);            }            //计算校验字节。            byte VerByte = 0;            if (rdXor.Checked)            {                //异或校验。                for (int i = 0; i < VerBin.Length; i++)                {                    VerByte ^= VerBin[i];                }            }            else if (rdAdd.Checked)            {                //和校验。                for (int i = 0; i < VerBin.Length; i++)                {                    VerByte += VerBin[i];                }            }            //校验字节转为HEX字符串。            string VerStr = Convert.ToString(VerByte, 16);            //合成一帧。            TempStr = TempStr + DelSpace(VerStr) + DelSpace(tbxEnd.Text);        }        //十六进制发送        SendAsHex(TempStr);    }    catch (Exception err)    {        TimeHex.Stop();        TimeHex.Enabled = false;        MessageBox.Show(err.Message, "串口调试助手");        chkbxTimeHex.Checked = false;    }}


这是检测是否加入帧头帧尾:

/// <summary>/// 使用自定义帧/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void chkbxDefFrm_CheckedChanged(object sender, EventArgs e){    if (chkbxDefFrm.Checked)    {        gpDefFrm.Enabled = true;    }    else    {        gpDefFrm.Enabled = false;    }}

这两部分是一些辅助代码:

/// <summary>/// 十六进制发送/// </summary>/// <param name="str"></param>private void SendAsHex(string str){    int Len = str.Length;    //组包发送。    byte[] send = new byte[Len / 2];    for (int i = 0, j = 0; i < Len; i += 2, j++)    {        send[j] = Convert.ToByte(str.Substring(i, 2), 16);    }    serialport.Write(send, 0, send.Length);}/// <summary>/// 清除空格/// </summary>/// <param name="str"></param>/// <returns></returns>private string DelSpace(string str){    string TempStr = string.Empty;    int Len = str.Length;    for (int i = 0; i < Len; i++)    {        if (str[i] != ' ')        {            TempStr += str[i];        }    }    //Hex 位数检查。    Len = TempStr.Length;    if (Len % 2 != 0)    {        TempStr = '0' + TempStr;    }    return TempStr;}


这里是两个时钟:

/// <summary>/// 发送指令时钟/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void TimeHex_Tick(object sender, EventArgs e){    try    {        int[] Len ={ tbxCmd1.Text.Length, tbxCmd2.Text.Length, tbxCmd3.Text.Length, tbxCmd4.Text.Length, tbxCmd5.Text.Length };        int j = 0;        int OldIdx = CmdIdx;        for (int i = OldIdx; i < OldIdx + 5; i++)        {            CmdIdx %= 5;            j = i % 5;            if (CmdIdx == j)            {                CmdIdx++;                if (Len[j] > 0)                {                    CmdClick(CmdIdx);                    return;                }            }        }    }    catch (Exception Err)    {        MessageBox.Show("定时发送错误!" + Err.Message, "串口调试助手");        chkbxTimeHex.Checked = false;    }}/// <summary>/// 发送文本时钟/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void TimeStr_Tick(object sender, EventArgs e){    try    {        btnSend_Click(null, null);    }    catch (Exception Err)    {        MessageBox.Show("定时发送错误!" + Err.Message, "串口调试助手");        chkbxTimeStr.Checked = false;    }}


这是停止自动发送的代码:

/// <summary>/// 停止自动发送/// </summary>private void StopAutoSend(){    //停止自动发送字符串。    TimeStr.Stop();    TimeStr.Enabled = false;    tbxTimeStr.Enabled = true;    chkbxTimeStr.Checked = false;    //停止自动发送指令。    TimeHex.Stop();    TimeHex.Enabled = false;    tbxTimeHex.Enabled = true;    chkbxTimeHex.Checked = false;}

这部分比较长,是数据间的转换:

/// <summary>/// 十进制转十六进制/// </summary>private void IntToHex(){    try    {        int Int = int.Parse(tbxDec.Text);        string TempStr = Convert.ToString(Int, 16);        while (TempStr.Length < 8)        {            TempStr = '0' + TempStr;        }        tbxHex.Text = TempStr.ToUpper();        tbxDec.SelectAll();    }    catch (Exception Err)    {        tbxDec.SelectAll();        MessageBox.Show(Err.Message, "串口调试助手");    }}/// <summary>/// 十六进制转十进制/// </summary>private void HexToInt(){    try    {        int Int = Convert.ToInt32(tbxHex.Text, 16);        tbxDec.Text = Int.ToString();        tbxHex.SelectAll();    }    catch (Exception Err)    {        tbxHex.SelectAll();        MessageBox.Show(Err.Message, "串口调试助手");    }}/// <summary>/// 字符串转换为byte[]/// </summary>/// <param name="hexstring"></param>/// <returns></returns>private byte[] StringToByte(string hexstring){    byte[] bytes = System.Text.Encoding.Default.GetBytes(hexstring.Trim().Replace(" ", ""));    return bytes;}/// <summary>/// byte[]转换成字符串/// </summary>/// <param name="byteArray"></param>/// <returns></returns>private string ByteToString(byte[] byteArray){    string str = System.Text.Encoding.Default.GetString(byteArray);    return str;}/// <summary>/// 字符串转十六进制字节数组/// </summary>/// <param name="hexString"></param>/// <returns></returns>private byte[] StringToHexByte(string hexString){    hexString = hexString.Replace(" ", "");    if ((hexString.Length % 2) != 0)    {        hexString += " ";    }    byte[] returnBytes = new byte[hexString.Length / 2];    for (int i = 0; i < returnBytes.Length; i++)    {        returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);    }    return returnBytes;}/// <summary>/// 字节数组转十六进制字符串/// </summary>/// <param name="bytes"></param>/// <returns></returns>public static string HexByteToString(byte[] bytes){    string returnStr = "";    if (bytes != null)    {        for (int i = 0; i < bytes.Length; i++)        {            returnStr += bytes[i].ToString("X2");        }    }    return returnStr;}/// <summary>/// 从汉字转换到十六进制/// </summary>/// <param name="s"></param>/// <param name="charset">编码,如"utf-8","gb2312"</param>/// <param name="fenge">是否每字符用逗号分隔</param>/// <returns></returns>public static string ChineseToHex(string s, string charset, bool fenge){    if ((s.Length % 2) != 0)    {        //空格        s += " ";    }    System.Text.Encoding chs = System.Text.Encoding.GetEncoding(charset);    byte[] bytes = chs.GetBytes(s);    string str = "";    for (int i = 0; i < bytes.Length; i++)    {        str += string.Format("{0:X}", bytes[i]);        if (fenge && (i != bytes.Length - 1))        {            str += string.Format("{0}", ",");        }    }    return str.ToLower();}/// <summary>/// 从十六进制转换成汉字/// </summary>/// <param name="hex"></param>/// <param name="charset">编码,如"utf-8","gb2312"</param>/// <returns></returns>public static string HexToChinese(string hex, string charset){    if (hex == null)    {        throw new ArgumentNullException("hex");    }    hex = hex.Replace(",", "");    hex = hex.Replace("\n", "");    hex = hex.Replace("\\", "");    hex = hex.Replace(" ", "");    if (hex.Length % 2 != 0)    {        //空格        hex += "20";    }    // 需要将 hex 转换成 byte 数组。     byte[] bytes = new byte[hex.Length / 2];    for (int i = 0; i < bytes.Length; i++)    {        try        {            // 每两个字符是一个 byte。             bytes[i] = byte.Parse(hex.Substring(i * 2, 2),            System.Globalization.NumberStyles.HexNumber);        }        catch        {            // Rethrow an exception with custom message.             throw new ArgumentException("hex is not a valid hex number!", "hex");        }    }    System.Text.Encoding chs = System.Text.Encoding.GetEncoding(charset);    return chs.GetString(bytes);}


这部分是10和16进制的转换,包含鼠标离开和回车处理:

/// <summary>/// 十进制/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void tbxDec_KeyPress(object sender, KeyPressEventArgs e){    //回车键    if (e.KeyChar == '\r')    {        //转换为Hex。        IntToHex();    }}/// <summary>/// 十进制/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void tbxDec_Leave(object sender, EventArgs e){    //转换为Hex。    IntToHex();}/// <summary>/// 十六进制/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void tbxHex_KeyPress(object sender, KeyPressEventArgs e){    //回车键    if (e.KeyChar == '\r')    {        while (tbxHex.Text.Length < 8)        {            tbxHex.Text = '0' + tbxHex.Text;        }        //转换为Dec。        HexToInt();    }}/// <summary>/// 十六进制/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void tbxHex_Leave(object sender, EventArgs e){    while (tbxHex.Text.Length < 8)    {        tbxHex.Text = '0' + tbxHex.Text;    }    //转换为Dec。    HexToInt();}

这部分是清除接收显示:

/// <summary>/// 清除接收/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnClrRec_Click(object sender, EventArgs e){    //清除接收    rtbxRecStr.Text = string.Empty;    rtbxRecHex.Text = string.Empty;    ClrEncode();}

代码差不多就是这些,理了理条理,接下来仔细学习这些代码.

今天就到这里,OVER!!!



原创粉丝点击