C#---chuankou

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);//系统dll导入ini写函数
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);//系统dll导入ini读函数
        string FileName = System.AppDomain.CurrentDomain.BaseDirectory + "Backup.ini";//ini文件名
        StringBuilder BackupBuf = new StringBuilder(30);//存储读出ini内容变量


        string Backup_text1;
        string Backup_text2;
        string Backup_text3;
        string Backup_text4;
        string Backup_text5;
        string Backup_text6;
        string Backup_text7;
        string Backup_text8;
        string Backup_text9;
        string Backup_text10;
        string Backup_text11;
        string Backup_text12;

    
       byte[] Head = new byte[2] { 0x21, 0x22 };//帧头0+帧头1
       byte[] FunCodeRead = new byte[4] { 0x01, 0x11, 0x31, 0x41 };//开关信号,温度,时间,PID参数,避开帧头0x21
       byte[] FunCodeSend = new byte[4] { 0x00, 0x10, 0x30, 0x40 };//开关信号,温度,时间,PID参数,避开帧头0x21
    //应答信号
       Boolean IONum0Ack = false;
       Boolean TemNum0Ack = false;
       Boolean TimerNum0Ack = false;
       Boolean KPNum0Ack = false;
       Boolean KINum0Ack = false;
       Boolean KDNum0Ack = false;
       Boolean PressNum0Ack = false;
       Boolean SystemErrorAck = false;
      //开关号
       ushort SetIONum = 0;
       ushort GetIONum = 0;
        //温度数据
       UInt16 SetTemperNum = 0;
       UInt16 GetTemperNum = 0;

       float SetTemper = 0.0f;
       float GetTemper = 0.0f; 
        
        //定时器数据
       ushort SetTimNum = 0;
       ushort GetTimNum = 0;

  
       Int32 SetHour = 0;
       Int32 GetHourPass = 0;//当前已经经过的时间
       Int32 GetHourDown = 0;//剩余时间
       Int32 GetHourSet = 0;//单片机定时的时间

       Int32 SetMinute = 0;
       Int32 GetMinutePass = 0;
       Int32 GetMinuteDown = 0;//剩余时间
       Int32 GetMinuteSet = 0;//单片机定时的时间


       Int32 SetSec = 0;
       Int32 GetSecPass = 0;
       Int32 GetSecDown = 0;//剩余时间
       Int32 GetSecSet = 0;//单片机定时的时间
        
      //PID参数
       float SetKP = 0.0f;
       float SetKI = 0.0f;
       float SetKD = 0.0f;

       float GetKP = 0.0f;
       float GetKI = 0.0f;
       float GetKD = 0.0f;

        //压力参数
       float SetPress = 0.0f;
       float GetPress = 0.0f;
        public Form1()
        {
            InitializeComponent();
            serialPort1.Encoding = Encoding.GetEncoding("GB2312");  //支持汉字
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

            serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
        }

        private void Form1_Load(object sender, System.EventArgs e)
        {
            string strPath = Application.StartupPath.Substring(0, Application.StartupPath.Substring(0, Application.StartupPath.LastIndexOf("\\")).LastIndexOf("\\"));
            //MessageBox.Show("要想获得帮助,请按F1");
            strPath += @"\温度测量系统说明.htm";//温度测量系统说明
            textBox15.AppendText(strPath);

            helpProvider1.HelpNamespace = strPath;
            helpProvider1.SetShowHelp(this, true);

        }

        private void button1_Click(object sender, EventArgs e)
        {
            //刷新可用串口
            if (!serialPort1.IsOpen)
            {
                SearchAndAddSerialToComboBox(serialPort1, comboBox1);//扫描端口号,并将可用端口添加至下拉列表
            }
        }
        private void SearchAndAddSerialToComboBox(SerialPort MyPort, ComboBox MyBox)
        {
            string[] ComputerPortName = SerialPort.GetPortNames();  //获取本机串口列表

            string SerialName = "";
            if (MyPort == serialPort1)
            {
                SerialName = "串口1";
            }
            bool MyBackupPortFlag = false;  //备份端口号可用标志位
            GetPrivateProfileString(SerialName, "端口号", "", BackupBuf, 10, FileName);  //获取备份的端口号
            string MyBackupPortName = BackupBuf.ToString();

            //添加端口号
            MyBox.Items.Clear();  //清空ComboBox内容
            for (int i = 0; i < ComputerPortName.Length; i++) //循环
            {
                if (MyBackupPortName == ComputerPortName[i])  //之前的端口号可用,置位标志位
                {
                    MyBackupPortFlag = true;
                }

                try  //核心原理是依靠try和catch完成遍历
                {
                    MyPort.PortName = ComputerPortName[i];
                    MyPort.Open();                          //如果失败,后面的代码不会执行          
                    MyBox.Items.Add(MyPort.PortName);       //打开成功,添加至下拉列表
                    MyPort.Close();                         //关闭
                }
                catch
                {

                }
            }
            //端口号赋初值
            if (MyBackupPortFlag == true)
            {
                MyBox.Text = MyBackupPortName; //添加备份的端口号
            }
            else
            {
                if (ComputerPortName.Length > 0)
                {
                    MyBox.Text = ComputerPortName[ComputerPortName.Length - 1]; //添加数值大的端口号
                }
                else
                {
                    if (MyPort == serialPort1)
                    {
                        textBox15.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                        textBox15.AppendText("没有检测到串口工具!\r\n");
                    }
                   
                }
            }
        }

        private void button2_Click(object sender, System.EventArgs e)
        {
            if (button2.Text == "关闭串口") //串口已打开,此时关闭串口                                     
            {
                try
                {
                    serialPort1.Close();
                    button7.BackColor = Color.Red;
                    button2.Text = "打开串口";
                }
                catch { }
            }
            else //打开串口
            {
                try
                {
                    serialPort1.PortName = comboBox1.Text;    //端口号
                    serialPort1.BaudRate = Convert.ToInt32(comboBox14.Text, 10); //获取波特率,字符数转10进制数
                    serialPort1.Open();                       //打开端口
                    button7.BackColor = Color.LimeGreen;
                    button2.Text = "关闭串口";

                    WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);
                }
                catch
                {
                    serialPort1.Close();
                    button7.BackColor = Color.Red;
                    button2.Text = "打开串口";
                    textBox15.AppendText("串口打开失败!\r\n");
                }
            }
        }

