⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd控制函数库.c

📁 S3C44B0X内置LCD的应用
💻 C
字号:
#include <string.h>

#include "44b.h"
#include "44blib.h"
#include "def.h"

#include "lcd.h"
#include "lcdlib.h"
#include "glib.h"

//SCR_XSIZE,SCR_YSIZE,LCD_XSIZE,LCD_YSIZE are defined in lcd.h

#define M5D(n) ((n) & 0x1fffff)//只保留n的低21位

#define ARRAY_SIZE_MONO 	(SCR_XSIZE*1/8*SCR_YSIZE)
#define ARRAY_SIZE_G4   	(SCR_XSIZE*2/8*SCR_YSIZE)
#define ARRAY_SIZE_G16  	(SCR_XSIZE*4/8*SCR_YSIZE)
#define ARRAY_SIZE_COLOR 	(SCR_XSIZE*8/8*SCR_YSIZE)

#define HOZVAL			(LCD_XSIZE/4-1)//数据线位数位4,VD[3:0]
#define HOZVAL_COLOR	(LCD_XSIZE*3/8-1)//彩色模式时,数据线位数为8,VD[7:0]
#define LINEVAL			(LCD_YSIZE-1)//单扫描模式
#define MVAL			(13)

#define CLKVAL_MONO 	(6)
#define CLKVAL_G4 		(6)
#define CLKVAL_G16 		(6)
#define CLKVAL_COLOR 	(6)
#define MVAL_USED       (0)

void LcdInit(int color);

unsigned int (*frameBuffer1)[SCR_XSIZE*1/32];//ARM7的内存地址是4B(32位)对齐,指向数组的指针变量frameBuffer1,单色模式
unsigned int (*frameBuffer4)[SCR_XSIZE*2/32];//ARM7的内存地址是4B(32位)对齐,指向数组的指针变量frameBuffer4,4级灰度模式
unsigned int (*frameBuffer16)[SCR_XSIZE*4/32];//ARM7的内存地址是4B(32位)对齐,指向数组的指针变量frameBuffer16,16级灰度模式
unsigned int (*frameBuffer256)[SCR_XSIZE*8/32];//ARM7的内存地址是4B(32位)对齐,指向数组的指针变量frameBuffer256,彩色模式



