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

using System.Configuration;
using System.Collections;
using System.IO.Ports;
using ShowforAW60ByCharp.Data;                                                           //工程数据区

using My.SerialPort;                                                                     //自定义的串口助手类  
using My.Utils;                                                                          //自定义工具类

using System.Drawing.Drawing2D;                                                          //绘图
using System.IO;


namespace ShowforAW60ByCharp
{
    public partial class StartShow : Form
    {
        /* 头部定义区 */

        public int                RunningFlag                     = 0;                   //指示控件，或者某个动作是否已经打开，用于执行换相反功能
        public byte[]             CommandBytes;                                          //用于存放命令字节，7个元素的一个数组
        public byte[]             ReceiveDataArray;                                      //临时用于接收数据的数组，byte型
        public long               TimerCountNum                   = 0;                   //用于存放定时器模块，两个时间的计数差
 

        delegate void delegateForKeyBoardShow(string str);                               //委托,为键盘演示而设。用于接收到的数据反馈给界面
        delegate void delegateForTimerCounting();                                        //委托，为定时器计数时间进行更新时间

        SerialPort SpPCorMCU = new SerialPort();                                         //首先定义一个串口通讯通道
                                                                                         //定义键盘"数组"，带有索引器功能，可以用字符索引.
        KeyBoard KeyToASCII = new KeyBoard();                                            //keyToASCII["055"] = "7";具体初始化在键盘操作区

        #region 索引器的创建与使用，为了键盘查找方便而设。这样可以直接通过ASCII码索取键名。"055"=="7"

        ///-------------------------------------------------------------------------
        /// <summary>
        /// 索引器接口类，用来定义 索引键，和值。有点类似于结构体的感觉。位KeyBoard
        /// 类调用。
        /// </summary>
        ///-------------------------------------------------------------------------
        class IndexClass
        {
            private string _ascii;                                                       //索引键，可以是不同类型的，字符索引
            private int _z;                                                              //数字索引
            private string _keyvalue;                                                    //对应索引键的值

            public IndexClass(string ascii, string key)
            {
                this._ascii = ascii;
                this._keyvalue = key;
            }

            public string ASCIIValue
            {
                get { return _ascii; }
                set { this._ascii = value; }
            }

            public string KEYValue
            {
                get { return _keyvalue; }
                set { this._keyvalue = value; }
            }

        }

        ///-------------------------------------------------------------------------
        /// <summary>
        /// 索引器实例化类。在MAIN函数中实例化此类，进行索引的构建，插入，查询
        /// </summary>
        ///-------------------------------------------------------------------------
        class KeyBoard
        {
            private ArrayList arr;
            public KeyBoard()
            {
                arr = new ArrayList();
            }

            public string this[string index]                                             //索引器
            {
                get
                {
                    foreach (IndexClass a in arr)
                    {
                        if (a.ASCIIValue == index)
                        {
                            return a.KEYValue;
                        }
                    }
                    return null;
                }
                set
                {
                    arr.Add(new IndexClass(index, value));
                }
            }
        }

        #endregion


        /* end 头部定义区 */

        public StartShow()
        {
            InitializeComponent();

            this.timer.Interval = 1000;                                                  //为定时器而设
            this.timer.Start();
        }


        #region Gloable Tips.为控件加入提示Tips帮助信息


        private void button_show_MouseHover(object sender, EventArgs e)
        {
            HelperUtils.ShowTips(sender, ConfigurationManager.AppSettings["TipTitle"], ConfigurationManager.AppSettings["Tip_button_show"]);
        }

        private void button_test_MouseHover(object sender, EventArgs e)
        {
            HelperUtils.ShowTips(sender, ConfigurationManager.AppSettings["TipTitle"], ConfigurationManager.AppSettings["Tip_button_test"]);
        }

        private void button_select_MouseHover(object sender, EventArgs e)
        {
            HelperUtils.ShowTips(sender, ConfigurationManager.AppSettings["TipTitle"], ConfigurationManager.AppSettings["Tip_button_select"]);
        }

        private void button_changeskin_MouseHover(object sender, EventArgs e)
        {
            HelperUtils.ShowTips(sender, ConfigurationManager.AppSettings["TipTitle"], ConfigurationManager.AppSettings["Tip_button_changeskin"]);
        }

        #region tabPage1 Tips --- 快关控制类
        private void pictureBox_shutdown_MouseHover(object sender, EventArgs e)
        {
            HelperUtils.ShowTips(sender, ConfigurationManager.AppSettings["TipTitle"], ConfigurationManager.AppSettings["Tip_pictureBox_shutdown"]);
        }

        private void pictureBox_open_MouseHover(object sender, EventArgs e)
        {
            HelperUtils.ShowTips(sender, ConfigurationManager.AppSettings["TipTitle"], ConfigurationManager.AppSettings["Tip_pictureBox_open"]);
        }

        private void pictureBox_change_MouseHover(object sender, EventArgs e)
        {
            HelperUtils.ShowTips(sender, ConfigurationManager.AppSettings["TipTitle"], ConfigurationManager.AppSettings["Tip_pictureBox_change"]);
        }

        private void pictureBox_led_MouseHover(object sender, EventArgs e)
        {
            if (RunningFlag == 0)
            {
                HelperUtils.ShowTips(sender, ConfigurationManager.AppSettings["TipTitle"], ConfigurationManager.AppSettings["Tip_pictureBox_led_start"]);
            }
            else
            {
                HelperUtils.ShowTips(sender, ConfigurationManager.AppSettings["TipTitle"], ConfigurationManager.AppSettings["Tip_pictureBox_led_stop"]);
            }
        }
        #endregion end tabPage1 Tips

        #region tabPage2 Tips --- 仿真键盘
        private void button_curPressedKeyBoardValue_MouseHover(object sender, EventArgs e)
        {
            HelperUtils.ShowTips(sender, ConfigurationManager.AppSettings["TipTitle"], ConfigurationManager.AppSettings["Tip_button_curPressedKeyBoardValue"]);
        }

        private void pictureBox_keyboard_listen_MouseHover(object sender, EventArgs e)
        {
            if (RunningFlag == 0)
            {
                HelperUtils.ShowTips(sender, ConfigurationManager.AppSettings["TipTitle"], ConfigurationManager.AppSettings["Tip_pictureBox_keyboard_listen_start"]);
            }
            else
            {
                HelperUtils.ShowTips(sender, ConfigurationManager.AppSettings["TipTitle"], ConfigurationManager.AppSettings["Tip_pictureBox_keyboard_listen_stop"]);
            }
        }
        #endregion end tabPage2 Tips



        #endregion end Global Tips


        #region 主要按钮操作 --- 测试，查询，换肤

        ///------------------------------------------------------------------------------
        /// <summary>
        /// 弹出测试窗体，主要测试mcu到PC机的通讯是否正常.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ///------------------------------------------------------------------------------
        private void button_test_Click(object sender, EventArgs e)
        {
            MCUtoPCTest mtp = new MCUtoPCTest();                                         //打开测试窗口
            mtp.Show();
        }

        ///------------------------------------------------------------------------------
        /// <summary>
        /// 弹出当前PC，MCU的相关配置信息。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ///------------------------------------------------------------------------------
        private void button_select_Click(object sender, EventArgs e)
        {
            SelectInfoShow sis = new SelectInfoShow();                                   //打开查询窗口
            sis.Show();
        }


        #region 皮肤操作，包括显示皮肤列表，以及换皮肤
        ///------------------------------------------------------------------------------
        /// <summary>
        /// 显示皮肤列表,利用RunningFlag标志
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ///------------------------------------------------------------------------------
        private void button_changeskin_Click(object sender, EventArgs e)
        {
            if (RunningFlag == 0)
            {
                this.panel_pifus.Visible = true;                                         //显示皮肤列表
                RunningFlag = 1;                                                         //置运行标志
            }
            else
            {
                this.panel_pifus.Visible = false;                                        //隐藏皮肤列表
                RunningFlag = 0;
            }
        }

        private void pictureBox_pifu_default_Click(object sender, EventArgs e)
        {
            //换皮肤
            this.SkinChange.SkinFile = "pf\\MSN.ssk";
        }

        private void pictureBox_fifu_realplayer_Click(object sender, EventArgs e)
        {
            //换皮肤
            this.SkinChange.SkinFile = "pf\\RealOne.ssk";
        }

        private void pictureBox_pf_jingying_Click(object sender, EventArgs e)
        {
            //换皮肤
            this.SkinChange.SkinFile = "pf\\MP10.ssk";
        }

        private void pictureBox_pf_mac_Click(object sender, EventArgs e)
        {
            //换皮肤
            this.SkinChange.SkinFile = "pf\\MacOS.ssk";
        }

