【1】16位还是24位
s3c2440 控制 T35 屏显示图片,需要先初始化一些变量:我的图片是通过 LCD彩色图片转换工具BMP_to_H 自动生成的,该工具只能识别 24 位的 bmp 图片,所以你用 PS 做 BMP 图片的时候,一定要保存为24位格式的,但是该工具生成后的C 语言图片数组却是 16 位的。所以我们需要设置 s3c2440 对应的控制器为16位:
//#define BPPMODE_TFT 13 //24位TFT型LCD
#define BPPMODE_TFT 12 //16位TFT型LCD
rLCDCON1=(CLKVAL_TFT<<8)|(MVAL_USED<<7)|(PNRMODE_TFT<<5)|(BPPMODE_TFT<<1)|0;
【2】16位的情况下,如何划分红绿蓝
每一个像素点用16bit表示,可以看出,16不能被3整除,不像24位色那样,红绿蓝各8bit;有两种方法划分这16bit :5:5:5:1 和 5:6:5,
rLCDCON5 的第11位用来控制这16bit的划分方法:0 表示 5:5:5:1 ; 1表示 5:6:5。BMP_to_H工具转化出来的是 5:6:5,所以设置rLCDCON5的第11 bit 为1。
这些信息都可以在 S3C2440.pdf 中查到(搜索关键字 LCDCON5)
总之,你一定要了解你使用的图片转化工具生成的图片数组是什么样的,然后再将对应的控制信息配置好。
【3】显示模糊怎么办
rLCDCON5 的最低位一定要为 1
#define HWSWP 0 //颜色数据半字不交换,这样会导致图片显示模糊,具体原因现在还不知道,后面再研究
rLCDCON5 = ((1<<11) | (1 << 9) | (1 << 8) | (1 << 3)) ;//bad
rLCDCON5 = ((1<<11) | (1 << 9) | (1 << 8) | (1 << 3) | (1 << 0));//good
【4】图片显示偏移出屏幕怎么办
一开始显示的图片可能会偏移,那是因为偏移量没有设置好,经过我多次的精确调试,mini2440的偏移如下:
//垂直同步信号
#define VBPD (1)//后肩
#define VFPD (5)//前肩
#define VSPW (1)//脉宽
//水平同步信号
#define HBPD (24)//前肩
#define HFPD (19)//后肩
#define HSPW (5)//脉宽
rLCDCON2=(VBPD<<24)|(LINEVAL<<14)|(VFPD<<6)|(VSPW);
rLCDCON3=(HBPD<<19)|(HOZVAL<<8)|(HFPD);
完整代码如下,sunflower_240x320 是用BMP_to_H工具转化出来的数组:
extern unsigned char sunflower_240x320[];
//FOR ADC
#define rADCCON (*(volatile unsigned *)0x58000000) //ADC control
#define rADCTSC (*(volatile unsigned *)0x58000004) //ADC touch screen control
#define rADCDLY (*(volatile unsigned *)0x58000008) //ADC start or Interval Delay
#define rADCDAT0 (*(volatile unsigned *)0x5800000c) //ADC conversion data 0
#define rADCDAT1 (*(volatile unsigned *)0x58000010) //ADC conversion data 1
#define rADCUPDN (*(volatile unsigned *)0x58000014) //Stylus Up/Down interrupt status
//FOR LCD
#define U32 unsigned int
#define M5D(n) ((n) & 0x1fffff) //用于设置显示缓存区时,取低21位地址
#define rGPCCON (*(volatile unsigned *)0x56000020) //Port C control
#define rGPCDAT (*(volatile unsigned *)0x56000024) //Port C data
#define rGPCUP (*(volatile unsigned *)0x56000028) //Pull-up control C
#define rGPDCON (*(volatile unsigned *)0x56000030) //Port D control
#define rGPDDAT (*(volatile unsigned *)0x56000034) //Port D data
#define rGPDUP (*(volatile unsigned *)0x56000038) //Pull-up control D
#define rGPGCON (*(volatile unsigned *)0x56000060) //Port G control
#define rGPGDAT (*(volatile unsigned *)0x56000064) //Port G data
#define rGPGUP (*(volatile unsigned *)0x56000068) //Pull-up control G
#define rLCDCON1 (*(volatile unsigned *)0x4d000000) //LCD control 1
#define rLCDCON2 (*(volatile unsigned *)0x4d000004) //LCD control 2
#define rLCDCON3 (*(volatile unsigned *)0x4d000008) //LCD control 3
#define rLCDCON4 (*(volatile unsigned *)0x4d00000c) //LCD control 4
#define rLCDCON5 (*(volatile unsigned *)0x4d000010) //LCD control 5
#define rLCDSADDR1 (*(volatile unsigned *)0x4d000014) //STN/TFT Frame buffer start address 1
#define rLCDSADDR2 (*(volatile unsigned *)0x4d000018) //STN/TFT Frame buffer start address 2
#define rLCDSADDR3 (*(volatile unsigned *)0x4d00001c) //STN/TFT Virtual screen address set
#define rLCDINTMSK (*(volatile unsigned *)0x4d00005c) //LCD Interrupt mask
#define rTCONSEL (*(volatile unsigned *)0x4d000060) //LPC3600 Control --- edited by junon
#define LCD_WIDTH 240 //屏幕的宽
#define LCD_HEIGHT 320 //屏幕的高
//垂直同步信号
#define VBPD (1)//后肩
#define VFPD (5)//前肩
#define VSPW (1)//脉宽
//水平同步信号
#define HBPD (24)//前肩
#define HFPD (19)//后肩
#define HSPW (5)//脉宽
//显示尺寸
#define LINEVAL (LCD_HEIGHT-1)
#define HOZVAL (LCD_WIDTH-1)
#define U16 unsigned short
//for LCDCON1
#define CLKVAL_TFT 6 //设置时钟信号
#define MVAL_USED 0 //
#define PNRMODE_TFT 3 //TFT型LCD
#define BPPMODE_TFT 12 //16位TFT型LCD
//for LCDCON5
#define BPP24BL 0 //32位数据表示24位颜色值时,低位数据有效,高8位无效
#define INVVCLK 0 //像素值在VCLK下降沿有效
#define INVVLINE 1 //翻转HSYNC信号
#define INVVFRAME 1 //翻转VSYNC信号
#define INVVD 0 //正常VD信号极性
#define INVVDEN 0 //正常VDEN信号极性
#define PWREN 1 //使能PWREN信号
//定义显示缓存区
volatile unsigned short LCD_BUFFER[320][240];
void Paint_Bmp(int x0,int y0,int h,int l,unsigned char bmp[])
{
int x,y,k=0;
U32 c;
int p = 0;
for( y = y0 ; y < l ; y++ )
{
for( x = x0 ; x< h ; x++ )
{
c = bmp[p+1] | (bmp[p]<<8) ;
if ( ( (x0+x) < LCD_WIDTH) && ( (y0+y) <LCD_HEIGHT) )
LCD_BUFFER[y0+y][x0+x] =c;
p = p + 2 ;
}
}
}
void Main(void)//M 一定要大写
{
//配置LCD相关引脚
rGPCUP = 0x00000000;
rGPCCON = 0xaaaa02a9;
rGPDUP = 0x00000000;
rGPDCON=0xaaaaaaaa;
rLCDCON1=(CLKVAL_TFT<<8)|(MVAL_USED<<7)|(PNRMODE_TFT<<5)|(BPPMODE_TFT<<1)|0;
rLCDCON2=(VBPD<<24)|(LINEVAL<<14)|(VFPD<<6)|(VSPW);
rLCDCON3=(HBPD<<19)|(HOZVAL<<8)|(HFPD);
rLCDCON4=(HSPW);
rLCDCON5 = ((1<<11) | (1 << 9) | (1 << 8) | (1 << 3) | (1 << 0));
rLCDSADDR3=LCD_WIDTH*32/16;
rLCDINTMSK|=(3); // 屏蔽LCD中断
rTCONSEL = 0; //无效LPC3480
rLCDSADDR1=(((U32)LCD_BUFFER>>22)<<21)|M5D((U32)LCD_BUFFER>>1);//帧缓存器的起始地址
//rLCDSADDR2=M5D( ((U32)LCD_BUFFER+(LCD_WIDTH*LCD_HEIGHT*4))>>1 );//背光很暗,灰蒙蒙的
rLCDSADDR2=M5D( ((U32)LCD_BUFFER+(LCD_WIDTH*LCD_HEIGHT*2))>>1 );
rLCDCON1|=1; //LCD开启,不能少
Paint_Bmp(0, 0, 240, 320, sunflower_240x320);
}
[ 此帖被luoben137在2013-05-18 20:24重新编辑 ]