/***************************************************
函数功能:初始化LCD控制器
输入参数:depth---单色模式为1,
               ---4级灰度模式为4
               ---16级灰度模式为16
               ---彩色模式为256
输出参数:无
***************************************************/
void Lcd_Init(int depth)
{
    //320x240 1bit/1pixel LCD
    rPDATC = ( rPDATC & (~(1<<8)) );//打开LCD显示屏
    
    switch(depth)
    {
       case 1://单色模式,每个像素1位,即2级灰度    
	   if((U32)frameBuffer1==0)
	   {
	      //The total frame memory should be inside 4MB.
	      //For example, if total memory is 8MB, the frame memory 
	      //should be in 0xc000000~0xc3fffff or c400000~c7fffff.
	      //But, the following code doesn't meet this condition(4MB) 
	      //if the code size & location is changed..
	      frameBuffer1=(unsigned int (*)[SCR_XSIZE/32])malloc(ARRAY_SIZE_MONO);//动态分配内存 
	   }

	   rLCDCON1=(0)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_MONO<<12);
	   //Disable ENVID,VD[7:0] Invert,4B_SNGL_SCAN,WDLY=16clk,WLH=16clk
	    
	   rLCDCON2=(LINEVAL)|(HOZVAL<<10)|(10<<21);  
	   //LINEBLANK=10 (without any calculation) 
	    
	   rLCDSADDR1= (0x0<<27) | ( ((U32)frameBuffer1>>22)<<21 ) | M5D((U32)frameBuffer1>>1);
	   //Monochrome mode, LCDBANK(4MB对齐), LCDBASEU(2B对齐)
	    
	   rLCDSADDR2= M5D( (((U32)frameBuffer1+(SCR_XSIZE*LCD_YSIZE*1/8))>>1) ) | (MVAL<<21);
	   //LCD_YSIZE是实屏高度,SCR_XSIZE是虚屏宽度,BSWP disable,LCDBASEL(2B对齐), MVAL
	   
	   rLCDSADDR3= (LCD_XSIZE*1/16) | ( ((SCR_XSIZE-LCD_XSIZE)*1/16)<<9 );
	   //LCD_XSIZE是实屏宽度,SCR_XSIZE是虚屏宽度,OFFSIZE, PAGEWIDTH都是以16位为单位

	   rLCDCON1=(1)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_MONO<<12);
	   //enable ENVID,4B_SNGL_SCAN,WDLY=16clk,WLH=16clk,
	   break;

    case 4://4级灰度
	if((U32)frameBuffer4==0)
	{
	    //The total frame memory should be inside 4MB.
	    //For example, if total memory is 8MB, the frame memory 
	    //should be in 0xc000000~0xc3fffff or c400000~c7fffff.
	    //But, the following code doesn't meet this condition(4MB) 
	    //if the code size & location is changed..
	    frameBuffer4=(unsigned int (*)[SCR_XSIZE/16])malloc(ARRAY_SIZE_G4); 
	}

	rLCDCON1=(0)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_G4<<12);
	//disable ENVID,VD[7:0] Invert,4B_SNGL_SCAN,WDLY=16clk,WLH=16clk
	    
	rLCDCON2=(LINEVAL)|(HOZVAL<<10)|(10<<21);  
	//LINEBLANK=10 (without any calculation) 
	   
	rLCDSADDR1= (0x1<<27) | ( ((U32)frameBuffer4>>22)<<21 ) | M5D((U32)frameBuffer4>>1);
	//4-gray mode, LCDBANK(4MB对齐), LCDBASEU(2B对齐)
	
	rLCDSADDR2= M5D((((U32)frameBuffer4+(SCR_XSIZE*LCD_YSIZE*2/8))>>1)) | (MVAL<<21);
	//LCD_YSIZE是实屏高度,SCR_XSIZE是虚屏宽度,BSWP disable,LCDBASEL(2B对齐), MVAL
	
	rLCDSADDR3= (LCD_XSIZE*2/16) | ( ((SCR_XSIZE-LCD_XSIZE)*2/16)<<9 );
	//LCD_XSIZE是实屏宽度,SCR_XSIZE是虚屏宽度,OFFSIZE, PAGEWIDTH都是以16位为单位

	//The following value has to be changed for better display.
	//Select 4 levels among 16 gray levels.
	rBLUELUT=0xfa40; 
	rDITHMODE=0x0;
	rDP1_2 =0xa5a5;      
	rDP4_7 =0xba5da65;
	rDP3_5 =0xa5a5f;
	rDP2_3 =0xd6b;
	rDP5_7 =0xeb7b5ed;
	rDP3_4 =0x7dbe;
	rDP4_5 =0x7ebdf;
	rDP6_7 =0x7fdfbfe;

	rLCDCON1=(1)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_G4<<12);
	//enable ENVID,4B_SNGL_SCAN,WDLY=16clk,WLH=16clk,
	break;

    case 16:
	if((U32)frameBuffer16==0)
	{
	    //The total frame memory should be inside 4MB.
	    //For example, if total memory is 8MB, the frame memory 
	    //should be in 0xc000000~0xc3fffff or c400000~c7fffff.
	    //But, the following code doesn't meet this condition(4MB) 
	    //if the code size & location is changed..
	    frameBuffer16=(unsigned int (*)[SCR_XSIZE/8])malloc(ARRAY_SIZE_G16); 
	}

	//The following value has to be changed for better display.
    rDITHMODE=0x12210;//芯片手册规定的值 	
    rDP1_2 =0xa5a5;      
	rDP4_7 =0xba5da65;
	rDP3_5 =0xa5a5f;
	rDP2_3 =0xd6b;
	rDP5_7 =0xeb7b5ed;
	rDP3_4 =0x7dbe;
	rDP4_5 =0x7ebdf;
	rDP6_7 =0x7fdfbfe;



	rLCDCON1=(0)|(1<<1)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_G16<<12);
	//disable ENVID,INVVD invert,4B_SNGL_SCAN,WDLY=16clk,WLH=16clk,
	
	rLCDCON2=(LINEVAL)|(HOZVAL<<10)|(10<<21);  
	//LINEBLANK=10 (without any calculation) 
	
	rLCDSADDR1= (0x2<<27) | ( ((U32)frameBuffer16>>22)<<21 ) | M5D((U32)frameBuffer16>>1);
	// 16-gray, LCDBANK(4MB对齐), LCDBASEU(2B对齐)
	
	rLCDSADDR2= M5D((((U32)frameBuffer16+(SCR_XSIZE*LCD_YSIZE*4/8))>>1)) | (MVAL<<21);
	//LCD_YSIZE是实屏高度,SCR_XSIZE是虚屏宽度,BSWP disable,LCDBASEL(2B对齐), MVAL
	
	rLCDSADDR3= (LCD_XSIZE*4/16) | ( ((SCR_XSIZE-LCD_XSIZE)*4/16)<<9 );
	//LCD_XSIZE是实屏宽度,SCR_XSIZE是虚屏宽度,OFFSIZE, PAGEWIDTH都是以16位为单位
	
	rLCDCON1=(1)|(1<<1)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_G16<<12);
	//enable ENVID, FS LCD set
	break;

    case 256:
	if((U32)frameBuffer256==0)
	{
	    //The total frame memory should be inside 4MB.
	    //For example, if total memory is 8MB, the frame memory 
	    //should be in 0xc000000~0xc3fffff or c400000~c7fffff.
	    //But, the following code doesn't meet this condition(4MB) 
	    //if the code size & location is changed..
	    frameBuffer256=(unsigned int (*)[SCR_XSIZE/4])malloc(ARRAY_SIZE_COLOR); 
	}

	rLCDCON1=(0)|(2<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_COLOR<<12);
    //disable ENVID,8B_SNGL_SCAN,WDLY=16clk,WLH=16clk,
    
	rLCDCON2=(LINEVAL)|(HOZVAL_COLOR<<10)|(10<<21);  
	//LINEBLANK=10 (without any calculation) 
	    
	rLCDSADDR1= (0x3<<27) | ( ((U32)frameBuffer256>>22)<<21 ) | M5D((U32)frameBuffer256>>1);
	//256-color, LCDBANK(4MB对齐), LCDBASEU(2B对齐)
	
	rLCDSADDR2= M5D((((U32)frameBuffer256+(SCR_XSIZE*LCD_YSIZE*8/8))>>1)) | (MVAL<<21);
	//LCD_YSIZE是实屏高度,SCR_XSIZE是虚屏宽度,BSWP disable,LCDBASEL(2B对齐), MVAL
	
	rLCDSADDR3= (LCD_XSIZE*8/16) | ( ((SCR_XSIZE-LCD_XSIZE)*8/16)<<9 );
	//LCD_XSIZE是实屏宽度,SCR_XSIZE是虚屏宽度,OFFSIZE, PAGEWIDTH都是以16位为单位

	//The following value has to be changed for better display.
	rREDLUT  =0xfdb96420;
	rGREENLUT=0xfdb96420;
	rBLUELUT =0xfb40;

	rDITHMODE=0x0;
	rDP1_2 =0xa5a5;      
	rDP4_7 =0xba5da65;
	rDP3_5 =0xa5a5f;
	rDP2_3 =0xd6b;
	rDP5_7 =0xeb7b5ed;
	rDP3_4 =0x7dbe;
	rDP4_5 =0x7ebdf;
	rDP6_7 =0x7fdfbfe;

	rLCDCON1=(1)|(2<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_COLOR<<12);
	//enable ENVID,8B_SNGL_SCAN,WDLY=16clk,WLH=16clk,
	break;

    default:
	        break;
    }	
}