        private void pictureBox_pf_feicuigreen_Click(object sender, EventArgs e)
        {
            //换皮肤
            this.SkinChange.SkinFile = "pf\\DiamondGreen.ssk";
        }
        #endregion

        #endregion end 主要按钮操作


        #region TabPage 开关控制操作
        ///------------------------------------------------------------------------------
        /// <summary>
        /// 小灯控制操作块。打开，关闭，交替。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ///------------------------------------------------------------------------------
        private void pictureBox_shutdown_DoubleClick(object sender, EventArgs e)
        {
            StopInOrderToRestart();                                                      //重新准备开始

                                                                                         //双击，关闭小灯
            if (OpenSCIport(SpPCorMCU))                                                  //打开串口
            {
                CommandBytes = MakeCommandBytes( DefinedTypeData.CODE_SUCCESSED,         //构造命令
                                                 DefinedTypeData.CODE_FAILED,
                                                 DefinedTypeData.CODE_LIGHT_SHUTDOWN);
                HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                          //发送命令

                HelperUtils.Delay(5000);                                                 //延时5000，等待回应信息，测试无问题

                if (HelperSCI.SCIReceiveData(SpPCorMCU, ref ReceiveDataArray))           //接收数据
                {
                                                                                         //识别看看是否是关灯命令
                    if (GetCommandByte(ReceiveDataArray).Equals(DefinedTypeData.CODE_LIGHT_SHUTDOWN))
                    {                                                                    //识别成功，将模拟灯关闭
                        this.pictureBox_light_state.Image = Properties.Resources.light_an;
                        this.state_show_all.Text = "关灯成功... ...";
                    }
                    else
                    {
                                                                                         //关灯失败，状态栏显示信息
                        this.state_show_all.Text = "关灯失败，请重新操作！";
                    }
                }
                CloseSCIport(SpPCorMCU);
            }
            else
            {
                                                                                         //打开串口失败，显示失败信息
                this.state_show_all.Text = "打开串口失败，可能被占用，请重新尝试！";
                                                                                         //发出警报声音
                HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
            }
            
        }
        private void pictureBox_open_DoubleClick(object sender, EventArgs e)
        {
            StopInOrderToRestart();                                                      //重新准备开始
                                                                                         //双击，打开小灯
            if (OpenSCIport(SpPCorMCU))                                                  //打开串口
            {
                CommandBytes = MakeCommandBytes( DefinedTypeData.CODE_SUCCESSED,         //构造命令
                                                 DefinedTypeData.CODE_FAILED,
                                                 DefinedTypeData.CODE_LIGHT_OPEN);
                HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                          //发送命令


                HelperUtils.Delay(5000);                                                 //延时5000，等待回应信息测试无问题

                if( HelperSCI.SCIReceiveData(SpPCorMCU, ref ReceiveDataArray) )          //接收数据
                {
                                                                                         //识别看看是否是开灯命令
                    if (GetCommandByte(ReceiveDataArray).Equals(DefinedTypeData.CODE_LIGHT_OPEN))
                    {                                                                    //识别成功，将模拟灯打开
                        this.pictureBox_light_state.Image = Properties.Resources.light_liang;
                        this.state_show_all.Text = "开灯成功... ...";
                    }
                    else
                    {
                                                                                         //开灯失败，状态栏显示信息
                        this.state_show_all.Text = "开灯失败，请重新操作！";
                    }
                }
                CloseSCIport(SpPCorMCU);
            }
            else
            {
                                                                                         //打开串口失败，显示失败信息
                this.state_show_all.Text = "打开串口失败，可能被占用，请重新尝试！";
                                                                                         //发出警报声音
                HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
            }
            
        }
        private void pictureBox_change_DoubleClick(object sender, EventArgs e)           //底端是一个死循环，只有发送停止指令，其他界面才能操作
        {
            StopInOrderToRestart();                                                      //重新准备开始
                                                                                         //双击，小灯闪烁
            if (OpenSCIport(SpPCorMCU))                                                  //打开串口
            {
                CommandBytes = MakeCommandBytes( DefinedTypeData.CODE_SUCCESSED,          //构造命令
                                                 DefinedTypeData.CODE_FAILED,
                                                 DefinedTypeData.CODE_LIGHT_CHANGE);
                HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                          //发送命令

                HelperUtils.Delay(5000);                                                 //延时5000，等待回应信息，测试无问题

                if (HelperSCI.SCIReceiveData(SpPCorMCU, ref ReceiveDataArray))           //接收数据
                {
                                                                                         //识别看看是否是关灯命令
                    if (GetCommandByte(ReceiveDataArray).Equals(DefinedTypeData.CODE_LIGHT_CHANGE))
                    {                                                                    //识别成功，将模拟灯闪烁
                        this.pictureBox_light_state.Image = Properties.Resources.light_chang;
                        this.state_show_all.Text = "小灯闪烁成功... ...";
                    }
                    else
                    {
                                                                                         //关灯失败，状态栏显示信息
                        this.state_show_all.Text = "小灯闪烁失败，请重新操作！";
                    }
                }
                CloseSCIport(SpPCorMCU);
            }
            else
            {
                                                                                         //打开串口失败，显示失败信息
                this.state_show_all.Text = "打开串口失败，可能被占用，请重新尝试！";
                                                                                         //发出警报声音
                HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
            }
        }


        /// <summary>
        /// 鼠标离开，自动关闭小灯闪烁
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox_change_MouseLeave(object sender, EventArgs e)
        {
            StopInOrderToRestart();                                                      //重新准备开始

                                                                                         //素表离开，关闭小灯
            if (OpenSCIport(SpPCorMCU))                                                  //打开串口
            {
                CommandBytes = MakeCommandBytes( DefinedTypeData.CODE_SUCCESSED,          //构造命令
                                                 DefinedTypeData.CODE_FAILED,
                                                 DefinedTypeData.CODE_LIGHT_SHUTDOWN);
                HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                          //发送命令

                HelperUtils.Delay(5000);                                                 //延时5000，等待回应信息，测试无问题

                if (HelperSCI.SCIReceiveData(SpPCorMCU, ref ReceiveDataArray))           //接收数据
                {
                                                                                         //识别看看是否是关灯命令
                    if (GetCommandByte(ReceiveDataArray).Equals(DefinedTypeData.CODE_LIGHT_SHUTDOWN))
                    {                                                                    //识别成功，将模拟灯关闭
                        this.pictureBox_light_state.Image = Properties.Resources.light_an;
                    }
                }
                CloseSCIport(SpPCorMCU);
            }
            else
            {
                                                                                         //打开串口失败，显示失败信息
                this.state_show_all.Text = "打开串口失败，可能被占用，请重新尝试！";
                                                                                         //发出警报声音
                HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
            }
            this.pictureBox_light_state.Image = Properties.Resources.light_an;
        }


        /// <summary>
        /// LED数码管的启动与停止。同时根据操作效果换图片
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox_led_Click(object sender, EventArgs e)
        {
            StopInOrderToRestart();                                                      //重新准备开始

            if (RunningFlag == 0)                                                        //如果LED处于停止状态
            {
                                                                                         //发送启动命令
                if (OpenSCIport(SpPCorMCU))                                              //打开串口
                {
                    CommandBytes = MakeCommandBytes(DefinedTypeData.CODE_SUCCESSED,      //构造命令
                                                     DefinedTypeData.CODE_FAILED,
                                                     DefinedTypeData.CODE_LED_COUNT_TO_NUM);
                    HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                      //发送命令   **** 暂时没有放置确认代码，工作量的问题 ****

                    HelperUtils.Delay(5000);                                             //延时5000，等待回应信息，测试无问题

                    CloseSCIport(SpPCorMCU);


                    this.state_show_all.Text = "LED数码管演示已经成功启动";
                    this.pictureBox_led.Image = Properties.Resources.Running;            //启动LED
                    RunningFlag = 1;
                }
                else
                {
                                                                                         //打开串口失败，显示失败信息
                    this.state_show_all.Text = "打开串口失败，可能被占用，请重新尝试！";
                                                                                         //发出警报声音
                    HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
                }
            }
            else
            {
                this.state_show_all.Text = "LED数码管演示已经关闭";
                this.pictureBox_led.Image = Properties.Resources.LED_Shutdown;           //停止LED
                RunningFlag = 0;
            }

        }
        ///------------------------------------------------------------------------------
        /// <summary>
        /// 鼠标离开，led自动关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ///------------------------------------------------------------------------------
        private void pictureBox_led_MouseLeave(object sender, EventArgs e)
        {
            StopInOrderToRestart();                                                      //重新准备开始
            this.pictureBox_led.Image = Properties.Resources.LED_Shutdown;               //停止LED
            RunningFlag = 0;
        }
        #endregion end 开关控制操作 


