主题 : mini2440 LCD 裸机显示图片 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 11371
精华: 0
发帖: 11
金钱: 55 两
威望: 11 点
贡献值: 0 点
综合积分: 22 分
注册时间: 2009-12-05
最后登录: 2015-08-16
楼主  发表于: 2013-05-16 23:04

 mini2440 LCD 裸机显示图片

【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重新编辑 ]
级别: 新手上路
UID: 92723
精华: 0
发帖: 4
金钱: 20 两
威望: 4 点
贡献值: 0 点
综合积分: 8 分
注册时间: 2013-06-05
最后登录: 2013-07-12
1楼  发表于: 2013-06-08 21:48

 回 楼主(luoben137) 的帖子

楼主,真心感谢