c#串口调试助手温度曲线的显示-上位机的开发-串口参数介绍

文章目录

  • c#串口调试助手、上位机
    • 串口参数介绍
    • 串口通信模块(SerialPort)
    • 串口窗口介绍
    • 代码编写

c#串口调试助手、上位机

简介
此串口调试助手是在windows下开发的,工具是 Visual Studio 2017开发的,串口调试助手支持 600~~115200波特率,端口号是 CMO1~~CMO9,支持数据位、停止位、奇偶位,支持数据的接收与发送,接收方式十六进制、字符的选择,对接收端数据的清空,并能对温度传感器数据进行接收与绘折线图,并且能设置正常温度现实的区间,及时判断温度是否显示正常与否,并能对曲线的显示进行刷新重新绘制。
实验问题与修正
在这篇博客中我会把我所遇到的问题、自己写的代码、与解决的方法分享出来
先上一下实验图片
c#串口调试助手温度曲线的显示-上位机的开发-串口参数介绍_第1张图片

串口参数介绍

简介
典型地,串口用于ASCII码字符的传输。通信使用3根线完成:(1)地线,(2)发送,(3)接收。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。
波特率
这是一个衡量符号传输速率的参数。它表示每秒钟传送的符号的个数。例如300波特表示每秒钟发送300个符号。当我们提到时钟周期时,我们就是指波特率,例如如果协议需要4800波特率,那么时钟是4800Hz。这意味着串口通信在数据线上的采样率为4800Hz。通常电话线的波特率为14400,28800和36600。波特率可以远远大于这些值,但是波特率和距离成反比。高波特率常常用于放置的很近的仪器间的通信,典型的例子就是GPIB设备的通信。
数据位
数据位表示一组数据实际包含的数据位数。数据位紧跟在起始位之后,是通信中的真正有效信息。数据位的位数由通信双方共同约定,一般可以是6位、7位或8位,比如标准的ASCII码是0—127(7位),扩展的ASCII码是0—255(8位)。传输数据时先传送字符的低位,后传送字符的高位,即低位(LSB)在前,高位(MSB)在后。
奇偶位
奇偶校验通常用在数据通信中来保证数据的有效性。奇偶校验位是一个表示给定位数的二进制数中 1 的个数是奇数还是偶数的二进制数。奇偶校验位是最简单的错误检测码。
停止位
用于表示单个包的最后一位。典型的值为1,1.5和2位。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。

串口通信模块(SerialPort)

  • 配置IO文件

using System.IO;
using System.IO.Ports;

  • 图标
    c#串口调试助手温度曲线的显示-上位机的开发-串口参数介绍_第2张图片
属性 介绍
BaudRate 波特率
DataBits 数据位
Parity 奇偶校验位
PortName 端口号
StopBits 停止位
ByteToRead 获取输入缓冲区的
IsOpen 获取是否开启串口
  • Serialport通信模块的事件
    c#串口调试助手温度曲线的显示-上位机的开发-串口参数介绍_第3张图片
    在这里我们只用到DataReceived串口接收函数,如需了解另外两个请自己查阅
事件 介绍
DataReceived 串口接收函数
ErrorReceived 串口数据接收错误
PinChanged 串口号发生改变

串口窗口介绍

c#串口调试助手温度曲线的显示-上位机的开发-串口参数介绍_第4张图片
由图可以看出正常温度区间设置的是20-25度之间,测试温度的过程中温度曲线黄色的为正常的曲线,红色的曲线为温度异常。温度刷新,温度曲线重新读取画线

在窗体上添加4个Groupbox控件
第一个:串口设置
第二的:接收数据
第三个:发送数据
第四个:温度曲线显示

代码编写

  1. 串口初始化函数