        #region TabPage FLASH操纵


        /// <summary>
        /// 弹出文件选取对话框，选择图片文件。图片文件生成 ~tem.pic的编码文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_flash_loadpic_Click(object sender, EventArgs e)
        {
            OpenFileDialog t = new OpenFileDialog();
            t.Filter = "(*.jpg)|*.jpg|(*.bmp)|*.bmp";                                    //过滤可选择的文件类型
            t.Title = "请选择需要放入FLASH中的图片";

            if (t.ShowDialog() == DialogResult.OK)                                       //如果对话框打开ok
            {
                try
                {
                    FileStream fs = new FileStream(t.FileName.ToString(), FileMode.Open, FileAccess.Read);
                    BinaryReader br = new BinaryReader(fs);
                    StreamWriter sw = new StreamWriter(Application.StartupPath.ToString() + "\\~temp.pic");

                    int length = (int)fs.Length;
                    while (length > 0)
                    {
                        byte tempByte = br.ReadByte();                                   //编码转换方法
                        int tempInt = Convert.ToInt32(tempByte);
                        string tempStr = Convert.ToString(tempInt, 16);

                        sw.WriteLine(tempStr);
                        length--;
                    }


                    sw.Close();                                                          //关闭打开的文件句柄
                    br.Close();
                    fs.Close();
                }
                catch (Exception exce)
                {
                    MessageBox.Show(exce.Message);
                }

                this.button_flash_encode.Enabled = true;
                this.state_show_all.Text = "FLASH操作:图片载入成功...存入文件成功！";
            }
        }

        /// <summary>
        /// 将编码文件恢复为图片。编码文件恢复为图片另存为result.jpg
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_flash_encode_Click(object sender, EventArgs e)
        {
            try
            {
                FileStream fs = new FileStream(Application.StartupPath.ToString() + "\\result.jpg", FileMode.Create, FileAccess.Write);
                BinaryWriter bw = new BinaryWriter(fs);
                StreamReader sr = new StreamReader(Application.StartupPath.ToString() + "\\~temp.pic");

                while (sr.Peek() != -1)
                {
                    string tempStr = sr.ReadLine();                                      //同图片编码相反的方式进行即可
                    int tempInt = Convert.ToInt16(tempStr, 16);
                    byte tempByte = Convert.ToByte(tempInt);

                    bw.Write(tempByte);
                }

                sr.Close();
                bw.Close();
                fs.Close();

            }
            catch (Exception exce)
            {
                MessageBox.Show(exce.Message);
            }


            this.pictureBox_flash_yuan.ImageLocation = Application.StartupPath.ToString() + "\\result.jpg";
            this.button_flash_ok.Enabled = true;
            this.state_show_all.Text = "FLASH操作:图片编码解析成功，准备好发送...";
        }


        /// <summary>
        /// 进入图片部分内容存进flash的0xA000。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_flash_pictoflash_Click(object sender, EventArgs e)
        {
            if (RunningFlag == 0)
            {

                this.button_flash_loadpic.Enabled = true;

                this.pictureBox_flash_zhong.Image = Properties.Resources.FLASH;
                this.pictureBox_flash_yuan.Image = null;

                this.button_flash_ok.Enabled = false;

                RunningFlag = 1;
            }
        }

        /// <summary>
        /// 从flash中读出写入的部分图片编码
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_flash_flashtopic_Click(object sender, EventArgs e)
        {
            if (RunningFlag == 1)
            {
                this.pictureBox_flash_yuan.Image = Properties.Resources.FLASH;
                this.pictureBox_flash_zhong.Image = null;

                this.button_flash_encode.Enabled = false;
                this.button_flash_loadpic.Enabled = false;
                this.button_flash_ok.Enabled = true;

                RunningFlag = 0;
            }
            else
            {
                MessageBox.Show("请先存取，在来读取!");
            }
        }

        /// <summary>
        /// 执行所选模式的具体操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_flash_ok_Click(object sender, EventArgs e)
        {
            byte[] picDataBuffer;
            int i = 0;

            if (RunningFlag == 1)                                                        // 图片向flash中写入
            {
                StreamReader sr = new StreamReader(Application.StartupPath.ToString() + "\\~temp.pic");

                try
                {
                    picDataBuffer = new byte[512];

                    while ((sr.Peek() != -1) && i < 512)                            //读取文件,考虑到串行通讯的速度和设计的复杂度，只读取出512个字节
                    {
                        string tempStr = sr.ReadLine();                                  //编码解析，一定要这样，否则写入flash后的数据将不是我们需要的编码
                        int tempInt = Convert.ToInt16(tempStr, 16);
                        byte tempByte = Convert.ToByte(tempInt);

                        picDataBuffer[i++] = tempByte;
                    }



                    //向FLASH写入,每52字节一写，每512字节一擦除，从0xA000开始写入

                    StopInOrderToRestart();                                              //重新准备开始
                    //发送
                    if (OpenSCIport(SpPCorMCU))                                          //打开串口
                    {
                        CommandBytes = MakeCommandBytes(DefinedTypeData.CODE_SUCCESSED, //构造命令
                                                         DefinedTypeData.CODE_FAILED,
                                                         DefinedTypeData.CODE_FLASH_PIC_SAVE);
                        HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                  //发送命令

                        HelperUtils.Delay(8000);                                         //延时8000，等待回应信息，测试无问题

                        if (HelperSCI.SCIReceiveData(SpPCorMCU, ref ReceiveDataArray))   //接收数据
                        {
                            //识别看看是否是FLASH写入命令
                            if (GetCommandByte(ReceiveDataArray).Equals(DefinedTypeData.CODE_FLASH_PIC_SAVE))
                            {
                                this.state_show_all.Text += "FLASH写入中... ...";

                                //发送512字节数据
                                HelperSCI.SCISendData(SpPCorMCU, picDataBuffer);

                                this.state_show_all.Text += "写入成功！";
                            }
                            else
                            {
                                //FLASH写入失败，状态栏显示信息
                                this.state_show_all.Text += "FLASH写入失败，请重新操作！";
                            }
                        }
                        CloseSCIport(SpPCorMCU);
                    }
                    else
                    {
                        //打开串口失败，显示失败信息
                        this.state_show_all.Text = "打开串口失败，可能被占用，请重新尝试！";
                        //发出警报声音
                        HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
                    }

                }
                catch (Exception exce)
                {
                    MessageBox.Show(exce.Message);
                }
                finally
                {
                    sr.Close();
                }
            }
            else                                                                         //从flash中读出数据
            {

                StopInOrderToRestart();                                                  //重新准备开始

                //发送
                if (OpenSCIport(SpPCorMCU))                                              //打开串口
                {
                    CommandBytes = MakeCommandBytes(DefinedTypeData.CODE_SUCCESSED,     //构造命令
                                                     DefinedTypeData.CODE_FAILED,
                                                     DefinedTypeData.CODE_FLASH_PIC_READ);
                    HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                      //发送命令

                    HelperUtils.Delay(8000);                                             //延时8000，等待回应信息，测试无问题


                    HelperSCI.SCIReceiveData(SpPCorMCU, ref ReceiveDataArray);

                    if (ReceiveDataArray.Length > 0)
                    {
                        string temp = "";

                        for (i = 0; i < ReceiveDataArray.Length; i++)
                        {
                            temp += ReceiveDataArray[i].ToString("X2") + " ";
                        }

                        this.state_show_all.Text = "FLASH操作:从Flash中读取数据成功！";
                        MessageBox.Show(temp);                                           //byte直接转为ASCII后的值

                        this.pictureBox_flash_zhong.Image = Properties.Resources.OK;
                    }
                }
                else
                {
                    //打开串口失败，显示失败信息
                    this.state_show_all.Text = "打开串口失败，可能被占用，请重新尝试！";
                    //发出警报声音
                    HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
                }


            }
        }





        #endregion end Tab


