lcd编程入门 (lcd写指令操作流程)

lcd编程教程,lcd编程入门

来源:韦东山嵌入式专栏_ARM裸机加强版维基教程

作者:韦东山

本文字数:2144,阅读时长:3分钟

前面我们写的程序都是采用的16BPP或者24BPP(也就是32BPP),假如我们要使用8PP,就需要使用调色板。

如图所示8PP工作原理示意图,在FB只存放8bit的每个像素索引,根据这个索引,再去调色板找到对应的数据传给LCD控制器,再通过电子枪显示出来。

调色板里面有2^8(256)个颜色数据,每个颜色数据为16bit,表示一种颜色。

lcd编程教程,lcd编程入门

在硬件上,我们要初始化这个调色板,才能通过索引得到颜色。

根据第三节的软件框架,调色板的初始化应该放在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,
};

调色板对应一块内存,我们需要找到它的位置和格式。

lcd编程教程,lcd编程入门

从芯片手册了解到,其起始地址为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编程编程添加除法

点击“了解更多”阅读更多相关文章。