CPU使用率高,串口时间长

时间:2012-03-01 10:04:14

标签: c# serial-port cpu-usage

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 个答案:

答案 0 :(得分:4)

我广泛使用串行端口连接设备,并且可以向您保证,定期使用SerialPort类本身不会产生高CPU负载。

第一次我建议你 PROFILE 你的应用程序。 .NET有a bunch of个分析器

分析后只有我建议解耦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
            }
        }
    }

P.S。但首先是PROFILE!

答案 1 :(得分: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);
    }
}

现在,当应用程序继续运行时,它会收集大量的图形点,因此绘制这么大的数据点就会占用资源。

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