        #region TabPage 键盘仿真操作
        ///------------------------------------------------------------------------------
        /// <summary>
        /// 双击打开键盘监听，通过向低端发送控制命令
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ///------------------------------------------------------------------------------
        private void pictureBox_keyboard_listen_DoubleClick(object sender, EventArgs e)
        {
            StopInOrderToRestart();                                                      //重新准备开始

            if (RunningFlag == 0)
            {
                //启动键盘监听
                if (OpenSCIport(SpPCorMCU))                                              //打开串口
                {
                    CommandBytes = MakeCommandBytes(DefinedTypeData.CODE_SUCCESSED,      //构造命令
                                                    DefinedTypeData.CODE_FAILED,
                                                    DefinedTypeData.CODE_KEYBOARD_RECOGNIZE);
                    HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                      //发送命令

                    HelperUtils.Delay(5000);                                             //延时5000，等待回应信息，测试无问题

                    if (HelperSCI.SCIReceiveData(SpPCorMCU, ref ReceiveDataArray))       //接收数据
                    {
                        //识别看看是否是键盘命令
                        if (GetCommandByte(ReceiveDataArray).Equals(DefinedTypeData.CODE_KEYBOARD_RECOGNIZE))
                        {                                                                //识别成功，开始键盘监听，并打开串口接收触发事件
                            //绑定DataReceive事件
                            this.SpPCorMCU.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.SpPCorMCU_KB_DataReceived);

                            //初始化 4x4 键盘对应表，利用了索引器，详见头部定义
                            KeyToASCII["070"] = "F";                                     //以下都是ASCII对应信息
                            KeyToASCII["069"] = "E";
                            KeyToASCII["068"] = "D";
                            KeyToASCII["067"] = "C";

                            KeyToASCII["066"] = "B";
                            KeyToASCII["051"] = "3";
                            KeyToASCII["054"] = "6";
                            KeyToASCII["057"] = "9";

                            KeyToASCII["065"] = "A";
                            KeyToASCII["050"] = "2";
                            KeyToASCII["053"] = "5";
                            KeyToASCII["056"] = "8";

                            KeyToASCII["048"] = "0";
                            KeyToASCII["049"] = "1";
                            KeyToASCII["052"] = "4";
                            KeyToASCII["055"] = "7";

                            this.state_show_all.Text = "键盘监听中... ...";

                            this.pictureBox_keyboard_listen.Image = Properties.Resources.OK;
                            RunningFlag = 1;
                        }
                        else
                        {
                            //打开键盘监听失败，状态栏显示信息
                            this.state_show_all.Text = "打开键盘监听失败，请重新操作！";
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 鼠标离开，自动关闭键盘监听
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox_keyboard_listen_MouseLeave(object sender, EventArgs e)
        {
            if( RunningFlag == 1 )
            {
                if (SpPCorMCU.IsOpen)                                                    //判断串口是否打开着，开着就关闭
                {                                                                        //移除串口接受事件，避免影响
                    this.SpPCorMCU.DataReceived -= new System.IO.Ports.SerialDataReceivedEventHandler(this.SpPCorMCU_KB_DataReceived);

                    CloseSCIport(SpPCorMCU);                                             //首先关闭串口，放置都接收事件的影响
                }

                if (OpenSCIport(SpPCorMCU))                                              //打开串口
                {
                    CommandBytes = MakeCommandBytes(DefinedTypeData.CODE_SUCCESSED,      //构造命令
                                                    DefinedTypeData.CODE_FAILED,
                                                    DefinedTypeData.CODE_KEYBOARD_RECOGNIZE_CLOSE);
                    HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                      //发送命令

                    HelperUtils.Delay(5000);                                             //延时5000，等待回应信息，测试无问题

                    if (HelperSCI.SCIReceiveData(SpPCorMCU, ref ReceiveDataArray))       //接收数据
                    {
                                                                                         //识别看看是否是关键盘命令
                        if (GetCommandByte(ReceiveDataArray).Equals(DefinedTypeData.CODE_KEYBOARD_RECOGNIZE_CLOSE))
                        {                                                                //识别成功，关闭键盘监听
                            this.pictureBox_keyboard_listen.Image = Properties.Resources.DisAllow;
                            this.state_show_all.Text = "键盘监听关闭成功";
                            RunningFlag = 0;
                        }
                        else
                        {                                                                //关闭键盘监听失败，状态栏显示信息
                            this.state_show_all.Text = "关闭键盘监听失败，请重新操作！";
                        }
                    }
                    CloseSCIport(SpPCorMCU);
                }

            }
        }

        /// <summary>
        /// 为键盘准备的串口接收中断
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SpPCorMCU_KB_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string s1;

            HelperSCI.SCIReceiveData(SpPCorMCU, ref ReceiveDataArray);
            if (ReceiveDataArray.Length > 0)
            {
                s1 = ReceiveDataArray[0].ToString("D3");                                 //byte直接转为ASCII后的值

                delegateForKeyBoardShow dp = new delegateForKeyBoardShow(ShowButtonHighByKeyBoardCode);
                try 
                {
                    this.Invoke(dp,s1);
                }
                catch
                {
                                                                                         //捕获异常
                }
            }

        }
        #endregion end 键盘仿真操作


        #region TabPage AD采集

        /// <summary>
        /// 开始AD，MCU内部温度传感器的温度值采集
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_ad_start_Click(object sender, EventArgs e)
        {
            StopInOrderToRestart();                                                      //重新准备开始

            System.Threading.Thread.Sleep(1000);
                                                                                         //单击，开始采集
            if (OpenSCIport(SpPCorMCU))                                                  //打开串口
            {
                CommandBytes = MakeCommandBytes(DefinedTypeData.CODE_SUCCESSED,          //构造命令
                                                 DefinedTypeData.CODE_FAILED,
                                                 DefinedTypeData.CODE_AD_MCU_TEMPERATURE);
                HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                          //发送命令

                HelperUtils.Delay(10000);                                                //延时10000，等待回应信息，测试无问题
                
                if (HelperSCI.SCIReceiveData(SpPCorMCU, ref ReceiveDataArray))           //接收数据
                {
                                                                                         //识别看看是否是采集命令
                    if (GetCommandByte(ReceiveDataArray).Equals(DefinedTypeData.CODE_AD_MCU_TEMPERATURE))
                    {                                                                    //识别成功，开始显示采集数据
                        this.state_show_all.Text = "正在采集中... ...";

                        this.textBox_ad_caiji.Text = ReceiveDataArray[7].ToString();     //显示采集到的数据
                        if (this.textBox_ad_caiji.Text != "")
                        {
                            this.button_ad_huigui.Enabled = true;
                            this.state_show_all.Text += "采集成功！";
                        }

                    }
                    else
                    {
                                                                                         //采集失败，状态栏显示信息
                        this.state_show_all.Text = "采集失败，请重新操作！";
                    }
                }
                CloseSCIport(SpPCorMCU);
            }
            else
            {
                                                                                         //打开串口失败，显示失败信息
                this.state_show_all.Text = "打开串口失败，可能被占用，请重新尝试！";
                                                                                         //发出警报声音
                HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
            }
        }

        /// <summary>
        /// ad物理量回归,利用采集公式计算
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_ad_huigui_Click(object sender, EventArgs e)
        {
            int x, y;
            double Vtemp;
            double T;

            this.button_ad_start.Enabled = false;
            this.button_ad_start.Text = "转化中...";

            System.Threading.Thread.Sleep(1000);
            this.button_ad_start.Text = "转换完成";

            x = Convert.ToInt32(this.textBox_ad_caiji.Text.ToString().Substring(0, 1));  //取得采集量的高四位
            y = Convert.ToInt32(this.textBox_ad_caiji.Text.ToString().Substring(1, 1));  //取得采集量的第四位，准备计算

            Vtemp = (float) (16 * x + y + 1) * 5 / 256;                                  //取得当时温度下电压值

            if( Vtemp > 1.396 )                                                          //如果大于，就应用热段斜率值
            {
                T = 25 - ( Vtemp - 1.396 ) / 3.266;
            }
            else
            {
                T = 25 - ( Vtemp - 1.396 ) / 3.638;
            }

            this.textBox_ad_shiji.Text = T.ToString();


        }

        /// <summary>
        /// 鼠标离开，重新初始化页面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_ad_huigui_MouseLeave(object sender, EventArgs e)
        {
            this.textBox_ad_caiji.Text = "";
            this.textBox_ad_shiji.Text = "";
            this.button_ad_start.Enabled = true;
            this.button_ad_start.Text = "开始采集";
            this.button_ad_huigui.Enabled = false;
        }

        #endregion end TabPage AD采集


        #region TabPage 定时器
        /// <summary>
        /// 自动更新当前时间，利用系统定时器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer_Tick(object sender, EventArgs e)
        {
            this.textBox_time_curtime.Text = System.DateTime.Now.ToString();
        }
        /// <summary>
        /// 获取将来时间文本域的时间值
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox_time_future_MouseDoubleClick(object sender, MouseEventArgs e)
        {                                                                                //获取将要设定的时间初始值
            this.textBox_time_future.Text = System.DateTime.Now.ToLocalTime().ToLongTimeString();
                                                                                         //绑定鼠标滚轮事件
            this.textBox_time_future.MouseWheel += new MouseEventHandler(textBox_time_future_MouseWheel);

            this.button_time_start.Enabled = true;
        }

        /// <summary>
        /// 禁止文本域输入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox_time_future_KeyPress(object sender, KeyPressEventArgs e)
        {
            e.Handled = true;
        }

        /// <summary>
        /// 鼠标滚轮事件，时间区域进行增减
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox_time_future_MouseWheel(object sender, MouseEventArgs e)
        {
            int pos;
            string time;

            pos = this.textBox_time_future.SelectionStart;                               //获取带设定时间光标的位置
            time = this.textBox_time_future.Text.ToString();                             //获得当前时间
                                                                                         
            TimeChangedByGunlun(this.textBox_time_future.SelectionStart,                 //获得文本域中光标的位置
                                e.Delta,                                                 //获取鼠标滚轮的值，大于0，向上滚动
                                ref time);                                               //time，当前文本域时间，用ref，可直接修改

            this.textBox_time_future.Text = time;                                        //更新时间

            this.textBox_time_future.SelectionStart = pos;                               //保证时间文本域中的鼠标位置不改变，不可以去掉
        }

        /// <summary>
        /// 保证日期控件的最小日期为当前的日期
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dateTimePicker_time_MouseHover(object sender, EventArgs e)
        {
            this.dateTimePicker_time.MinDate = System.DateTime.Today;                    //将日期下限设为今天的日期
        }

        /// <summary>
        /// 判断设定时间是否比现在时间大，如果打，开始计时。如果小，发出警报，提示出错。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_time_start_Click(object sender, EventArgs e)
        {
            string s1, s2;
            long t;

            RunningFlag = 1;                                                             //置运行标志

            s1 = this.dateTimePicker_time.Text.ToString() +                              //获得日期
                 " " +                                                                   //需要加空格，标准时间格式
                 this.textBox_time_future.Text.ToString();                               //获得文本域时间
            s2 = System.DateTime.Now.ToLocalTime().ToLongTimeString();                   //获得当前系统时间

            t = Convert.ToDateTime(s1).Ticks - Convert.ToDateTime(s2).Ticks;             //获得两个时间之间的计数差

            if (t < 0)
            {                                                                            //播放警告声音
                HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
                this.state_show_all.Text = "设定的计时时间比当前系统时间小，无法开始计时，请重新设定大一点";
            }
            else
            {
                                                                                         //发送开始计时命令，并反馈出来
                StopInOrderToRestart();                                                  //重新准备开始

                if (OpenSCIport(SpPCorMCU))                                              //打开串口
                {
                    CommandBytes = MakeCommandBytes( DefinedTypeData.CODE_SUCCESSED,     //构造命令
                                                     DefinedTypeData.CODE_FAILED,
                                                     DefinedTypeData.CODE_TIMER_COUNT);  //开始计数命令
                    HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                      //发送命令

                    HelperUtils.Delay(8000);                                             //延时8000,测试通过

                    if (HelperSCI.SCIReceiveData(SpPCorMCU, ref ReceiveDataArray))       //接收数据
                    {
                        if (GetCommandByte(ReceiveDataArray).Equals(DefinedTypeData.CODE_TIMER_COUNT))
                        {                                                                //识别成功，准备接收数据，并设置反馈界面

                            this.pictureBox_time_counting.Visible = true;                //运行图片显示

                            s1 = t.ToString();
                            s2 = s1.Substring(0, s1.Length - 7);                         //获得时间的计数，用于计数

                            TimerCountNum = Convert.ToInt32(s2);                         //需要计得数，次数

                            HelperSCI.SetBytesForReceived(SpPCorMCU, 7);                 //设定触发事件字符为7个
                                                                                         //绑定DataReceive事件
                            this.SpPCorMCU.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.SpPCorMCU_Timer_DataReceived);

                                                                                         //获得mcu计时时间
                            this.textBox_time_mcu.Text = System.DateTime.Now.ToString();

                            this.pictureBox_time_arrived.Image = Properties.Resources.time_shalou;
                            this.pictureBox_time_arrived.Visible = true;                 //显示运行沙漏

                            this.dateTimePicker_time.Enabled = false;
                            this.textBox_time_future.Enabled = false;
                            this.button_time_start.Text = "正在计时中...";
                            this.state_show_all.Text = "定时器正在工作中... ...";
                        }
                        else
                        {
                                                                                         //定时器打开失败，状态栏显示信息
                            this.state_show_all.Text = "定时器操作:MCU定时器打开失败！";
                                                                                         //发出警报声音
                            HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
                        }
                    }
                }
                else
                {
                                                                                         //打开串口失败，显示失败信息
                    this.state_show_all.Text = "定时器操作:打开串口失败，可能被占用，请重新尝试！";
                                                                                         //发出警报声音
                    HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
                }



            }
        }

        /// <summary>
        /// 鼠标离开按钮，自动关闭计时，停止计时，并初始化界面.关闭串口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_time_start_MouseLeave(object sender, EventArgs e)
        {
            if (RunningFlag == 1)
            {
                                                                                         //去除DataReceived事件
                this.SpPCorMCU.DataReceived -= new System.IO.Ports.SerialDataReceivedEventHandler(this.SpPCorMCU_Timer_DataReceived);
                CloseSCIport(SpPCorMCU);

                if (OpenSCIport(SpPCorMCU))
                {
                                                                                         //向MCU发送关闭定时器的请求
                    CommandBytes = MakeCommandBytes(DefinedTypeData.CODE_SUCCESSED,      //构造命令
                                                    DefinedTypeData.CODE_FAILED,
                                                    DefinedTypeData.CODE_TIMER_COUNT_CLOSE); 
                    HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                      //发送命令

                    HelperUtils.Delay(8000);                                             //延时8000,测试通过

                    if (HelperSCI.SCIReceiveData(SpPCorMCU, ref ReceiveDataArray))       //接收数据
                    {
                        if (GetCommandByte(ReceiveDataArray).Equals(DefinedTypeData.CODE_TIMER_COUNT_CLOSE))
                        {                                                                //识别成功,已经关闭定时器
                            this.state_show_all.Text += ",定时器已经成功关闭";
                                                                                         //重置用户界面

                            this.button_time_start.Enabled = false;
                            this.button_time_start.Text = "开始计时";
                            this.textBox_time_mcu.Text = "";
                            this.textBox_time_future.Text = "Db_Click";
                            this.textBox_time_future.Enabled = true;
                            this.dateTimePicker_time.Enabled = true;
                            this.pictureBox_time_arrived.Visible = false;
                            this.pictureBox_time_counting.Visible = false;
                        }
                        else
                        {
                                                                                         //定时器关闭失败，状态栏显示信息
                            this.state_show_all.Text = "定时器操作:定时器关闭失败！";
                                                                                         //发出警报声音
                            HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
                        }
                    }
                    CloseSCIport(SpPCorMCU);
                }
                else
                {
                    this.state_show_all.Text = "打开串口失败";
                }
                RunningFlag = 0;
            }
        }

        /// <summary>
        /// 为定时器技术接收准备的串口接收中断
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SpPCorMCU_Timer_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int i;

            if (HelperSCI.SCIReceiveData(SpPCorMCU,                                      //开始接受数据,并放置于ReceiveDataArray中
                                    ref ReceiveDataArray))                               //注意使用 ref关键字，需要赋值
            {
                if (ReceiveDataArray.Length > 0)
                {
                    if (ReceiveDataArray.Length != 7)                                    //如果接受到的不是7位，则清空此次接收数据，重新接收    * * *
                    {
                        for (i = 0; i < ReceiveDataArray.Length; i++)
                            ReceiveDataArray[i] = 0;                                     //都清零，避免影响
                    }
                    else
                    {

                        if (CmdBytesFromMCU_Recognize(ReceiveDataArray,                  //从底端接受的7字节命令帧
                                                      DefinedTypeData.CODE_TIMER__))     //需要识别的操作码，即计数单位
                        {
                                                                                         //识别成功
                                                                                         //只能通过委托异步才能执行
                            delegateForTimerCounting dt = new delegateForTimerCounting(UpdateTimerMcuTextbox);
                             try
                            {
                                this.Invoke(dt);
                             }
                            catch
                            {
                                                                                         //捕获异常
                            }
                            

                            if (TimerCountNum == 1)
                            {
                                this.state_show_all.Text = "定时器操作:定时器计数完毕了！";
                                                                                         //去除DataReceived事件
                                this.SpPCorMCU.DataReceived -= new System.IO.Ports.SerialDataReceivedEventHandler(this.SpPCorMCU_Timer_DataReceived);
                                dt -= UpdateTimerMcuTextbox;                             //去除委托,否则异步还会继续执行
                                                                                         
                                                                                         //换时间到的图片
                                this.pictureBox_time_arrived.Image = Properties.Resources.naozhong;
                            }
                            else
                            {
                                TimerCountNum--;                                         //计数减少1
                                this.state_show_all.Text = "定时器操作:来自于MCU的计数" + TimerCountNum.ToString();
                            }
                        }

                    }
                }
            }


        }

        #endregion end TabPage 定时器


        #region TabPage PWM波形

        /// <summary>
        /// 开始pwm波形控制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_pwm_start_Click(object sender, EventArgs e)
        {
            StopInOrderToRestart();                                                      //重新准备开始

            if (RunningFlag == 0)
            {
                                                                                         //单击，打开PWM控制
                if (OpenSCIport(SpPCorMCU))                                              //打开串口
                {
                    CommandBytes = MakeCommandBytes(DefinedTypeData.CODE_SUCCESSED,      //构造命令
                                                     DefinedTypeData.CODE_FAILED,
                                                     DefinedTypeData.CODE_PWM_CONTROL_LIGHT_INIT);
                    HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                      //发送命令

                    HelperUtils.Delay(8000);                                             //延时8000，等待回应信息，测试无问题

                    this.trackBar_pwm_zkb.Enabled = true;
                    this.button_pwm_start.Text = "<-方向键->";
                    this.trackBar_pwm_zkb.Value = 10;                                    //设定初始占空比50%

                    this.GroupBox_PWM.CreateGraphics().Clear(Color.Empty);               //清屏
                    DrawPWM(this.GroupBox_PWM.CreateGraphics(), (float)0.5);             //画波形图

                    this.state_show_all.Text = "PWM小灯控制中... ...";

                    RunningFlag = 1;

                    CloseSCIport(SpPCorMCU);
                }
                else
                {
                                                                                         //打开串口失败，显示失败信息
                    this.state_show_all.Text = "打开串口失败，可能被占用，请重新尝试！";
                                                                                         //发出警报声音
                    HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
                }

            }

        }

        /// <summary>
        /// 调节占空比
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void trackBar_pwm_zkb_Scroll(object sender, EventArgs e)
        {
            float zk;
            byte[] temp;

            Graphics g = this.GroupBox_PWM.CreateGraphics();                             //创建画布，GruppBox_PWM控件上的

            temp = new byte[1];
            if (this.trackBar_pwm_zkb.Value == 20)
            {
                temp[0] = 0x99;                                                          //只能用99，因为100 --- 256，大于255
            }
            else if (this.trackBar_pwm_zkb.Value < 10)
            {                                                                            //注意，这里应该乘以5，但是追求反馈效果的明显，取小一点的数 3 *** ***
                temp[0] = Convert.ToByte((Convert.ToInt32(this.trackBar_pwm_zkb.Value) * 3).ToString(), 16);
            }
            else
            {
                temp[0] = Convert.ToByte((Convert.ToInt32(this.trackBar_pwm_zkb.Value) * 3).ToString(), 16);
            }





                                                                                         //单击，打开PWM控制
            if (OpenSCIport(SpPCorMCU))                                                  //打开串口
            {
                CommandBytes = MakeCommandBytes(DefinedTypeData.CODE_SUCCESSED,          //构造命令
                                                 DefinedTypeData.CODE_FAILED,
                                                 DefinedTypeData.CODE_PWM_CONTROL_LIGHT);
                HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                          //发送命令

                HelperUtils.Delay(8000);                                                 //延时8000，等待回应信息，测试无问题

                if (HelperSCI.SCIReceiveData(SpPCorMCU, ref ReceiveDataArray))           //接收数据
                {
                                                                                         //识别看看是否是PWM控灯命令
                    if (GetCommandByte(ReceiveDataArray).Equals(DefinedTypeData.CODE_PWM_CONTROL_LIGHT))
                    {                                                                
                                                                                         //识别成功，开始控制波形
                        if (HelperSCI.SCISendData(SpPCorMCU, temp))                      //发送控制
                        {
                            zk = (float)this.trackBar_pwm_zkb.Value / 20;                //获得占空比

                            this.button_pwm_start.Text = (zk * 100).ToString() + " / 100";      

                            DrawPWM(g, zk);                                              //重绘波形图

                            this.state_show_all.Text = "PWM控制: 占空比" + this.button_pwm_start.Text + "控制小灯成功！";
                        }
                        CloseSCIport(SpPCorMCU);
                    }
                    else
                    {
                                                                                         //控制失败，状态栏显示信息
                        this.state_show_all.Text = "PWM控灯失败，请重新操作！";
                    }
                }
            }
            else
            {
                                                                                         //打开串口失败，显示失败信息
                this.state_show_all.Text = "打开串口失败，可能被占用，请重新尝试！";
                                                                                         //发出警报声音
                HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
            }

        }

        /// <summary>
        /// 鼠标离开按钮，关闭pwm控制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_pwm_start_MouseLeave(object sender, EventArgs e)
        {
            StopInOrderToRestart();                                                      //重新准备开始

            if (RunningFlag == 1)
            {

            }

            StopInOrderToRestart();                                                      //重新准备开始

            if (RunningFlag == 1)
            {
                //单击，打开PWM控制
                if (OpenSCIport(SpPCorMCU))                                              //打开串口
                {
                    CommandBytes = MakeCommandBytes(DefinedTypeData.CODE_SUCCESSED,      //构造命令
                                                     DefinedTypeData.CODE_FAILED,
                                                     DefinedTypeData.CODE_PWM_CONTROL_LIGHT_CLOSE);
                    HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                      //发送命令

                    RunningFlag = 0;
                    this.button_pwm_start.Enabled = true;
                    this.button_pwm_start.Text = "开 始";
                    this.trackBar_pwm_zkb.Enabled = false;

                    this.state_show_all.Text = "PWM控制:PWM小灯控制已成功结束！";

                    this.GroupBox_PWM.Refresh();                                         //重新刷新屏幕，恢复初始状态

                    CloseSCIport(SpPCorMCU);
                }
                else
                {
                                                                                         //打开串口失败，显示失败信息
                    this.state_show_all.Text = "打开串口失败，可能被占用，请重新尝试！";
                                                                                         //发出警报声音
                    HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
                }

            }
        }

        #endregion end TabPage PWM波形


        #region TabPage LED液晶显示
        /// <summary>
        /// 鼠标点击清空
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox_LED_input_MouseClick(object sender, MouseEventArgs e)
        {
            this.textBox_LED_input.Text = "";                                            //清输入框
            this.button_LED_input.Enabled = true;
        }
        ///------------------------------------------------------------------------------
        /// <summary>
        /// textBox_LED_input_KeyUp文本域每输入一个字符触发的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ///------------------------------------------------------------------------------
        private void textBox_LED_input_KeyUp(object sender, KeyEventArgs e)
        {
            this.label_led_input_info.Text = "你已经输入了 " +
                                             this.textBox_LED_input.Text.Length.ToString() +
                                             " 个字符";
            if (this.textBox_LED_input.Text.Length >= 33)
            {                                                                            //播放警告声音
                HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0); 

                this.textBox_LED_input.Text = this.textBox_LED_input.Text.Substring(0, 32);
                this.label_led_input_info.Text = "你输入的字符过长，超过32个字符！";     //显示警告文字

                this.textBox_LED_input.Focus();
                this.textBox_LED_input.Select(this.textBox_LED_input.Text.Length, 0);    //光标移动到文本的末尾
            }
        }
        ///------------------------------------------------------------------------------
        /// <summary>
        /// textBox_LED_input_KeyUp文本域每摁下一个键的时候触发的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ///------------------------------------------------------------------------------
        private void textBox_LED_input_KeyPress(object sender, KeyPressEventArgs e)
        {
            bool bflag;

            bflag = HelperUtils.AcceptedCharHandle(sender, e, 2);                        //对键盘的输入字符处理，判断是否合法
            if (bflag == false)                                                          //遇到非法字符
            {
                this.label_led_input_info.Text = "你已经按下了禁止输入的字符！";
                                                                                         //播放警告声音
                HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0); 
            }
        }

