
来源:韦东山嵌入式专栏_ARM裸机加强版维基教程
作者:韦东山
本文字数:2144,阅读时长:3分钟
前面我们写的程序都是采用的16BPP或者24BPP(也就是32BPP),假如我们要使用8PP,就需要使用调色板。
如图所示8PP工作原理示意图,在FB只存放8bit的每个像素索引,根据这个索引,再去调色板找到对应的数据传给LCD控制器,再通过电子枪显示出来。
调色板里面有2^8(256)个颜色数据,每个颜色数据为16bit,表示一种颜色。

在硬件上,我们要初始化这个调色板,才能通过索引得到颜色。
根据第三节的软件框架,调色板的初始化应该放在s3c2440_lcd_controller.c里面。
在lcd_controller结构体里添加调色板初始化函数:
struct lcd_controller s3c2440_lcd_controller = {
.name = "s3c2440",
.init = s3c2440_lcd_controller_init,
.enable = s3c2440_lcd_controller_enalbe,
.disable = s3c2440_lcd_controller_disable,
.init_palette = s3c2440_lcd_controller_init_palette,
};
调色板对应一块内存,我们需要找到它的位置和格式。

从芯片手册了解到,其起始地址为0x4D000400,且设置调色板前,需要关闭LCD控制器。
void s3c2440_lcd_controller_init_palette(void)
{
volatile unsigned int *palette_base = (volatile unsigned int *)0x4D000400;
int i;
int bit = LCDCON1 & (1<<0);
/* LCDCON1'BIT 0 : 设置LCD控制器是否输出信号 */
if (bit)
LCDCON1 &= ~(1<<0);
for (i = 0; i < 256; i++)
{
/* 低16位 : rgb565 */
*palette_base++ = i;
}
if (bit)
LCDCON1 |= (1<<0);
}
设置调色板前,先判断LCD控制器是否打开,如果打开了就先关闭,且设置完成后再打开。
在网上搜索了一下,没有找到调色板数据数组,这里作为实验,就随便设置,让其为i。
我们让调色板数据等于i,0-255,只占据8位,最后的颜色范围为B5G3R0,因此会比较偏蓝。
修改lcd_4.3.c,将BPP改为8,
再修改lcd_controller.c的初始化函数,加入调色板初始化函数。
int lcd_controller_init(p_lcd_params plcdparams)
{
/* 调用所选择的LCD控制器的初始化函数 */
if (g_p_lcd_controller_selected)
{
g_p_lcd_controller_selected->init(plcdparams);
g_p_lcd_controller_selected->init_palette();
return 0;
}
return -1;
}
再修改lcd_test.c,加入bpp=8的情况:
if (bpp == 8)
{
/* 让LCD输出整屏的红色 */
/* bpp: palette[12] */
p0 = (unsigned char *)fb_base;
for (x = 0; x < xres; x++)
for (y = 0; y < yres; y++)
*p0++ = 12;
/* palette[47] */
p0 = (unsigned char *)fb_base;
for (x = 0; x < xres; x++)
for (y = 0; y < yres; y++)
*p0++ = 47;
/* palette[88] */
p0 = (unsigned char *)fb_base;
for (x = 0; x < xres; x++)
for (y = 0; y < yres; y++)
*p0++ = 88;
/* palette[0] */
p0 = (unsigned char *)fb_base;
for (x = 0; x < xres; x++)
for (y = 0; y < yres; y++)
*p0++ = 0;
}
随便让其全屏显示某个颜色。
最后在画线画圆,显示文字的函数里,修改下颜色:
/* 画线 */
draw_line(0, 0, xres - 1, 0, 0x23ff77);
draw_line(xres - 1, 0, xres - 1, yres - 1, 0xffff);
draw_line(0, yres - 1, xres - 1, yres - 1, 0xff00aa);
draw_line(0, 0, 0, yres - 1, 0xff00ef);
draw_line(0, 0, xres - 1, yres - 1, 0xff45);
draw_line(xres - 1, 0, 0, yres - 1, 0xff0780);
delay(1000000);
/* 画圆 */
draw_circle(xres/2, yres/2, yres/4, 0xff);
/* 输出文字 */
fb_print_string(10, 10, "www.100ask.net\n\r100ask.taobao.com", 0xff);
上面的颜色数据,其实只有低两位有效,因为前面的调色板映射范围是0-255。
上一篇:LCD原理详解及裸机程序分析——第010节_LCD编程编程添加除法
点击“了解更多”阅读更多相关文章。