private void button_open_Click(object sender, EventArgs e)
        {
           // if(Button_on == 1)
            if (!serialPort1.IsOpen)//如果串口是开
            {
                serialPort1.PortName = comboBox1.Text;//端口号
                serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text, 10);//波特率
                float f = Convert.ToSingle(comboBox3.Text.Trim());//trim去除字符串前后的空格
                if (f == 0)//设置停止位
                    serialPort1.StopBits = StopBits.None;
                else if (f == 1.5)
                    serialPort1.StopBits = StopBits.OnePointFive;
                else if (f == 1)
                    serialPort1.StopBits = StopBits.One;
                else if (f == 2)
                    serialPort1.StopBits = StopBits.Two;
                else
                    serialPort1.StopBits = StopBits.One;
                //设置数据位
                serialPort1.DataBits = Convert.ToInt32(comboBox4.Text.Trim());
                //设置奇偶校验位
                string s = comboBox5.Text.Trim();
                if (s.CompareTo("无") == 0)
                    serialPort1.Parity = Parity.None;
                else if (s.CompareTo("奇校验") == 0)
                    serialPort1.Parity = Parity.Odd;
                else if (s.CompareTo("偶校验") == 0)
                    serialPort1.Parity = Parity.Even;
                else
                    serialPort1.Parity = Parity.None;
                try
                {
                    serialPort1.Open();     //打开串口
                    button_open.Text = "关闭串口";
                    comboBox1.Enabled = false;//关闭使能
                    comboBox2.Enabled = false;
                    comboBox3.Enabled = false;
                    comboBox4.Enabled = false;
                    comboBox5.Enabled = false;
                    comboBox6.Enabled = false;
                    comboBox7.Enabled = false;
                }
                catch
                {
                    MessageBox.Show("串口打开失败!");
                }
            }
            else//如果串口是打开的则将其关闭
            {
                serialPort1.Close();
                button_open.Text = "打开串口";
                comboBox1.Enabled = true;//使能配置
                comboBox2.Enabled = true;
                comboBox3.Enabled = true;
                comboBox4.Enabled = true;
                comboBox5.Enabled = true;
                comboBox6.Enabled = true;
                comboBox7.Enabled = true;
            }

        }
  1. 画坐标图
    c#串口调试助手温度曲线的显示-上位机的开发-串口参数介绍_第5张图片
  • 画坐标时用到头文件

using System.Drawing;
using System.Drawing.Drawing2D;

  • 画线时用到类graphics

graphics是抽象函数不能实例化,并且画线的时候编辑器是以左上角为坐标原点画的,想要把它改成左下角,只能自己计算坐标点,根据自己的需求把它画成称自己想要的,如上图我把(50,218)这个坐标表示成原点

注意:Graphics是在控件Groupbox控件下事件Paint下写的

private void groupBox4_Paint(object sender, PaintEventArgs e)
        {
            FontFamily family = new FontFamily("Arial");//实例化字体的类型
            int fontstyle = (int)FontStyle.Italic;//设置字体的样式
            GraphicsPath gp = new GraphicsPath();
            string Str;
            //Draw y纵向轴绘制
            for (int i = 0; i <= 14; i++)
            {
                e.Graphics.DrawLine(TablePen, StartPrint + i * Unit_length, StartPrint - 32, StartPrint + i * Unit_length, 10 * Unit_length + 18);//画线
                gp.AddString((i * 10).ToString(), family, fontstyle, 8, new RectangleF(StartPrint + i * Unit_length - 7, 10 * Unit_length + 18 + 4, 400, 50), null);//添加文字
            }
            gp.AddString("时间(s)", family, fontstyle, 12, new RectangleF(groupBox4.ClientRectangle.Width / 2 , 9 * Unit_length + 55, 400, 50), null);
            ////Draw X 横向轴绘制
            for (int i = 0; i <= 10; i++)
            {
                e.Graphics.DrawLine(TablePen, StartPrint, i * Unit_length + 18, StartPrint + 14 * Unit_length, i * Unit_length + 18);//画线
                Str = Convert.ToString((10 - i) * 5);
                if (i == 0)
                    Str = "50";
                if (i == 10)
                    break;
                gp.AddString(Str, family, fontstyle, 8, new RectangleF(20, i * Unit_length +16, 400, 50), null);//添加文字
            }
            gp.AddString("温", family, fontstyle, 12, new RectangleF(0, groupBox4.ClientRectangle.Height / 2 - StartPrint, 400, 50), null);
            gp.AddString("度", family, fontstyle, 12, new RectangleF(0, groupBox4.ClientRectangle.Height / 2 + 18 - StartPrint, 400, 50), null);
            gp.AddString("°C", family, fontstyle, 12, new RectangleF(0, groupBox4.ClientRectangle.Height / 2 + 32 - StartPrint, 400, 50), null);
            e.Graphics.DrawPath(Pens.White, gp);//写文字
        }
  • 方法介绍
    DrawLine(Pen pen, int x1, int y1, int x2, int y2);