        ///------------------------------------------------------------------------------
        /// <summary>
        /// 打开或停止液晶显示功能。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ///------------------------------------------------------------------------------
        private void button_LED_input_start_Click(object sender, EventArgs e)
        {
            this.button_LED_input_start.Text = "等待输入";
            this.button_LED_input_start.Enabled = false;

            this.textBox_LED_input.Text = "等待输入中... ...";

            this.textBox_LED_input.Enabled = true;

        }
        /// <summary>
        /// 发送文本域中的内容给底层，并显示在底层MCU上
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_LED_input_Click(object sender, EventArgs e)
        {
            string s1;

            StopInOrderToRestart();                                                      //重新准备开始
            
            if (OpenSCIport(SpPCorMCU))                                                  //打开串口
            {
                CommandBytes = MakeCommandBytes( DefinedTypeData.CODE_SUCCESSED,         //构造命令
                                                 DefinedTypeData.CODE_FAILED,
                                                 DefinedTypeData.CODE_LCD_SHOW_STR);
                HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                          //发送命令

                HelperUtils.Delay(9000);                                                //延时9000,测试通过

                if (HelperSCI.SCIReceiveData(SpPCorMCU, ref ReceiveDataArray))           //接收数据
                {
                    System.Threading.Thread.Sleep(500);                                  //缓冲下，等待处理完全
                    
                    if (GetCommandByte(ReceiveDataArray).Equals(DefinedTypeData.CODE_LCD_SHOW_STR))
                    {                                                                    //识别成功，准备发送数据
                                                                                         //处理发送过程
                        s1 = this.textBox_LED_input.Text.ToString();                     //获取输入框文字
                        s1 = ShowStrInScreen32(s1);                                      //保证发送的字符是32个

                        if (
                            HelperSCI.SCISendData(
                            SpPCorMCU, 
                            System.Text.Encoding.Default.GetBytes(s1)) )                 //编码转换，为byte
                        {
                                                                                         //向仿真屏幕显示同样内容
                            this.textBox_LED_show.Text = s1.Substring(0, 16) +           //第一行
                                                         "\r\n\r\n" +                    //回车
                                                         s1.Substring(16, 16);           //第二行
                            
                            this.state_show_all.Text = "液晶屏操作:向液晶屏发送文字并显示成功... ...";
                            this.button_LED_clear.Enabled = true;
                        }
                    }
                    else
                    {
                                                                                         //关灯失败，状态栏显示信息
                        this.state_show_all.Text = "液晶屏操作:向液晶屏发送显示文字失败！";
                    }
                     
                }
                CloseSCIport(SpPCorMCU);
            }
            else
            {
                                                                                         //打开串口失败，显示失败信息
                this.state_show_all.Text = "液晶屏操作:打开串口失败，可能被占用，请重新尝试！";
                                                                                         //发出警报声音
                HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
            }
        }
        /// <summary>
        /// 液晶屏清屏
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_LED_clear_Click(object sender, EventArgs e)
        {
            CloseSCIport(SpPCorMCU);

            StopInOrderToRestart();                                                      //重新准备开始

            if (OpenSCIport(SpPCorMCU))                                                  //打开串口
            {
                CommandBytes = MakeCommandBytes( DefinedTypeData.CODE_SUCCESSED,         //构造命令
                                                 DefinedTypeData.CODE_FAILED,
                                                 DefinedTypeData.CODE_LCD_CLEAR);
                HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                          //发送命令

                HelperUtils.Delay(8000);                                                 //延时8000,测试通过

                if (HelperSCI.SCIReceiveData(SpPCorMCU, ref ReceiveDataArray))           //接收数据
                {                                                                        //确认是否是清屏指令
                    if (GetCommandByte(ReceiveDataArray).Equals(DefinedTypeData.CODE_LCD_CLEAR))
                    {                                                                
                        this.state_show_all.Text = "液晶屏操作:清屏成功... ...";

                        this.button_LED_clear.Enabled = true;
                        this.button_LED_input.Enabled = false;

                        this.textBox_LED_input.Text = "等待输入中... ...";
                        this.textBox_LED_show.Text = "";
                    }
                    else
                    {
                                                                                         //清屏失败，状态栏显示信息
                        this.state_show_all.Text = "液晶屏操作:清屏失败！";
                    }
                }
                CloseSCIport(SpPCorMCU);
            }
            else
            {
                //打开串口失败，显示失败信息
                this.state_show_all.Text = "液晶屏操作:打开串口失败，可能被占用，请重新尝试！";
                //发出警报声音
                HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_jinggao"], 0);
            }
                                                                                         //发送清屏
        }
        #endregion end TabPage LED液晶显示




