串口数据波形显示

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

namespace WindowsFormsApp3
{
    public partial class Drawer : Form
    {
        private const int Unit_length = 32;//单元格大小
        private int DrawStep = 8;//默认绘制单位
        private const int Y_Max = 512;//Y轴最大数值
        private const int MaxStep = 33;//绘制单位最大值
        private const int MinStep = 1;//绘制最小值
        private const int StartPrint = 32;//点坐标偏移量
        private List<byte> DataList = new List<byte>();
        private Pen TablePen = new Pen(Color.FromArgb(0x00, 0x00, 0x00));//轴线颜色
        private Pen LinesPen = new Pen(Color.FromArgb(0xa0, 0x00, 0x00));//波形颜色       
       //实例化委托对象
        public ShowWindow ShowMainWindow; //定义显示主窗口委托访问权限为public
        public HideWindow HideMainWindow; //定义隐藏主窗口委托
        public OpenPort OpenSerialPort;   //定义打开串口委托
        public ClosePort CloseSerialPort; //定义关闭串口委托
        public GetMainPos GetMainPos;     //定义获取主窗口信息委托(自动对齐)
        public GetMainWidth GetMainWidth; //定义获取主窗口宽度(自动对齐)
       //定义快捷键状态
        private bool KeyShift, KeyShowMain, KeyHideMain, KeyExit, KeyOpen, KeyClose, KeyStepUp, KeyStepDown;//定义快捷键状态



        public Drawer()
        {
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer|ControlStyles.UserPaint|
                ControlStyles.AllPaintingInWmPaint,true);//开启双缓冲
            this.UpdateStyles();
            InitializeComponent();
        }

        public void AddDate(byte[] Data)
        {
            for (int i = 0; i < Data.Length; i++)
            {
                DataList.Add(Data[i]);
            }
            Invalidate();
        }

        //绘制xy轴网格,绘制波形
        private void Form1_Paint(object sender, PaintEventArgs e)//画
        {
            String Str = "";
            System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();
            e.Graphics.FillRectangle(Brushes.White, e.Graphics.ClipBounds);
            //Draw Y 纵向轴绘制(y坐标绘制)
            for (int i = 0; i <= this.ClientRectangle.Width / Unit_length; i++)
            {
                e.Graphics.DrawLine(TablePen, StartPrint + i * Unit_length, StartPrint, StartPrint + i * Unit_length, StartPrint + Y_Max);//画线

                gp.AddString((i * (Unit_length / DrawStep)).ToString(), this.Font.FontFamily, (int)FontStyle.Regular, 12, new RectangleF(StartPrint + i * Unit_length - 7, this.ClientRectangle.Height - StartPrint + 4, 400, 50), null);//添加文字
            }

            //Draw X 横向轴绘制(x坐标绘制)
            for (int i = 0; i <= this.ClientRectangle.Height / Unit_length; i++)
            {
                e.Graphics.DrawLine(TablePen, StartPrint, (i + 1) * Unit_length, this.ClientRectangle.Width, (i + 1) * Unit_length);//画线
                Str = ((16 - i) * 16).ToString("X");
                Str = "0x" + (Str.Length == 1 ? Str + "0" : Str);
                if (i == 0)
                    Str = "0xFF";
                if (i == 17)
                    break;
                gp.AddString(Str, this.Font.FontFamily, (int)FontStyle.Regular, 14, new RectangleF(0, StartPrint + i * Unit_length - 8, 400, 50), null);//添加文字
            }
            e.Graphics.DrawPath(Pens.Black, gp);//写文字


            if (DataList.Count - 1 >= (this.ClientRectangle.Width - StartPrint) / DrawStep) //如果数据量大于可容纳的数据量,即删除最左数据 | 波形左移
            {
                DataList.RemoveRange(0, DataList.Count - (this.ClientRectangle.Width - StartPrint) / DrawStep - 1);
            }

            //绘制波形 DataList.Count;
            for (int i = 0; i < DataList.Count - 1; i++)//绘制
            {
                e.Graphics.DrawLine(LinesPen, StartPrint + i * DrawStep, 17 * Unit_length - DataList[i] * 2, StartPrint + (i + 1) * DrawStep, 17 * Unit_length - DataList[i + 1] * 2);
            }
        }

