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

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

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

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

/// 
/// 数据解码
/// 
/// 
/// 
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, "串口调试助手");
    }
}

/// 
/// 高位在前

private void rdBig_CheckedChanged(object sender, EventArgs e)
{
    //重新刷新数据解码。
    rtbxRecHex_MouseClick(null, null);
}

/// 
/// 低位在前

private void rdLit_CheckedChanged(object sender, EventArgs e)
{
    //重新刷新数据解码。
    rtbxRecHex_MouseClick(null, null);
}


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

/// 
/// 自动发送文本
/// 
/// 
/// 
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, "串口调试助手");
    }
}

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

/// 
/// 自动发送指令
/// 
/// 
/// 
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代码:

       /// 
        /// 指令一
        /// 
        /// 
        /// 
        private void btnCmd1_Click(object sender, EventArgs e)
        {
            //发送指令
            CmdClick(1);
        }

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

/// 
/// 发送指令
/// 
/// 
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;
    }
}


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

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

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

/// 
/// 十六进制发送
/// 
/// 
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);
}

/// 
/// 清除空格
/// 
/// 
/// 
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;
}


这里是两个时钟:

/// 
/// 发送指令时钟
/// 
/// 
/// 
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;
    }
}

/// 
/// 发送文本时钟
/// 
/// 
/// 
private void TimeStr_Tick(object sender, EventArgs e)
{
    try
    {
        btnSend_Click(null, null);
    }
    catch (Exception Err)
    {
        MessageBox.Show("定时发送错误!" + Err.Message, "串口调试助手");
        chkbxTimeStr.Checked = false;
    }

}


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

/// 
/// 停止自动发送
/// 
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;
}

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

/// 
/// 十进制转十六进制
/// 
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, "串口调试助手");
    }
}

/// 
/// 十六进制转十进制
/// 
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, "串口调试助手");
    }
}

/// 
/// 字符串转换为byte[]
/// 
/// 
/// 
private byte[] StringToByte(string hexstring)
{
    byte[] bytes = System.Text.Encoding.Default.GetBytes(hexstring.Trim().Replace(" ", ""));
    return bytes;
}

/// 
/// byte[]转换成字符串
/// 
/// 
/// 
private string ByteToString(byte[] byteArray)
{
    string str = System.Text.Encoding.Default.GetString(byteArray);
    return str;
}

/// 
/// 字符串转十六进制字节数组
/// 
/// 
/// 
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;
}

/// 
/// 字节数组转十六进制字符串
/// 
/// 
/// 
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;
}

/// 
/// 从汉字转换到十六进制
/// 
/// 
/// 编码,如"utf-8","gb2312"
/// 是否每字符用逗号分隔
/// 
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();
}

/// 
/// 从十六进制转换成汉字
/// 
/// 
/// 编码,如"utf-8","gb2312"
/// 
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进制的转换,包含鼠标离开和回车处理:

/// 
/// 十进制
/// 
/// 
/// 
private void tbxDec_KeyPress(object sender, KeyPressEventArgs e)
{
    //回车键
    if (e.KeyChar == '\r')
    {
        //转换为Hex。
        IntToHex();
    }
}

/// 
/// 十进制
/// 
/// 
/// 
private void tbxDec_Leave(object sender, EventArgs e)
{
    //转换为Hex。
    IntToHex();
}

/// 
/// 十六进制
/// 
/// 
/// 
private void tbxHex_KeyPress(object sender, KeyPressEventArgs e)
{
    //回车键
    if (e.KeyChar == '\r')
    {
        while (tbxHex.Text.Length < 8)
        {
            tbxHex.Text = '0' + tbxHex.Text;
        }
        //转换为Dec。
        HexToInt();
    }
}

/// 
/// 十六进制
/// 
/// 
/// 
private void tbxHex_Leave(object sender, EventArgs e)
{
    while (tbxHex.Text.Length < 8)
    {
        tbxHex.Text = '0' + tbxHex.Text;
    }
    //转换为Dec。
    HexToInt();
}

这部分是清除接收显示:

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

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

今天就到这里,OVER!!!



你可能感兴趣的:(C#,学习,2010,c#,C#,串口,扩展)