        #region 局部函数区，仅供此文件自己调用
        /// <summary>
        /// 打开串口，成功返回TRUE，否则返回FALSE
        /// </summary>
        /// <param name="sp">串口指针</param>
        /// <returns>返回true则成功</returns>
        private bool OpenSCIport( SerialPort sp)
        {
            if (SerialPort.GetPortNames().Length > 0)
            {
                string t = SerialPort.GetPortNames().GetValue(0).ToString();                 //获得当前电脑中的第一个存在的串口号，如COM1
                if (HelperSCI.SCIInit(sp, t, DefinedTypeData.BaudRate))                      //初始化并打开串口
                {
                    return true;                                                             //打开成功
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 关闭串口。成功返回TRUE，否则返回FALSE
        /// </summary>
        /// <param name="sp">串口指针</param>
        /// <returns>返回true成功</returns>
        private bool CloseSCIport(SerialPort sp)
        {
            if( HelperSCI.SCIClose(sp) )                                                 //关闭，并释放窗口资源
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 利用命令开始标志，结束标志，命令码，组成符合要求的命令字段。
        /// 形如 0x00 0x00 0x00 CODE 0xFF 0xFF 0xFF
        /// </summary>
        /// <param name="start">开始标志</param>
        /// <param name="end">结束标志</param>
        /// <param name="operatorCode"操作码></param>
        /// <returns>返回组好的字节</returns>
        private byte[] MakeCommandBytes(byte start, byte end, byte operatorCode)
        {
            byte[] b = new byte[7];
            b[0] = start;
            b[1] = start;
            b[2] = start;

            b[3] = operatorCode;

            b[4] = end;
            b[5] = end;
            b[6] = end;

            return b;
        }

        /// <summary>
        /// 如果识别成功返回操作码，否则返回失败码
        /// </summary>
        /// <param name="receiveCommandBytes"></param>
        /// <returns></returns>
        private byte GetCommandByte(byte[] receiveCommandBytes)
        {
            if (receiveCommandBytes.Length > 0)
            {
                if (receiveCommandBytes[0] == DefinedTypeData.CODE_FAILED &&
                    receiveCommandBytes[1] == DefinedTypeData.CODE_FAILED &&
                    receiveCommandBytes[2] == DefinedTypeData.CODE_FAILED &&
                    receiveCommandBytes[4] == DefinedTypeData.CODE_SUCCESSED &&
                    receiveCommandBytes[5] == DefinedTypeData.CODE_SUCCESSED &&
                    receiveCommandBytes[6] == DefinedTypeData.CODE_SUCCESSED)
                {
                    return receiveCommandBytes[3];
                }
                else
                {
                    return DefinedTypeData.CODE_FAILED;
                }
            }
            else
            {
                return DefinedTypeData.CODE_FAILED;
            }
        }

        /// <summary>
        /// 停止所有当前动作，开始新的演示动作，建议在每个新动作之前进行调用.可以重置没有关闭的串口，以及低端的中断，循环。
        /// </summary>
        private void StopInOrderToRestart()
        {
            try
            {
                if (OpenSCIport(SpPCorMCU))                                              //打开串口
                {
                    CommandBytes = MakeCommandBytes(DefinedTypeData.CODE_SUCCESSED,      //构造命令
                                                         DefinedTypeData.CODE_FAILED,
                                                         DefinedTypeData.CODE_STOP);     //停止一项而不是全部命令
                    HelperSCI.SCISendData(SpPCorMCU, CommandBytes);                      //发送命令

                    HelperUtils.Delay(1000);                                             //延时1000，让底端反映
                    CloseSCIport(SpPCorMCU);                                             //关闭串口
                }
            }
            catch
            {
                //
            }
        }

        /// <summary>
        /// 将不足32个字符的字符串款冲到32个字符
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private string ShowStrInScreen32( string str)
        {
            while (str.Length < 32)
            {
                str += " ";                                                              //加空格弥补不足的字符
            }

            return str;
        }

        /// <summary>
        /// 根据底端按下键的定义值，转换为的ascii后对应的的仿真按钮突起显示
        /// </summary>
        /// <param name="str">按下键的定义值</param>
        private void ShowButtonHighByKeyBoardCode(string str)
        {
            string keyName = KeyToASCII[str].ToString();                                 //获得所按键的真实字符

                                                                                         //在前台页面来反馈，按钮突起
            this.button_curPressedKeyBoardValue.Text = keyName;
                                                                                         //遍历键盘区域的所有控件，与输入值相符的按钮突出显示
            foreach (Control c in this.panel1.Controls)
            {
                if ((c is Button) && c.Text == keyName)
                {
                    c.Enabled = false;
                    System.Threading.Thread.Sleep(700);                                  //模拟按下弹起的效果
                    c.Enabled = true;
                }
            }
        }

        /// <summary>
        /// 滚动鼠标根据鼠标所在位置，判定是时，分，秒，的增减。鼠标改变后的新的时间放在time，用ref直接修改
        /// </summary>
        /// <param name="pos">时间文本域中鼠标的位置</param>
        /// <param name="direction">鼠标滚轮的方向，上，下</param>
        /// <param name="time">需要改变的时间</param>
        private void TimeChangedByGunlun(int pos, int direction, ref string time)
        {
            string[] t = time.Split(':');                                                //从时间中分出时分秒
            int temp;

            if (direction > 0)                                                           //方向大于0，则增加时间.即向上滚动
            {
                if (pos == 0 || pos == 1 || pos == 2)                                    //对时进行处理，大于24，从0开始
                {
                    temp = Convert.ToInt32(t[0]) + 1;                                    //自增操作
                    if( temp >= 24 )                                                     //达到24小时，从0开始
                    {
                        t[0] = "00";
                    }
                    else if (temp.ToString().Length == 1)
                    {
                        t[0] = "0" + temp;
                    }
                    else
                    {
                        t[0] = temp.ToString();
                    }
                }
                else if (pos == 3 || pos == 4 || pos == 5)                               //对分处理，大于60，从0开始
                {
                    temp = Convert.ToInt32(t[1]) + 1;                                    //自增操作
                    if (temp >= 60)                                                      //达到60分，从0开始
                    {
                        t[1] = "00";
                    }
                    else if (temp.ToString().Length == 1)
                    {
                        t[1] = "0" + temp;
                    }
                    else
                    {
                        t[1] = temp.ToString();
                    }
                }
                else                                                                     //对秒进行操作，大于60，从0开始
                {
                    temp = Convert.ToInt32(t[2]) + 1;                                    //自增操作
                    if (temp >= 60)                                                      //达到60分，从0开始
                    {
                        t[2] = "00";
                    }
                    else if (temp.ToString().Length == 1)
                    {
                        t[2] = "0" + temp;
                    }
                    else
                    {
                        t[2] = temp.ToString();
                    }
                }
            }
            else                                                                         //鼠标向下滚动
            {
                if (pos == 0 || pos == 1 || pos == 2)                                    //对时进行处理
                {
                    temp = Convert.ToInt32(t[0]) - 1;                                    //自减操作
                    if (temp < 0)                                                        //达到0小时，从23开始
                    {
                        t[0] = "23";
                    }
                    else if (temp.ToString().Length == 1)
                    {
                        t[0] = "0" + temp;
                    }
                    else
                    {
                        t[0] = temp.ToString();
                    }
                }
                else if (pos == 3 || pos == 4 || pos == 5)                               //对分处理
                {
                    temp = Convert.ToInt32(t[1]) - 1;                                    //自减操作
                    if (temp < 0)                                                        //达到0分，从59开始
                    {
                        t[1] = "59";
                    }
                    else if (temp.ToString().Length == 1)
                    {
                        t[1] = "0" + temp;
                    }
                    else
                    {
                        t[1] = temp.ToString();
                    }
                }
                else                                                                     //对秒进行操作
                {
                    temp = Convert.ToInt32(t[2]) - 1;                                    //自减操作
                    if (temp < 0)                                                        //达到0分，从59开始
                    {
                        t[2] = "59";
                    }
                    else if (temp.ToString().Length == 1)
                    {
                        t[2] = "0" + temp;
                    }
                    else
                    {
                        t[2] = temp.ToString();
                    }
                }
            }


            time = t[0] + ":" + t[1] + ":" + t[2];
        }


        /// <summary>
        /// 处理从低端接收过来的数据，解析出操作码。形如0xFF 0xFF 0xFF CODE 0x00 0x00 0x00.识别成功，返回true
        /// </summary>
        /// <param name="CmdB">低端来的命令字段</param>
        /// <param name="code">需要识别的操作码</param>
        /// <returns>识别成功，返回TRUE，否则返回FALSE</returns>
        private bool CmdBytesFromMCU_Recognize(byte[] CmdB,int code)
        {
            if (!(CmdB[0] == DefinedTypeData.CODE_FAILED &&                              //识别除CODE位的其他标识，是否正确
                  CmdB[1] == DefinedTypeData.CODE_FAILED &&
                  CmdB[2] == DefinedTypeData.CODE_FAILED &&
                  CmdB[4] == DefinedTypeData.CODE_SUCCESSED &&
                  CmdB[5] == DefinedTypeData.CODE_SUCCESSED &&
                  CmdB[6] == DefinedTypeData.CODE_SUCCESSED))
            {
                return false;                                                            //如果标识识别失败，说明为非法或意外指令，直接跳出函数
            }
            else
            {

                if (CmdB[3] == code)                                                     //识别指定操作码
                {
                    return true;                                                         //识别成功，返回true
                }
                else
                {
                    return false;
                }
            }
        }

        /// <summary>
        /// 更新定时器模块，计数来自MCU得时间文本域textBox_time_mcu的文本。并且计数完毕关闭MCU定时系统
        /// </summary>
        private void UpdateTimerMcuTextbox()
        {
            this.textBox_time_mcu.Text =                                                 //更新文本域的时间
                   Convert.ToDateTime(this.textBox_time_mcu.Text.ToString()).            //将文本转换为时间
                   AddSeconds(1).ToString();                                             //增加1s

                                                                                         //时间到了，去除DataReceive事件，并关闭串口！反馈界面，发出时间到了的警报。
            if (TimerCountNum == 1)
            {
                                                                                         //发出警报声音
                HelperUtils.ActionSoundEvent(ConfigurationManager.AppSettings["Sound_naoling"], 0);

                this.pictureBox_time_counting.Visible = false;                           //运行图片隐藏
                this.button_time_start.Text = "计时完毕";        
            }
        }


        /// <summary>
        /// pwm控制块，画x，y坐标轴
        /// </summary>
        /// <param name="graphics">需要画的平面</param>
        private void DrawXandY(Graphics graphics)
        {
            Pen r = new Pen(Color.Red, 2);
            Pen b = new Pen(Color.Black, 2);

            //画y
            graphics.DrawLine(r, 20, 30, 20, 150);
            //画刻度
            graphics.DrawLine(b, 18, 140, 22, 140);
            graphics.DrawLine(b, 18, 70, 22, 70);

            //画x
            graphics.DrawLine(r, 0, 140, 440, 140);
            //画刻度
            graphics.DrawLine(b, 20, 138, 20, 142);
            graphics.DrawLine(b, 120, 138, 120, 142);
            graphics.DrawLine(b, 220, 138, 220, 142);
            graphics.DrawLine(b, 320, 138, 320, 142);
            graphics.DrawLine(b, 420, 138, 420, 142);
        }

        /// <summary>
        /// 画pwm波形，并画出虚线
        /// </summary>
        /// <param name="graphics">需要画的平面</param>
        /// <param name="per">占空比</param>
        private void DrawPWM(Graphics graphics, float per)
        {
            Pen g = new Pen(Color.Green, 5);
            Pen w = new Pen(Color.White, 3);

            Pen xuColor = new Pen(Color.YellowGreen, 2);
            xuColor.DashStyle = DashStyle.Dash;                                          //画虚线

            graphics.Clear(Color.Empty);                                                 //清空屏幕，重绘
            DrawXandY(graphics);

            //画波形
            graphics.DrawLine(w, 20, 70, 440, 70);

            graphics.DrawLine(g, 20, 70, (float)(100 * per + 20), 70);
            graphics.DrawLine(xuColor, (float)(100 * per + 20), 70, (float)(100 * per + 20), 140);

            graphics.DrawLine(g, 120, 70, (float)(100 * per + 120), 70);
            graphics.DrawLine(xuColor, (float)(100 * per + 120), 70, (float)(100 * per + 120), 140);

            graphics.DrawLine(g, 220, 70, (float)(100 * per + 220), 70);
            graphics.DrawLine(xuColor, (float)(100 * per + 220), 70, (float)(100 * per + 220), 140);

            graphics.DrawLine(g, 320, 70, (float)(100 * per + 320), 70);
            graphics.DrawLine(xuColor, (float)(100 * per + 320), 70, (float)(100 * per + 320), 140);

            graphics.DrawLine(g, 420, 70, (float)(100 * per + 420), 70);
            graphics.DrawLine(xuColor, (float)(100 * per + 420), 70, (float)(100 * per + 420), 140);
        }

        #endregion
    }
} 


/* ***  2010/09/26 截止  苏州大学嵌入式仿真研究所 *** */