首页 文章

CPU使用率高,串口时间长

提问于
浏览
2

Iam目前正在开展一个项目,我必须不断阅读串口 . 数据持续最多45分钟 . 我必须通过校验和验证数据并创建一个79字节的数据包 . 在此之后,我必须实时绘制数据(轨迹) . 代码的问题在于它在开始时使用20%的CPU使用率(Pentium 4,3.0 GHz,超线程)(我认为仍然很高)但随着时间的推移CPU使用率增加,最终达到60% .

数据以波特率115200进入,并以100毫秒的速率连续发送 .

我的阅读,验证和绘图代码如下:以下函数接收数据并验证它...

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            header1 = serialPort1.ReadByte();
            if (header1 == 0)
                header2 = serialPort1.ReadByte();
            if ((header1 == 0) && (header2 == 1))//Store the data in an array.
            {
                for (int i = 0; i < 77; i++)
                    abudata[i] = serialPort1.ReadByte();
                tail = abudata[76];
            }
            else
            {
                serialPort1.DiscardInBuffer();
            }
            checksum = 1;// Calculate the checksum.
            for (i = 0; i < 74; i++)
                checksum = checksum + (abudata[i]);
            checksum1 = (abudata[75] << 8);
            checksum1 = checksum1 + (abudata[74]);

            if ((checksum == checksum1) && (tail == 4))
                this.Invoke(new EventHandler(Display_Results));// Function to display
        }
        catch (Exception ode)
        {
            l4[4].BackColor = Color.Red;
        }
    }

以下功能显示标签上的数据并在图片框上绘制轨迹

private void Display_Results(object s, EventArgs e)
    {
        head1[0] = header1;
        head1[1] = header2;
        for (k = 0; k < 77; ++k)
            head1[k + 2] = (((int)abudata[k]) & 0x000000ff);
        jk = 0;
        for (k = 0; k < 36; ++k) //Data packing into 36 bytes
        {
            num_1[k] = (ulong)((head1[jk + 1]) + (head1[jk] << 8)) & 0x0000ffff;
            num_1[k] = (double)num_1[k];
            num_2[k] = (double)num_1[k];
            jk = jk + 2;
            signbit = (int)num_1[k] >> 15;

            if (signbit == 1)
            {
                sgnval = -1;
                num_1[k] = num_1[k] - 65535;
                num_1[k] = num_1[k] * (-1.0);
            }
            else
                sgnval = 1;

            //Converting the data into engineering values

            engval[k] = Math.Round(num_1[k] * parammaxval[k] * sgnval / 32767.0, 3);

            if (k == 14)
            {
                try
                {

                    curr_x = (pictureBox2.Width / 2) + (int)((engval[13] * (pictureBox2.Width)) / map_width);
                    curr_y = (pictureBox2.Height / 2) - (int)((engval[14] * (pictureBox2.Height)) / map_height);
                    PointF p1 = new Point(curr_x, curr_y);
                    if (_gPath != null && _gPath.PointCount > 0)
                        p1 = _gPath.PathPoints[_gPath.PathPoints.Length - 1];
                    PointF p2 = new Point(curr_x, curr_y);
                    _gPath.AddLine(p1, p2);
                    pictureBox2.Invalidate();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

        }           
    }

2 回答

  • 4

    我广泛使用串行端口连接设备,并可能向您保证,常规使用SerialPort类本身不会产生高CPU负载 .

    FIRST 我建议你 PROFILE 你的申请 . .NET有a bunch of个分析器

    只有 after profiling我建议解耦SerialPort读取和数据处理 . 使用 生产环境 者消费者模式 . 将SerialPort中的数据放入队列并从其他线程中使用它 .

    这就是我在其中一个项目中的SerialPortDataReceived函数

    private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            lock (SyncObject)
            {
                if (!_serialPort.IsOpen) return;
    
                try
                {                    
                    int toread = _serialPort.BytesToRead;
                    byte[] bytes = new byte[toread];
                    _serialPort.Read(bytes, 0, toread);
    
                   ProducerAddBytes(bytes);
                }
                catch (TimeOutException)
                {
                    //logic
                }
            }
        }
    

    附:但首先是PROFILE!

  • 1

    我得到了上面代码的问题..

    我正在使用Graph path绘制轨迹

    if (k == 14)
    {
        try
        {
    
            curr_x = (pictureBox2.Width / 2) + (int)((engval[13] * (pictureBox2.Width)) / map_width);
            curr_y = (pictureBox2.Height / 2) - (int)((engval[14] * (pictureBox2.Height)) / map_height);
            PointF p1 = new Point(curr_x, curr_y);
            if (_gPath != null && _gPath.PointCount > 0)
                p1 = _gPath.PathPoints[_gPath.PathPoints.Length - 1];
            PointF p2 = new Point(curr_x, curr_y);
            _gPath.AddLine(p1, p2);
            pictureBox2.Invalidate();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    

    现在,当应用程序继续运行时,它会收集大量的图形点,因此绘制这个巨大数量的点正在消耗资源 .

    任何人都可以建议我解决这个问题,如何绘制轨迹而不减慢系统...

相关问题