/**********************************************
函数功能:在LCD显示屏上移动视口
输入参数:(vx,vy)
          depth---单色模式为1,
               ---4级灰度模式为4
               ---16级灰度模式为16
               ---彩色模式为256
输出参数:无
**********************************************/
void Lcd_MoveViewPort(int vx,int vy,int depth)
{
    U32 addr;
    switch(depth)
    {
    case 1:
    	// LCDBASEU,LCDBASEL register has to be changed before 12 words before the end of VLINE.
    	// In mono mode, x=320 is 10 words, So, We can't change LCDBASEU,LCDBASEL 
    	// during LINECNT=1~0 at mono mode. 

	    //The processor mode should be superviser mode.  
    	DisableInterrupt(); 

    #if (LCD_XSIZE<512)//LCD_XSIZE是实屏宽度,SCR_XSIZE是虚屏宽度
    	while((rLCDCON1>>22)<=1); // if x<512
    #else	
    	while((rLCDCON1>>22)==0); // if x>512 ((12+4)*32) 
    #endif

    addr=(U32)frameBuffer1+(vx/8)+vy*(SCR_XSIZE*1/8);
	rLCDSADDR1= (0x0<<27) | ( (addr>>22)<<21 ) | M5D(addr>>1);
	//LCD_XSIZE是实屏宽度,SCR_XSIZE是虚屏宽度,monochrome, LCDBANK 4MB对齐, LCDBASEU 2B对齐
	
	rLCDSADDR2= M5D( ((addr+(SCR_XSIZE*LCD_YSIZE*1/8))>>1) ) | (MVAL<<21);
	//LCD_YSIZE是实屏高度,SCR_XSIZE是虚屏宽度,LCDBASEL 2B对齐

	EnableInterrupt();
    break;

    case 4:
	    //The processor mode should be superviser mode.  
    	DisableInterrupt(); 

        #if (LCD_XSIZE<256)//LCD_YSIZE是实屏高度,SCR_XSIZE是虚屏宽度,
    	   while((rLCDCON1>>22)<=1); // if x<256
        #else	
    	   while((rLCDCON1>>22)==0); // if x>256
        #endif
    
        addr=(U32)frameBuffer4+(vx/4)+vy*(SCR_XSIZE*2/8);
	    rLCDSADDR1= (0x1<<27) | ( (addr>>22)<<21 ) | M5D(addr>>1);
	    //4-gray, LCDBANK 4MB对齐, LCDBASEU 2B对齐
	
	    rLCDSADDR2= M5D(((addr+(SCR_XSIZE*LCD_YSIZE*2/8))>>1)) | (MVAL<<21);
	    //LCD_YSIZE是实屏高度,SCR_XSIZE是虚屏宽度,LCDBASEL 2B对齐

	    EnableInterrupt();
        break;

    case 16:
	    //The processor mode should be superviser mode.  
        DisableInterrupt(); 

        #if (LCD_XSIZE<128)//LCD_YSIZE是实屏高度,SCR_XSIZE是虚屏宽度,
    	   while((rLCDCON1>>22)<=1); // if x<128
        #else	
    	   while((rLCDCON1>>22)==0); // if x>128
        #endif
        addr=(U32)frameBuffer16+(vx/2)+vy*(SCR_XSIZE*4/8);
	    rLCDSADDR1= (0x2<<27) | ( (addr>>22)<<21 ) | M5D(addr>>1);
	    //LCD_YSIZE是实屏高度,SCR_XSIZE是虚屏宽度,16-gray, LCDBANK 4MB对齐, LCDBASEU 2B对齐
	    
	    rLCDSADDR2= M5D(((addr+(SCR_XSIZE*LCD_YSIZE*4/8))>>1)) | (MVAL<<21);
	    //LCD_YSIZE是实屏高度,SCR_XSIZE是虚屏宽度,LCDBASEL 2B对齐

	    EnableInterrupt();
    	break;

    case 256:
	    //The processor mode should be superviser mode.  
    	DisableInterrupt(); 

        #if (LCD_XSIZE<64)//LCD_YSIZE是实屏高度,SCR_XSIZE是虚屏宽度,
    	   while((rLCDCON1>>22)<=1); // if x<64
        #else	
    	   while((rLCDCON1>>22)==0); // if x>64
        #endif
        addr=(U32)frameBuffer256+(vx/1)+vy*(SCR_XSIZE*8/8);
	    rLCDSADDR1= (0x3<<27) | ( (addr>>22)<<21 ) | M5D(addr>>1);
	    //LCD_YSIZE是实屏高度,SCR_XSIZE是虚屏宽度,256-color, LCDBANK 4MB对齐, LCDBASEU 2B对齐
	    rLCDSADDR2= M5D(((addr+(SCR_XSIZE*LCD_YSIZE*8/8))>>1)) | (MVAL<<21);
        //LCD_YSIZE是实屏高度,SCR_XSIZE是虚屏宽度,LCDBASEL 2B对齐
        
	    EnableInterrupt();
    	break;
    }
}    