pen:定义线条的宽度、颜色、样式
画线由(x1,y1)向(x2,y2)画

public void AddString(string s, FontFamily family, int style, float emSize, RectangleF layoutRect, StringFormat format);

s:绘制的字符
family:绘制的字体类型
style:字体的样式
emsize:方形块的高度
layoutRect:文本的矩形
format:文本格式设置信息

  1. c#延时函数
public static void Delay(int milliSecond)
        {
            int start = Environment.TickCount;
            while (Math.Abs(Environment.TickCount - start) < milliSecond)//毫秒
            {
                Application.DoEvents();//可执行某无聊的操作
            }
        }

关于Math.Abs():
  Environment.TickCount,内部API是用DWORD GetTickCount()来实现的,该属性的值从系统计时器派生,并以 32 位有符号整数的形式存储。因此,如果系统连续运行,TickCount 将在约 24.9 天内从零递增至 Int32. MaxValue ,然后跳至 Int32. MinValue (这是一个负数),再在接下来的 24.9 天内递增至零。DWORD是无符号的,而 Environment.TickCount属性返回的值是有符号的,所以有一半的值用负数表示!

  1. 串口写函数
private void button_send_Click(object sender, EventArgs e)
        {//发送数据
            if(serialPort1.IsOpen)
            {//如果串口开启
                if (textBox_send.Text.Trim() != "")//如果框内不为空则
                {
                    serialPort1.Write(textBox_send.Text.Trim());//写数据
                }
                else
                {
                    MessageBox.Show("发送框没有数据");
                }
            }
            else
            {
                MessageBox.Show("串口未打开");
            }
        }
  1. 串口读函数(如果是温度传感器并选择温度传感器画温度曲线)
private void post_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            float Up, Dw,t;
            Graphics graphics = groupBox4.CreateGraphics();
            if (!radioButton1.Checked)
            {
                string str = serialPort1.ReadExisting();//字符串方式读
                if(!radioButton3.Checked)
                {
                    //提取字符串中的数字
                    string result = System.Text.RegularExpressions.Regex.Replace(str, @"[^0-9]+", "");
                    Console.WriteLine(result);
                    //设置正常温度上限下限
                    Dw = Convert.ToSingle(comboBox6.Text);
                    Up = Convert.ToSingle(comboBox7.Text);
                    if(Dw=Up&&dstr2<=Dw)
                    {
                        graphics.DrawLine(LinesPen, Origin_x + i * Unit_length, dstr1, Origin_x + (i+0.1f) * Unit_length, Origin_y - dstr2 * 4);
                    }
                    else//异常温度的曲线
                    {
                        graphics.DrawLine(LinesEpen, Origin_x + i * Unit_length, dstr1, Origin_x + (i + 0.1f) * Unit_length, Origin_y - dstr2 * 4);
                    }
                    i += 0.1f;
                    dstr1 = Origin_y - dstr2 * 4;
                    Delay(1000);//不延时的话不显示
                    //textBox_T.Clear();无所谓
                }
                else
                {
                    textBox_receive.AppendText(str);
                }
            }
            else
            {
                byte data;
                data = (byte)serialPort1.ReadByte();
                string str = Convert.ToString(data, 16).ToUpper();//
                textBox_receive.AppendText("0x" + (str.Length == 1 ? "0" + str : str) + "  ");

            }
        }

想要源代码的可以关注公众号回复:上位机
c#串口调试助手温度曲线的显示-上位机的开发-串口参数介绍_第6张图片

你可能感兴趣的:(c#串口调试助手,c#,上位机,串口调试助手,上位机温度曲线显示,串口调试助手参数介绍)