2

我正在使用 C#(在Netduino Plus上运行的.NET Micro Framework)来控制 84 x 48 像素的 LCD 屏幕。

LCD 屏幕中的每个像素都有两种状态:1(ON)或0(OFF)。为了控制屏幕中的像素,我需要发送一个数组504 bytes,其中每个byte代表一列 8 个像素(即,屏幕被“分割”成 6 行,每行 84 x 8 像素)。

最好用一个例子来证明这一点:

  • 字节00000001( 2^0) 表示一列八个像素,其中列顶部的第一个像素为 ON ( 1)。

  • 字节00001001( 2^0 + 2^3) 表示另一列 8 个像素,其中从列顶部算起的第一个和第四个像素为 ON。

从中可以看出,按位AND运算将显示给定列中的哪些像素是 ON 或 OFF。例如,要查看给定 8 像素列中的第 4 个像素是否为 ON:

00001001    AND
00001000
-----------------
00001000 > 0
∴ The 4th pixel is ON

问题是我需要能够使用(x,y)坐标来访问屏幕中的每个像素。例如,该点(3,10)表示屏幕左上角像素右侧的 4 像素和下方 11 的像素。同样,该点(83,47)代表屏幕右下角的像素。

我编写了以下 C# 代码来实现这一点:

byte[] display = new byte[504];

// storing these means they don't need to be calculated every time:
byte[] base2 = { 1, 2, 4, 8, 16, 32, 64, 128 };

// Determine if the pixel is ON (true) or OFF (false)
public bool PixelState(Pixel px)
{
    return (display[GetColumn(px)] & base2[GetPxNum(px)]) > 0;
}

// Find the number of the pixel in its column of 8
private int GetPxNum(Pixel px)
{
    return px.y % 8;
}

// Find the index of the byte containing the bit representing the state of a pixel
private int GetColumn(Pixel px)
{
    return (px.y / 8 * 84) + px.x;
}

// Set a pixel's state
public void SetPixel(Pixel px, bool state)
{
    int col = GetColumn(px);
    int num = GetPxNum(px);

    if (state && !PixelState(px))
        display[col] += base2[num];
    else if (!state && PixelState(px))
        display[col] -= base2[num];
}

// Represents one (x,y) point
public struct Pixel
{
    public int x, y;

    public Pixel(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}

由于这是在微控制器上运行的,因此我需要代码尽可能快速高效。这也是必要的,因为这些方法可能会被快速连续调用多次以更新 LCD 屏幕中的像素。

因此我的问题是如何让这段代码更快更高效?有没有更好的方法来解决这个问题?

编辑:经过一些广泛的测试后,我意识到我应该Math.FloorGetColumn. 我已经更新了我的代码。

4

1 回答 1

1

这个小片段在SetPixel

if (state && !PixelState(px))
    display[col] += base2[num];
else if (!state && PixelState(px))
    display[col] -= base2[num];

可以替换为:

if (state)
    display[col] |= base2[num];
else
    display[col] &= (byte)~base2[num]; // You could precompute this inverse array too

如果你有足够的可用内存,预计算可能没问题,但说真的,现在 uC 拥有如此强大的处理能力。你真的会注意到一点位移或否定吗?


此外,您可能有兴趣不使用(double),并且Math.ceiling()由于您的微控制器可能不支持浮点,因此必须对其进行仿真(因此性能下降。使用(float)会使其更好(单精度仿真更快)但更好的是这:

return ( (px.y/8 + ((px.y%8)?1:0)) * 84 ) + px.x;

编辑:仔细看看netduino它可能有一个FPU(虽然我在数据表中看不到它,所以它可能没有......)整数数学替代方案可能仍然更快:)


它是否更快只能通过测试来保证,但是,就像我在评论中所说的那样,这可以说是一个瓶颈,你看起来就像另一个过早优化的受害者。

这里最大的瓶颈是你的框架。

于 2012-04-06T04:54:20.640 回答