LCD编程_使用调色板

梦想的初衷 提交于 2019-11-27 18:33:14

在前面的博客中,使用的像素格式都是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\n\r100ask.taobao.com", 0xff);
133 }

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!