zoukankan      html  css  js  c++  java
  • LCD编程_使用调色板

    在前面的博客中,使用的像素格式都是16bpp,24bpp(24bpp实际实际上就是32bpp)?如果想使用8bpp时,就需要使用调色板。

    在以前的博客中,曾经说过,在framebuffer中如果每个像素用8bpp表示,这8bpp怎么转换成lcd需要的16bpp的数据,需要引入一个调色板。

    2的8次方,为256。即调色板中有256项,0-255。需要在调色板所对应的内存里面,填入16bpp的数据(这些数据就是真正的颜色值)。把lcd控制器设置为8bpp时,它会从framebuffer中取出一个像素的数据(8位),使用这8位数据作为一个索引,在调色板中取出真正的颜色,从而就得到了16位的数据。最终将这16位的数据发给lcd。

    需要修改s3c2440_lcd_controller.c    lcd_controller.c中的代码:

      1 #include "lcd.h"
      2 #include "lcd_controller.h"
      3 #include "../s3c2440_soc.h"
      4 
      5 #define HCLK 100
      6 
      7 void jz2440_lcd_pin_init(void)
      8 {
      9     /* 初始化引脚 : 背光引脚 */
     10     GPBCON &= ~0x3;
     11     GPBCON |= 0x01;
     12 
     13     /* LCD专用引脚 */
     14     GPCCON = 0xaaaaaaaa;
     15     GPDCON = 0xaaaaaaaa;
     16 
     17     /* PWREN */
     18     GPGCON |= (3<<8);
     19 }
     20 
     21 
     22 /* 根据传入的LCD参数设置LCD控制器 */
     23 void s3c2440_lcd_controller_init(p_lcd_params plcdparams)
     24 {
     25     int pixelplace;
     26     unsigned int addr;
     27 
     28     jz2440_lcd_pin_init();
     29     
     30     /* [17:8]: clkval, vclk = HCLK / [(CLKVAL+1) x 2]
     31      *                   9   = 100M /[(CLKVAL+1) x 2], clkval = 4.5 = 5
     32      *                 CLKVAL = 100/vclk/2-1
     33      * [6:5]: 0b11, tft lcd
     34      * [4:1]: bpp mode
     35      * [0]  : LCD video output and the logic enable/disable
     36      */
     37     int clkval = (float)HCLK/plcdparams->time_seq.vclk/2-1+0.5;
     38     //int clkval = 5;
     39     int bppmode = plcdparams->bpp == 8  ? 0xb :
     40                   plcdparams->bpp == 16 ? 0xc :
     41                   0xd;  /* 0xd: 24,32bpp */
     42     LCDCON1 = (clkval<<8) | (3<<5) | (bppmode<<1) ;
     43 
     44     /* [31:24] : VBPD    = tvb - 1
     45      * [23:14] : LINEVAL = line - 1
     46      * [13:6]  : VFPD    = tvf - 1
     47      * [5:0]   : VSPW    = tvp - 1
     48      */
     49     LCDCON2 =     ((plcdparams->time_seq.tvb - 1)<<24) | 
     50                 ((plcdparams->yres - 1)<<14)         | 
     51                 ((plcdparams->time_seq.tvf - 1)<<6)  | 
     52                 ((plcdparams->time_seq.tvp - 1)<<0);
     53 
     54     /* [25:19] : HBPD     = thb - 1
     55      * [18:8]  : HOZVAL  = 列 - 1
     56      * [7:0]   : HFPD     = thf - 1
     57      */
     58     LCDCON3 =    ((plcdparams->time_seq.thb - 1)<<19) | 
     59                 ((plcdparams->xres - 1)<<8)              | 
     60                 ((plcdparams->time_seq.thf - 1)<<0);
     61 
     62     /* 
     63      * [7:0]   : HSPW     = thp - 1
     64      */
     65     LCDCON4 =    ((plcdparams->time_seq.thp - 1)<<0);
     66 
     67     /* 用来设置引脚极性, 设置16bpp, 设置内存中象素存放的格式
     68      * [12] : BPP24BL
     69      * [11] : FRM565, 1-565
     70      * [10] : INVVCLK, 0 = The video data is fetched at VCLK falling edge
     71      * [9]  : HSYNC是否反转
     72      * [8]  : VSYNC是否反转
     73      * [7]  : INVVD, rgb是否反转
     74      * [6]  : INVVDEN
     75      * [5]  : INVPWREN
     76      * [4]  : INVLEND
     77      * [3]  : PWREN, LCD_PWREN output signal enable/disable
     78      * [2]  : ENLEND
     79      * [1]  : BSWP
     80      * [0]  : HWSWP
     81      */
     82 
     83     pixelplace = plcdparams->bpp == 32 ? (0) : 
     84                  plcdparams->bpp == 16 ? (1) : 
     85                  (1<<1);  /* 8bpp */
     86     
     87     LCDCON5 = (plcdparams->pins_pol.vclk<<10) |
     88               (plcdparams->pins_pol.rgb<<7)   |
     89               (plcdparams->pins_pol.hsync<<9) |
     90               (plcdparams->pins_pol.vsync<<8) |
     91                (plcdparams->pins_pol.de<<6)    |
     92               (plcdparams->pins_pol.pwren<<5) |
     93               (1<<11) | pixelplace;
     94 
     95     /* framebuffer地址 */
     96     /*
     97      * [29:21] : LCDBANK, A[30:22] of fb
     98      * [20:0]  : LCDBASEU, A[21:1] of fb
     99      */
    100     addr = plcdparams->fb_base & ~(1<<31);
    101     LCDSADDR1 = (addr >> 1);
    102 
    103     /* 
    104      * [20:0] : LCDBASEL, A[21:1] of end addr
    105      */
    106     addr = plcdparams->fb_base + plcdparams->xres*plcdparams->yres*plcdparams->bpp/8;
    107     addr >>=1;
    108     addr &= 0x1fffff;
    109     LCDSADDR2 = addr;//    
    110 }
    111 
    112 void s3c2440_lcd_controller_enalbe(void)
    113 {
    114     /* 背光引脚 : GPB0 */
    115     GPBDAT |= (1<<0);
    116     
    117     /* pwren    : 给LCD提供AVDD  */
    118     LCDCON5 |= (1<<3);
    119     
    120     /* LCDCON1'BIT 0 : 设置LCD控制器是否输出信号 */
    121     LCDCON1 |= (1<<0);
    122 }
    123 
    124 void s3c2440_lcd_controller_disable(void)
    125 {
    126     /* 背光引脚 : GPB0 */
    127     GPBDAT &= ~(1<<0);
    128 
    129     /* pwren    : 给LCD提供AVDD  */
    130     LCDCON5 &= ~(1<<3);
    131 
    132     /* LCDCON1'BIT 0 : 设置LCD控制器是否输出信号 */
    133     LCDCON1 &= ~(1<<0);
    134 }
    135 
    136 
    137 /* 设置调色板之前, 先关闭lcd_controller */
    138 void s3c2440_lcd_controller_init_palette(void)
    139 {
    140     volatile unsigned int *palette_base =  (volatile unsigned int *)0x4D000400;
    141     int i;
    142 
    143     int bit = LCDCON1 & (1<<0);
    144 
    145     /* LCDCON1'BIT 0 : 设置LCD控制器是否输出信号 */
    146     if (bit)
    147         LCDCON1 &= ~(1<<0);
    148 
    149     for (i = 0; i < 256; i++)
    150     {
    151         /* 低16位 : rgb565 */    
    152         *palette_base++ = i;
    153     }
    154 
    155     if (bit)
    156         LCDCON1 |= (1<<0);
    157 }
    158 
    159 struct lcd_controller s3c2440_lcd_controller = {
    160     .name    = "s3c2440",
    161     .init    = s3c2440_lcd_controller_init,
    162     .enable  = s3c2440_lcd_controller_enalbe,
    163     .disable = s3c2440_lcd_controller_disable,
    164     .init_palette = s3c2440_lcd_controller_init_palette,
    165 };
    166 
    167 
    168 void s3c2440_lcd_contoller_add(void)
    169 {
    170     register_lcd_controller(&s3c2440_lcd_controller);
    171 }
     1 #include "lcd_controller.h"
     2 
     3 #define LCD_CONTROLLER_NUM 10
     4 
     5 static p_lcd_controller p_array_lcd_controller[LCD_CONTROLLER_NUM];
     6 static p_lcd_controller g_p_lcd_controller_selected;
     7 
     8 int register_lcd_controller(p_lcd_controller plcdcon)
     9 {
    10     int i;
    11     for (i = 0; i < LCD_CONTROLLER_NUM; i++)
    12     {
    13         if (!p_array_lcd_controller[i])
    14         {
    15             p_array_lcd_controller[i] = plcdcon;
    16             return i;
    17         }
    18     }
    19     return -1;        
    20 }
    21 
    22 int select_lcd_controller(char *name)
    23 {
    24     int i;
    25     for (i = 0; i < LCD_CONTROLLER_NUM; i++)
    26     {
    27         if (p_array_lcd_controller[i] && !strcmp(p_array_lcd_controller[i]->name, name))
    28         {
    29             g_p_lcd_controller_selected = p_array_lcd_controller[i];
    30             return i;
    31         }
    32     }
    33     return -1;        
    34 }
    35 
    36 
    37 /* 向上: 接收不同LCD的参数
    38  * 向下: 使用这些参数设置对应的LCD控制器
    39  */
    40 
    41 int lcd_controller_init(p_lcd_params plcdparams)
    42 {
    43     /* 调用所选择的LCD控制器的初始化函数 */
    44     if (g_p_lcd_controller_selected)
    45     {
    46         g_p_lcd_controller_selected->init(plcdparams);
    47         g_p_lcd_controller_selected->init_palette();
    48         return 0;
    49     }
    50     return -1;
    51 }
    52 
    53 void lcd_controller_enable(void)
    54 {
    55     if (g_p_lcd_controller_selected)
    56     {
    57         g_p_lcd_controller_selected->enable();
    58     }
    59 }
    60 
    61 void lcd_controller_disable(void)
    62 {
    63     if (g_p_lcd_controller_selected)
    64     {
    65         g_p_lcd_controller_selected->disable();
    66     }
    67 }
    68 
    69 
    70 void lcd_contoller_add(void)
    71 {
    72     s3c2440_lcd_contoller_add();
    73 }

    再来看一下,lcd_4.3中,做了什么修改?

    led_test.c,注意:这里面的颜色值都是随便写的。目的就是想看看,使用8bpp时,能够实现功能。

      1 #include "geometry.h"
      2 #include "font.h"
      3 
      4 void lcd_test(void)
      5 {
      6     unsigned int fb_base;
      7     int xres, yres, bpp;
      8     int x, y;
      9     unsigned char *p0;
     10     unsigned short *p;
     11     unsigned int *p2;
     12         
     13     /* 初始化LCD */
     14     lcd_init();
     15 
     16     /* 使能LCD */
     17     lcd_enable();
     18 
     19     /* 获得LCD的参数: fb_base, xres, yres, bpp */
     20     get_lcd_params(&fb_base, &xres, &yres, &bpp);
     21     fb_get_lcd_params();
     22     font_init();
     23     
     24     /* 往framebuffer中写数据 */
     25     if (bpp == 8)
     26     {
     27         /* 让LCD输出整屏的红色 */
     28 
     29         /* bpp: palette[12] */
     30 
     31         p0 = (unsigned char *)fb_base;
     32         for (x = 0; x < xres; x++)
     33             for (y = 0; y < yres; y++)
     34                 *p0++ = 12;
     35 
     36         /* palette[47] */
     37         p0 = (unsigned char *)fb_base;
     38         for (x = 0; x < xres; x++)
     39             for (y = 0; y < yres; y++)
     40                 *p0++ = 47;
     41 
     42         /* palette[88] */
     43         p0 = (unsigned char *)fb_base;
     44         for (x = 0; x < xres; x++)
     45             for (y = 0; y < yres; y++)
     46                 *p0++ = 88;
     47 
     48         /* palette[0] */
     49         p0 = (unsigned char *)fb_base;
     50         for (x = 0; x < xres; x++)
     51             for (y = 0; y < yres; y++)
     52                 *p0++ = 0;
     53             
     54     }
     55     else if (bpp == 16)
     56     {
     57         /* 让LCD输出整屏的红色 */
     58 
     59         /* 565: 0xf800 */
     60 
     61         p = (unsigned short *)fb_base;
     62         for (x = 0; x < xres; x++)
     63             for (y = 0; y < yres; y++)
     64                 *p++ = 0xf800;
     65 
     66         /* green */
     67         p = (unsigned short *)fb_base;
     68         for (x = 0; x < xres; x++)
     69             for (y = 0; y < yres; y++)
     70                 *p++ = 0x7e0;
     71 
     72         /* blue */
     73         p = (unsigned short *)fb_base;
     74         for (x = 0; x < xres; x++)
     75             for (y = 0; y < yres; y++)
     76                 *p++ = 0x1f;
     77 
     78         /* black */
     79         p = (unsigned short *)fb_base;
     80         for (x = 0; x < xres; x++)
     81             for (y = 0; y < yres; y++)
     82                 *p++ = 0;
     83             
     84     }
     85     else if (bpp == 32)
     86     {
     87         /* 让LCD输出整屏的红色 */
     88 
     89         /* 0xRRGGBB */
     90 
     91         p2 = (unsigned int *)fb_base;
     92         for (x = 0; x < xres; x++)
     93             for (y = 0; y < yres; y++)
     94                 *p2++ = 0xff0000;
     95 
     96         /* green */
     97         p2 = (unsigned int *)fb_base;
     98         for (x = 0; x < xres; x++)
     99             for (y = 0; y < yres; y++)
    100                 *p2++ = 0x00ff00;
    101 
    102         /* blue */
    103         p2 = (unsigned int *)fb_base;
    104         for (x = 0; x < xres; x++)
    105             for (y = 0; y < yres; y++)
    106                 *p2++ = 0x0000ff;
    107 
    108         /* black */
    109         p2 = (unsigned int *)fb_base;
    110         for (x = 0; x < xres; x++)
    111             for (y = 0; y < yres; y++)
    112                 *p2++ = 0;
    113 
    114     }
    115 
    116     delay(1000000);
    117     
    118     /* 画线 */
    119     draw_line(0, 0, xres - 1, 0, 0x23ff77);
    120     draw_line(xres - 1, 0, xres - 1, yres - 1, 0xffff);
    121     draw_line(0, yres - 1, xres - 1, yres - 1, 0xff00aa);
    122     draw_line(0, 0, 0, yres - 1, 0xff00ef);
    123     draw_line(0, 0, xres - 1, yres - 1, 0xff45);
    124     draw_line(xres - 1, 0, 0, yres - 1, 0xff0780);
    125 
    126     delay(1000000);
    127 
    128     /* 画圆 */
    129     draw_circle(xres/2, yres/2, yres/4, 0xff);
    130 
    131     /* 输出文字 */
    132     fb_print_string(10, 10, "www.100ask.net
    
    100ask.taobao.com", 0xff);
    133 }
  • 相关阅读:
    java——ArrayList中remove()方法疑问总结
    java——ArrayList中contains()方法中的疑问
    C语言中signed和unsigned理解
    IO流——常用IO流详解
    Lost's revenge
    Searching the String
    DNA repair
    Ring
    Wireless Password
    Censored!
  • 原文地址:https://www.cnblogs.com/-glb/p/11372278.html
Copyright © 2011-2022 走看看