0

我已经为 MicroChip PIC32 嵌入式芯片上的 LCD 显示器改编的 DMA 中断处理程序遇到了一些问题。

我的内存有限,我的彩色 LCD 需要一个帧缓冲区。已决定使用 16 种颜色并使用每像素半字节。我创建了一个如下所示的数组:

unsigned char GraphicsFrame[FRAME_HEIGHT][LINE_LENGTH/2]; 

在我的中断处理程序中,我将 4 位半字节转换为 16 位值,以通过并行端口和 DMA 传输发送到 LCD。我在中断处理程序中使用查找表来实现这一点,但是在调试时我将进入 General_Exception_Handler,它指出了我提取 4 位半字节并将其转换为 16 位值的方式存在问题:

for( i=0,j=0; i<30; i++, lineX++ )
{
    // not particularly elegant, perhaps look at a better way
    if     ((((GraphicsFrame[line][i]) >> 4) & 0x0F) == 0x0) lineBuffer[j++] = (unsigned short int)RGBBlack;
    else if((((GraphicsFrame[line][i]) >> 4) & 0x0F) == 0x1) lineBuffer[j++] = (unsigned short int)RGBBlue;
    else if((((GraphicsFrame[line][i]) >> 4) & 0x0F) == 0x2) lineBuffer[j++] = (unsigned short int)RGBRed;
    else if((((GraphicsFrame[line][i]) >> 4) & 0x0F) == 0x3) lineBuffer[j++] = (unsigned short int)RGBGreen;
    else if((((GraphicsFrame[line][i]) >> 4) & 0x0F) == 0x4) lineBuffer[j++] = (unsigned short int)RGBCyan;
    else if((((GraphicsFrame[line][i]) >> 4) & 0x0F) == 0x6) lineBuffer[j++] = (unsigned short int)RGBYellow;
    else if((((GraphicsFrame[line][i]) >> 4) & 0x0F) == 0x7) lineBuffer[j++] = (unsigned short int)RGBKaneGreen;
    else if((((GraphicsFrame[line][i]) >> 4) & 0x0F) == 0xF) lineBuffer[j++] = (unsigned short int)RGBWhite;

    if     ((GraphicsFrame[line][i] & 0x0F) == 0x0) lineBuffer[j++] = (unsigned short int)RGBBlack;
    else if((GraphicsFrame[line][i] & 0x0F) == 0x1) lineBuffer[j++] = (unsigned short int)RGBBlue;
    else if((GraphicsFrame[line][i] & 0x0F) == 0x2) lineBuffer[j++] = (unsigned short int)RGBRed;
    else if((GraphicsFrame[line][i] & 0x0F) == 0x3) lineBuffer[j++] = (unsigned short int)RGBGreen;
    else if((GraphicsFrame[line][i] & 0x0F) == 0x4) lineBuffer[j++] = (unsigned short int)RGBCyan;
    else if((GraphicsFrame[line][i] & 0x0F) == 0x5) lineBuffer[j++] = (unsigned short int)RGBMagenta;
    else if((GraphicsFrame[line][i] & 0x0F) == 0x6) lineBuffer[j++] = (unsigned short int)RGBYellow;
    else if((GraphicsFrame[line][i] & 0x0F) == 0x7) lineBuffer[j++] = (unsigned short int)RGBKaneGreen;
    else if((GraphicsFrame[line][i] & 0x0F) == 0xF) lineBuffer[j++] = (unsigned short int)RGBWhite;
}

我正在尝试使用另一个包含 60 个像素的数组将 DMA 设置为一次传输 60 个像素(60 x 16 位):

unsigned short int lineBuffer[60];

谁能发现我提取半字节并转换它的方式有问题?没有任何警告或错误,所以没有任何事情发生在我身上!

任何帮助表示赞赏,谢谢

4

1 回答 1

1

从您发布的内容中我可以看出,它看起来还不错。唯一可疑的是lineandlineX变量。它们似乎没有被使用。此外,如果您想遍历二维数组的第一个维度,您可能必须使用嵌套的 for 循环。

帖子的其余部分是代码审查,而不是答案:

发布的代码不是查找表。考虑这样做:

const uint16_t COLOR_TABLE [COLORS_N] = 
{
  RGBBlack,      // 0x0
  RGBBlue,       // 0x1
  RGBRed,        // 0x2
  RGBGreen,      // 0x3
  RGBCyan,       // 0x4
  undefined,     // 0x5
  RGBYellow,     // 0x6
  RGBKaneGreen,  // 0x7
  undefined,     // 0x8
  undefined,     // 0x9
  undefined,     // 0xA
  undefined,     // 0xB
  undefined,     // 0xC
  undefined,     // 0xD
  undefined,     // 0xE
  RGBWhite,      // 0xF
};

...

uint8_t line_iterator=0;

for(uint8_t i=0; i<LINE_LENGTH/2; i++)
{
  uint8_t nibble;

  nibble = (uint8_t) ((GraphicsFrame[line][i]) >> 4) & 0x0F);
  lineBuffer[line_iterator] =  COLOR_TABLE[nibble];

  nibble = (uint8_t) (GraphicsFrame[line][i] & 0x0F);
  lineBuffer[line_iterator + 1] =  COLOR_TABLE[nibble];

  line_iterator += 2;
}

对以上评论:

  • 该查找表将显着提高可读性和程序速度。如果这是针对 ISR,您肯定必须使用这样的表。
  • 由于它是嵌入式系统,您应该使用 stdint.h 中的整数类型。
  • 当心隐式整数促销。
  • 保持 for 循环简单,避免混淆它们。如果您需要多个迭代器,请为迭代器使用自我解释的变量名称。
  • 不要使用像 30 这样的“幻数”。
于 2014-04-17T11:40:33.600 回答