        //按下松开后才判断
        private void Form1_KeyUp(object sender, KeyEventArgs e)//按键弹开,执行对应动作
        {
            if (KeyShift)
            {
                if (KeyShowMain)//显示主窗体快捷键
                {
                    ShowMainWindow();
                    Rectangle Rect = Screen.GetWorkingArea(this);
                    SetWindow(Rect.Width - GetMainWidth(), new Point(GetMainWidth(), GetMainPos().Y));//缩小自己
                    KeyShowMain = false;
                }
                else
                {
                    if (KeyOpen)
                    {
                        OpenSerialPort();//打开主窗口串口
                        KeyOpen = false;
                    }
                    else
                    {
                        if (KeyClose)
                        {
                            CloseSerialPort();//关闭主窗口串口
                            KeyClose = false;
                        }
                        else
                        {
                            if (KeyExit)
                            {
                                KeyExit = false;//退出自己
                                Close();
                            }
                            else
                            {
                                if (KeyStepUp)
                                {
                                    if (DrawStep < MaxStep)//绘制单位递增
                                        DrawStep++;
                                    Invalidate();
                                    KeyStepUp = false;
                                }
                                else
                                {
                                    if (KeyStepDown)
                                    {
                                        if (DrawStep > MinStep)//绘制单位递减
                                            DrawStep--;
                                        Invalidate();
                                        KeyStepDown = false;
                                    }
                                    else
                                    {
                                        if (KeyHideMain)
                                        {
                                            HideMainWindow();//隐藏主窗口并扩大自己
                                            Rectangle Rect = Screen.GetWorkingArea(this);
                                            SetWindow(Rect.Width, new Point(0, GetMainPos().Y));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else//如果是其他按键,清空所有标志位
            {
                KeyClose = false;
                KeyOpen = false;
                KeyShowMain = false;
                KeyExit = false;
                KeyStepUp = false;
                KeyStepDown = false;
            }
            KeyShift = false;//清空shift标志位
        }


        private void Form1_KeyDown(object sender, KeyEventArgs e)//快捷键检测
        {
            if (e.Shift)//shift功能键按下
                KeyShift = true;//标志位置位
            switch (e.KeyCode)//功能标志置位
            {
                case Keys.S://显示主窗口
                    KeyShowMain = true;
                    break;
                case Keys.E://退出波形显示
                    KeyExit = true;
                    break;
                case Keys.O://打开串口
                    KeyOpen = true;
                    break;
                case Keys.C://关闭串口
                    KeyClose = true;
                    break;
                case Keys.Up://放大波形
                    KeyStepUp = true;
                    break;
                case Keys.H://隐藏主窗口
                    KeyHideMain = true;
                    break;
                case Keys.Down://缩小波形
                    KeyStepDown = true;
                    break;
                default:
                    break;
            }
        }

        //主窗口设置自己 的 大小位——在MainForm的CreateDisplayer调用
        public void SetWindow(int width, Point Pt)//允许主窗口设置自己
        {
            int height = this.ClientRectangle.Height;
            height = this.Height - height;
            int BorderWeigh = this.Width - this.ClientRectangle.Width;
            this.Size = new Size(width - (width - BorderWeigh) % Unit_length, height + Y_Max + StartPrint + Unit_length);
            this.Location = Pt;
        }



        private void Drawer_Load(object sender, EventArgs e)
        {
        }
    }
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace WindowsFormsApp3
{
    //定义委托
    public delegate void ShowWindow();
    public delegate void HideWindow();
    public delegate void OpenPort();
    public delegate void ClosePort();
    public delegate Point GetMainPos();
    public delegate int GetMainWidth();

    public partial class Form1 : Form
    {
        Drawer Displayer;
        public Form1()
        {
            InitializeComponent();
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
           
        }
        //委托函数编写
        //关闭串口,供委托调用
        public void ClosePort()
        {
            try
            {
                serialPort1.Close();
            }
            catch (System.Exception)
            {

            }
        }

        //打开串口,供委托调用
        public void OpenPort()
        {
            try
            {
                serialPort1.Open();
            }
            catch (System.Exception)
            {
                MessageBox.Show("串口打开失败,请检查", "错误");
            }
        }

        //供委托调用
        private Point GetMyPos()
        {
            return this.Location;
        }

        //供委托调用
        public void ShowMe()
        {
            this.Show();
        }

        //供委托调用
        public void HideMe()
        {
            this.Hide();
        }

        //供委托调用
        int GetMyWidth()
        {
            return this.Width;
        }


        //创建&显示绘图窗口 | 初始化类成员委托
        private void CreateNewDrawer()//创建Drawer窗口
        {
            //创建新对象
            Displayer = new Drawer();
            //初始化类成员委托            
            Displayer.ShowMainWindow = new ShowWindow(ShowMe);
            Displayer.HideMainWindow = new HideWindow(HideMe);
            Displayer.GetMainPos = new GetMainPos(GetMyPos);
            Displayer.CloseSerialPort = new ClosePort(ClosePort);
            Displayer.OpenSerialPort = new OpenPort(OpenPort);
            Displayer.GetMainWidth = new GetMainWidth(GetMyWidth);
            //显示窗口
            Displayer.Show();
        }



        private void Form1_Load(object sender, EventArgs e)
        {
            /*string str;
            for (int i = 0; i < 256; i++)
            {
                str = i.ToString("X").ToUpper();//i.ToString("X")是将数字转换为16进制,同时字母大写
                if (str.Length == 1)
                {
                    str = "0" + str;//如果是一位的(0xA),为了对齐,在数据前加一个0(0x0A)
                }
                comboBox1.Items.Add("0x" + str);
            }
            comboBox1.Text = "0X00";*/
            for (int i = 0; i < 20; i++)
            {
                comboBox1.Items.Add("COM"+i);
            }
            comboBox1.Text = "COM1";
            comboBox2.Items.Add("9600");
           
           
        }

        private void SearAndAdd(SerialPort serialPort ,ComboBox comboBox)
        {
            string MyString ;
            string Buffer;
            comboBox3.Items.Clear();
            for (int i = 0; i < 5; i++)
            {
                try
                {
                    Buffer = "COM" + i.ToString();
                    serialPort.PortName = Buffer;
                    serialPort.Open();
                    MyString = Buffer;
                    comboBox3.Items.Add(MyString);
                    serialPort.Close();
                }
                catch
                {

                }              
            }
            comboBox3.SelectedItem = comboBox3.Items[0];
        }

        private void port_DataReceive(object sender, SerialDataReceivedEventArgs e)//串口接收事件
        {
            if (!radioButton3.Checked)//如果接收模式为字符模式
            {
                string str = serialPort1.ReadExisting();
                textBox2.AppendText(str+"\r\n");//
            }
            else
            {
                byte data;
                data=(byte)serialPort1.ReadByte();//转换为byte类型
                byte[] Data=new byte[serialPort1.BytesToRead];
                serialPort1.Read(Data, 0, Data.Length);
                if (Displayer != null)
                {
                    Displayer.AddDate(Data);
                }
                string str=Convert.ToString(data,16).ToUpper();//转换为大写16进制符
                textBox2.AppendText("0x" + (str.Length == 1 ? "0" + str : str) + "\r\n");
            }
          
        }

     
        /// <summary>
        /// 点击发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            /* string data = comboBox1.Text;
             string converdata = data.Substring(2, 2);
             byte[] buffer = new byte[1];
             buffer[0]=Convert.ToByte(converdata,16);//将16位字符转换为Byte字符*/
            byte[] Date=new byte[1];
            if (serialPort1.IsOpen)
            {
                if (textBox1.Text != "")
                {
                    if (!radioButton1.Checked)//如果发送模式是字符模式
                    {
                        try
                        {
                            serialPort1.Write(textBox1.Text);          
                        }
                        catch 
                        {
                            MessageBox.Show("串口数据写入错误");
                        }
                    }
                    else
                    {
                        for (int i = 0; i < (textBox1.Text.Length-textBox1.Text.Length%2)/2; i++)
                        {
                            Date[0] = Convert.ToByte(textBox1.Text.Substring(i*2,2),16);
                            serialPort1.Write(Date, 0, 1);
                        }
                        if (textBox1.Text.Length % 2 != 0)
                        {
                            Date[0] = Convert.ToByte(textBox2.Text.Substring(textBox1.Text.Length - 1, 1),16);
                            serialPort1.Write(Date, 0, 1);
                        }
                    }
                }
            }
        }

        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// 打开端口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                serialPort1.PortName=comboBox1.Text;
                serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);
                serialPort1.Open();
                button2.Enabled = false;
                button3.Enabled=true;
            }
            catch 
            {
                MessageBox.Show("端口错误");
            }
        }

        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {

        }

        private void button4_Click(object sender, EventArgs e)
        {
            SearAndAdd(serialPort1, comboBox3);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
           
        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (Displayer == null)//第一次创建Displayer = null
            {
                CreateDisplayer();
            }
            else
            {
                //多次创建通过判断IsDisposed确定串口是否已关闭,避免多次创建
                if (Displayer.IsDisposed)
                {
                    CreateDisplayer();
                }
            }
        }

        //创建绘图界面 & 设置界面大小 与 主窗口 在 显示器屏幕 平行最大化显示
        private void CreateDisplayer()
        {
            this.Left = 0;
            CreateNewDrawer();
            Rectangle Rect = Screen.GetWorkingArea(this);
            Displayer.SetWindow(Rect.Width - this.Width, new Point(this.Width, this.Top));//设置绘制窗口宽度,以及坐标
        }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值