//串口接收数据serialPort1_DataReceived
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] Data = new byte[serialPort1.BytesToRead];    //定义缓冲区,因为串口接收事件触发时字节数不固定
            bool Rec_Flag = true;
            bool UpdateData = false;
     //单设备,如果是接收的数据字节长度小于13,接收标记等于假
    //帧头0+帧头1+------功能码+器件码+数据码1+数据码2+数据码3+数据码4+数据码5+数据码6+校验码CSUM+帧尾0+帧尾1。(0-12)
            if (Data.Length < 13)
            {
                Rec_Flag = false;
                //将接收的数据显示在文本框中
                UpdateChanData(textBox1, Data, 1);
                UpdateChanData(textBox2, Data, 2);
                UpdateChanData(textBox3, Data, 3);
                UpdateChanData(textBox4, Data, 4);
                UpdateChanData(textBox5, Data, 5);
                UpdateChanData(textBox6, Data, 6);
                UpdateChanData(textBox7, Data, 7);
                UpdateChanData(textBox8, Data, 8);
                UpdateChanData(textBox9, Data, 9);
                UpdateChanData(textBox10, Data, 10);
                UpdateChanData(textBox11, Data, 11);
                UpdateChanData(textBox12, Data, 12);
                UpdateChanData(textBox13, Data, 13);
            }    
            //接收到一帧数据
            if (Rec_Flag == true)
            {
                try
                {
                    //将缓冲区的数据读取,放在data数组中
                    serialPort1.Read(Data, 0, Data.Length);
                    textBox15.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "收 <- ");
                   
                    foreach (byte Member in Data)        //遍历用法
                    {
                        string str = Convert.ToString(Member, 16).ToUpper();//转换成16进制的字符
                        //
                        textBox15.AppendText((str.Length == 1 ? "0" + str : str) + " ");
                    }
                    textBox15.AppendText("\r\n");
                    textBox15.AppendText("\r\n");
                }
                catch { }

                //数据校验
                if (Data.Length == 13)  //单设备模式
                {
           //帧头0+帧头1+------功能码+器件码+数据码1+数据码2+数据码3+数据码4+数据码5+数据码6+校验码CSUM+帧尾0+帧尾1。
               //校验和
                    //判断帧头0和帧头1是不是相等,是的话,进行后面的处理,否则退出
                    if (Data[0] == Head[0])
                    {
                        if (Data[1] == Head[1])
                        {
                            int csum = CheckSumAction(Data, 13);
                            if (Data[10] == csum)  //校验正确
                            {
                                UpdateData = true;
                            }
                            else //校验错误  
                            {
                                textBox15.AppendText("\r\n和校验值错误,请检查校验算法!!\r\n");
                            }
                        }
                        else
                            return;
                    }
                    else
                        return;     
                }
                else
                {
                    textBox15.AppendText("\r\n返回的字节数不对!!\r\n");
                }


                数据解析,校验正确,那么显示在文本框中
                if (UpdateData == true)
                {               
                    UpdateChanData(textBox1, Data, 1);
                    UpdateChanData(textBox2, Data, 2);
                    UpdateChanData(textBox3, Data, 3);
                    UpdateChanData(textBox4, Data, 4);
                    UpdateChanData(textBox5, Data, 5);
                    UpdateChanData(textBox6, Data, 6);
                    UpdateChanData(textBox7, Data, 7);
                    UpdateChanData(textBox8, Data, 8);
                    UpdateChanData(textBox9, Data, 9);
                    UpdateChanData(textBox10, Data, 10);
                    UpdateChanData(textBox11, Data, 11);
                    UpdateChanData(textBox12, Data, 12);
                    UpdateChanData(textBox13, Data, 13);
                    //接收的数据OK,判断是什么信息
                    //根据接收到的功能码进行判断,
                    switch (Data[2])
                    { 
            //应答信号处理,3秒内进行处理,超过3秒没有收到应答,进行应答错误提示-------------------
                        case 0x02://IO口应答信号
                            switch (Data[3])//设备的号码
                            { 
                                case 0x00:
                                    if (Data[4] == 0x01)
                                    {
                                        IONum0Ack = true;
                                        try
                                        {
                                            timer1.Stop();
                                        }
                                        catch { }
                                    }
                                    else
                                        IONum0Ack = false;
                                    break;
                                case 0x01:
                                    break;
                                default: break;
                            }   
                               break;
                        case 0x12://温度设置应答信号
                               switch (Data[3])//设备的号码
                               {
                                   case 0x00:
                                       if (Data[4] == 0x01)
                                       {  TemNum0Ack = true;
                                           try
                                        {
                                            timer1.Stop();
                                        }
                                        catch { }
                                        }
                                       else
                                           TemNum0Ack = false;
                                       break;
                                   case 0x01:
                                       break;
                                   default: break;
                               }   
                            break;
                        case 0x32://定时时间设置应答信号
                            switch (Data[3])//设备的号码
                            {
                                case 0x00:
                                    if (Data[4] == 0x01)
                                    {
                                        TimerNum0Ack = true;
                                        try
                                        {
                                            timer1.Stop();
                                        }
                                        catch { }
                                    }
                                    else
                                        TimerNum0Ack = false;
                                    break;
                                case 0x01:
                                    break;
                                default: break;
                            }   
                            break;
                        case 0x46://KP设置应答信号
                            switch (Data[3])//设备的号码
                            {
                                case 0x00:
                                    if (Data[4] == 0x01)
                                    {
                                        KPNum0Ack = true;
                                        try
                                        {
                                            timer1.Stop();
                                        }
                                        catch { }
                                      }
                                    else
                                        KPNum0Ack = false;
                                    break;
                                case 0x01:
                                    break;
                                default: break;
                            }   
                            break;
                        case 0x47://KI设置应答信号
                            switch (Data[3])//设备的号码
                            {
                                case 0x00:
                                    if (Data[4] == 0x01)
                                    {
                                        KINum0Ack = true;
                                        try
                                        {
                                            timer1.Stop();
                                        }
                                        catch { }
                                    }
                                    else
                                        KINum0Ack = false;
                                    break;
                                case 0x01:
                                    break;
                                default: break;
                            }   
                            break;
                        case 0x48://KD设置应答信号
                            switch (Data[3])//设备的号码
                            {
                                case 0x00:
                                    if (Data[4] == 0x01)
                                    {
                                        KDNum0Ack = true;
                                        try
                                        {
                                            timer1.Stop();
                                        }
                                        catch { }
                                     }
                                    else
                                        KDNum0Ack = false;
                                    break;
                                case 0x01:
                                    break;
                                default: break;
                            }  
                            break;
                        case 0x52://压力设置应答信号
                            switch (Data[3])//设备的号码
                            {
                                case 0x00:
                                    if (Data[4] == 0x01)
                                    {
                                        PressNum0Ack = true;
                                        try
                                        {
                                            timer1.Stop();
                                        }
                                        catch { }
                                    }
                                    else
                                        PressNum0Ack = false;
                                    break;
                                case 0x01:
                                    break;
                                default: break;
                            }  
                            break;
                        case 0x99://单片机检测系统出错
                            MessageBox.Show("单片机检测系统出错,请检查!", "错误");
                            try
                            {
                                timer1.Stop();
                            }
                            catch { }
                            break;
                            
                        //接收数据的功能
                        case 0x01://开关信号的读取
                            {
                                //判断是那个设备的开关信号
                                switch(Data[3])
                                {
                                    case 0x00://第一个LED设备码
                                            //判断开关的状态
                                        {
                                            if (Data[4] == 0x01)
                                                button4.BackColor = Color.LimeGreen;
                                            else
                                                button4.BackColor = Color.Red;
                                        }       
                                        break;
                                    case 0x01:
                                                                  
                                         break;
                                    case 0x02:

                                        break;

                                }
                                
                            }
                            break;
                        case 0x11://data[2]读取温度,读取的温度是整型
                            {
                                switch (Data[3])//判断第几个温度传感器
                                {
                                    case 0x00://第一个热电偶
                                        //+12345度,不做负数的温度测量
                                        {
                                            //先读取数值,除以100,再添加正负号
                                            int GetTemper0 = Data[5] * 10000 + Data[6] * 1000 + Data[7] * 100 + Data[8] * 10 + Data[9];
                                            GetTemper = (float)GetTemper0 / 100;
                                            if (Data[4] == '-')
                                                GetTemper = (-1) * GetTemper;
                                            textBox24.Text = Convert.ToString(GetTemper);//显示数据                        
                                        }
                                        break;
                                    case 0x01://第二个热电偶

                                        break;
                                    default: break; 
                                }
                            
                            
                            }
                            break;
                        case 0x31://读取单片机定时时间;
                            {
                                switch (Data[3])//判断哪个热传感器的定时时间
                                {
                                    case 0x00://第一个热电偶的已经定时时间                   
                                        GetHourPass =Data[4]*10+Data[5];
                                        GetMinutePass = Data[6] * 10 + Data[7];
                                        GetSecPass = Data[8] * 10 + Data[9];

                                        //将数据显示在文本框中
                                        textBox21.Text = Convert.ToString(GetMinutePass);//显示定时经过的分
                                        textBox23.Text = Convert.ToString(GetSecPass);//显示定时经过的秒
                                        break;
                                    case 0x01://1个热电偶的剩余的定时时间
                                        GetHourDown =Data[4]*10+Data[5];
                                        GetMinuteDown = Data[6] * 10 + Data[7];
                                        GetSecDown = Data[8] * 10 + Data[9];

                                        //将数据显示在文本框中
                                        textBox25.Text = Convert.ToString(GetMinuteDown);//显示定时经过的分
                                        textBox26.Text = Convert.ToString(GetSecDown);//显示定时经过的秒
                                        break;

                                    case 0x02://第一个热电偶目标定时的时间
                                        GetHourSet =Data[4]*10+Data[5];
                                        GetMinuteSet = Data[6] * 10 + Data[7];
                                        GetSecSet = Data[8] * 10 + Data[9];

                                        //将数据显示在文本框中
                                        textBox16.Text = Convert.ToString(GetMinuteSet);//显示定时经过的分
                                        textBox22.Text = Convert.ToString(GetSecSet);//显示定时经过的秒
                                        break;

                                    default: break; 
                                }
                            }
                            break;
                        case 0x43://读取当前P参数
                            {
                                switch (Data[3])//判断哪个热传感器的定时时间
                                {
                                    case 0x00://第一个热电偶的KP
                                        int KPtemp= Data[4]*100000+Data[5] * 10000 + Data[6] * 1000 + Data[7] * 100 + Data[8] * 10 + Data[9];
                                         GetKP = (float)KPtemp / 100;                          
                                         textBox27.Text = Convert.ToString(GetKP);//显示数据     
                                        break;
                                    case 0x01://第二个热电偶的KP

                                        break;
                                    default: break;
                                }
                            }
                            break;
                        case 0x44://读取当前KI参数
                            {
                                switch (Data[3])//判断哪个热传感器的定时时间
                                {
                                    case 0x00://第一个热电偶的KI
                                        int KItemp = Data[4] * 100000 + Data[5] * 10000 + Data[6] * 1000 + Data[7] * 100 + Data[8] * 10 + Data[9];
                                         GetKI = (float)KItemp / 100;                          
                                         textBox28.Text = Convert.ToString(GetKI);//显示数据   
                                        break;
                                    case 0x01://第二个热电偶的KI

                                        break;
                                    default: break;
                                }
                            }
                            break;
                        case 0x45://读取当前KD参数
                            {
                                switch (Data[3])//判断哪个热传感器的定时时间
                                {
                                    case 0x00://第一个热电偶的KD
                                        int KDtemp = Data[4] * 100000 + Data[5] * 10000 + Data[6] * 1000 + Data[7] * 100 + Data[8] * 10 + Data[9];
                                         GetKD = (float)KDtemp / 100;                          
                                         textBox29.Text = Convert.ToString(GetKD);//显示数据
                                        break;
                                    case 0x01://第二个热电偶的KD

                                        break;
                                    default: break;
                                }
                            }
                            break;


                        default:break;
                    }
                }
            }
        }
//------------------------------------------------------校验和计算
        private int CheckSumAction(byte[] Data, byte DataLEN)
        {
            int csum = 0x0000;//UInt16
            //计算帧头0,帧头1后面的数据的校验码,长度=13
            //帧头0+帧头1+------功能码+器件码+数据码1+数据码2+数据码3+数据码4+数据码5+数据码6+校验码CSUM+帧尾0+帧尾1。
            for (byte i = 2; i < DataLEN-3; i++)
            {
                csum += Data[i];
            }
            csum = csum % 256;
            return csum;
        }

          private void UpdateChanData(TextBox MyTextBox,byte[] Data,byte ChanNummber)
        {
            try
            {
                //   textBox15.AppendText("0x"+(str.Length == 1 ? "0" + str : str) + " ");
                string strtemp= Convert.ToString(Data[ChanNummber - 1],16).ToUpper();
                int datatemp=Data[ChanNummber - 1];
                if(datatemp<16)
                    strtemp="0"+strtemp;
                strtemp="0x"+strtemp;
                MyTextBox.Text =strtemp;
            }
            catch { }
        }

 通过串口,发送数据,串口通讯
        private void WriteByteToSerialPort1(TextBox MyTextBox, TextBox ChanTextBox)
        {
            //if (serialPort1.IsOpen)
            //{
                try
                {
                    if (Convert.ToByte(MyTextBox.Text) > 200)//为什么是200?
                    {
                        textBox15.AppendText("\r\n数据大于200,无效!!\r\n");
                        MyTextBox.Text = ChanTextBox.Text;
                    }
                    else
                    {
                        if (true)  //单设备
                        {
                            //下发
                            try
                            {
                                byte[] Data = new byte[10] { 0x21, 0x22, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00 };
                                Data[Convert.ToByte(MyTextBox.Tag) + 1] = Convert.ToByte(MyTextBox.Text);
                                //插入CRC
                                int csum = CheckSumAction(Data,13); 
                                Data[10] = Convert.ToByte(csum);
                           
                                 System.Threading.Thread.Sleep(100);
                                 textBox15.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "发 -> ");
                                 serialPort1.Write(Data, 0, 10);//发送
                                 System.Threading.Thread.Sleep(100);

                                foreach (byte Member in Data)                                                   //遍历用法
                                {
                                    string str = Convert.ToString(Member, 16).ToUpper();
                                    textBox15.AppendText((str.Length == 1 ? "0" + str : str) + " ");

                                    //   textBox15.AppendText("0x"+(str.Length == 1 ? "0" + str : str) + " ");
                                }
                                textBox15.AppendText("\r\n");
                            }
                            catch
                            {
                                textBox15.AppendText("\r\n单设备模式下发错误!!\r\n");
                                serialPort1.Close();
                                button7.BackColor = Color.Red;
                                button2.Text = "打开串口";
                            }
                        }              
                    }
                }
                catch
                {
                    textBox15.AppendText("\r\n数据无效!!\r\n");
                    MyTextBox.Text = ChanTextBox.Text;
                }
            //}
        }

        private void button11_Click(object sender, System.EventArgs e)
        {
            MessageBox.Show("输入字符有误", "操作说明");//出错提示

        }
//串口1发送一个字节
        private void SendDataToSerialPort(SerialPort MyPort, byte DataToSend)
        {
            byte[] DatasToWrite = new byte[] { DataToSend };
            if (serialPort1.IsOpen)
            {
                try
                {
                    MyPort.Write(DatasToWrite, 0, 1);
                    timer1.Interval = 3 * 1000;
                    timer1.Start();
                }
                catch
                { 
                    MessageBox.Show("串口数据写入错误","错误");
                }
            }
        }

//*********************以上是代码
    }//不能删
}
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值