/*****************************************
函数功能:打开LCD显示屏
输入参数:无
输出参数:无
*****************************************/
void Lcd_DispON(void)
{
	Delay(5000);
    rPDATC = ( rPDATC & (~(1<<8)) );
    Delay(5000);
}


/****************************************
函数功能:关闭LCD显示屏
输入参数:无
输出参数:无
****************************************/
void Lcd_DispOFF(void)
{
	Delay(5000);
    rPDATC = ( rPDATC | (1<<8) );
    Delay(5000);
}


/****************************************
函数功能:LCD显示屏上电复位
输入参数:无
输出参数:无
****************************************/
void Lcd_PowerReset(void)	
{
    U8 i;
    rPDATC = ( rPDATC | 3<<4 );		//crtl=1,adj=1
    for(i=0;i<1;i++);
    rPDATC = ( rPDATC & (~(1<<5)) );	//ctrl=0
    for(i=0;i<2;i++);
    rPDATC = ( rPDATC | 1<<5 );		//ctrl=1
    for(i=0;i<1;i++);
    rPDATC = ( rPDATC & (~(1<<4)) );	//adj=0

}

/****************************************
函数功能:LCD显示屏上电
输入参数:无
输出参数:无
****************************************/
void Lcd_PowerUp(void)
{
    U8 i;
    rPDATC = ( rPDATC | 2<<4 );		//ctrl=1,adj=0
    for(i=0;i<2;i++);
    rPDATC = ( rPDATC | 1<<4 );		//adj=1
    for(i=0;i<1;i++);
    rPDATC = ( rPDATC & (~(1<<4)) );	//adj=0
    for(i=0;i<2;i++);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -