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

📄 lcd_drv.c

📁 SED1335驱动程序
💻 C
字号:
//=============================================
//	320X240@单色LCD基本函数
//控制电路SED1335,总线方式
//==============================================
#include "lcd_defs.h"
#include "ha_defs.h"	//LCD寄存器地址
#include "type.h"
#include "font.h"
//--------1335初始化-------------------
void Init1335(void)
{
#ifndef LCD_DATABUS
	LCDCS = 0;
#endif
	LcdCommand(0x40);      //系统设置指令,8个参数
	LcdDataWrite(0x30);     
	LcdDataWrite(0x87);
	LcdDataWrite(0x07);	
	LcdDataWrite(39);	   //显示域长度为320dot                
	LcdDataWrite(66);      //确定液晶工作频率66                  
	LcdDataWrite(240);     //显示屏高度为240dot                
	LcdDataWrite(40);      //显示屏一行所占显示缓冲区字节数(L) 
	LcdDataWrite(0);       //显示屏一行所占显示缓冲区字节数(H) 

	LcdCommand(0x44);      //显示区设置,最多10个参数          
	LcdDataWrite(0x00);    //显示1区对应的显示RAM起始地址(L)   
	LcdDataWrite(0x00);    //显示1区对应的显示RAM起始地址(H)   
	LcdDataWrite(240);     //显示1区控制240行             
	LcdDataWrite(9600%256);//显示2区对应的显示RAM起始地址(L) (0+40×240=9600)
	LcdDataWrite(9600/256);//显示2区对应的显示RAM起始地址(H)   
	LcdDataWrite(240);     //显示2区控制240行             
	LcdDataWrite(SAD3%256);//显示3区对应的显示RAM起始地址(L) (19200)  
	LcdDataWrite(SAD3/256);//显示3区对应的显示RAM起始地址(H)   
	LcdDataWrite(SAD4%256);//显示4区对应的显示RAM起始地址(L) (28800)   
	LcdDataWrite(SAD4/256);//显示4区对应的显示RAM起始地址(H)   

	LcdCommand(0x5a);      //水平卷动,初始化时必须清零         
	LcdDataWrite(0x00);

	LcdCommand(0x5b);      //各个显示区的合成方式,1个参数      
	LcdDataWrite(0x0c);    //简单叠加,图形模式                          
	LcdCommand(0x59);      //打开显示,1个参数                 
	LcdDataWrite(0x14);    //开显示区1和2,不闪烁,光标关闭
#ifndef LCD_DATABUS
	LCDCS = 1;
#endif
}
//----清一、二屏-----------------
void LcdClear(void)
{
	INT8U i,j;
	
#ifndef LCD_DATABUS
	LCDCS = 0;
#endif
	LcdCommand(0x4c);    	//光标向后移动 
	LcdLocate(0,0,SAD1);	//第1区	
	LcdCommand(0x42);
	for(j=0;j<240;j++)
	{
		for(i=0;i<40;i++)
			LcdDataWrite(0x00);
	}
	LcdLocate(0,0,SAD2);	//第2区	
	LcdCommand(0x42);
	for(j=0;j<240;j++)
	{
		for(i=0;i<40;i++)
			LcdDataWrite(0x00);
	}
#ifndef LCD_DATABUS
	LCDCS = 1;
#endif
}
//--------清指定区域--------------------------------------------
//入口:(x1,y1)=左上角
//		(x2,y2)=右上角
void DisClrRec(INT16U x1,INT16U y1,INT16U x2,INT16U y2,INT16U offset)
{
	INT16U j,i;
	INT8U temp;

#ifndef LCD_DATABUS
	LCDCS = 0;
#endif
	LcdCommand(0x4c);    	//光标向后移动 
	for(j=y1;j<y2;j++)
	{
		temp = LcdRead(x1,j,offset);
		temp &= (0xff<<(8-x1%8));
		LcdWrite(x1,j,temp,offset);
	}	
	for(j=y1;j<y2;j++)
	{
  		LcdLocate(x1+8,j,offset);	
	    LcdCommand(0x42);
		for(i=x1+8;i<x2;i=i+8)
		{
			LcdDataWrite(0x00);
		}
	}
	for(j=y1;j<y2;j++)
	{
		temp = LcdRead(x2,j,offset);
		temp &= (0xff>>(x2%8));
		LcdWrite(x2,j,temp,offset);
	}	
#ifndef LCD_DATABUS
	LCDCS = 1;
#endif
}
//--------填充指定区域--------------------------------------------
//入口:(x1,y1)=左上角
//		(x2,y2)=右上角
void DisFullRec(INT16U x1,INT16U y1,INT16U x2,INT16U y2,INT16U offset)
{
	INT8U temp;
	INT16U i,j;

#ifndef LCD_DATABUS
	LCDCS = 0;
#endif
	LcdCommand(0x4c);    	//光标向后移动 
	for(j=y1;j<y2;j++)
	{
		temp = LcdRead(x1,j,offset);
		temp |= (0xff>>(x1%8));
		LcdWrite(x1,j,temp,offset);
	}	
	for(j=y1;j<y2;j++)
	{
  		LcdLocate(x1+8,j,offset);	
	    LcdCommand(0x42);
		for(i=x1+8;i<x2;i=i+8)
		{
			LcdDataWrite(0xff);
		}
	}
	for(j=y1;j<y2;j++)
	{
		temp = LcdRead(x2,j,offset);
		temp |= (0xff<<(8-x2%8));
		LcdWrite(x2,j,temp,offset);
	}	
#ifndef LCD_DATABUS
	LCDCS = 1;
#endif
}
//----画点-------------------------
//入口:(x,y)=位置
void DisDot(INT16U x,INT16U y,INT16U offset)
{
	INT8U temp;
#ifndef LCD_DATABUS
	LCDCS = 0;
#endif
	temp = LcdRead(x,y,offset);
	temp |= (0x80>>(x%8));
	LcdWrite(x,y,temp,offset);
#ifndef LCD_DATABUS
	LCDCS = 1;
#endif
}
//----擦除1点-------------------------
//入口:(x,y)=位置
void DisClrDot(INT16U x,INT16U y,INT16U offset)
{
	INT8U temp,temp1;
#ifndef LCD_DATABUS
	LCDCS = 0;
#endif
	temp = LcdRead(x,y,offset);
	temp1 = (0x80>>(x%8));
	temp1 = ~temp1;
	temp &= temp1;
	LcdWrite(x,y,temp,offset);
#ifndef LCD_DATABUS
	LCDCS = 1;
#endif
}
//-----虚线 只提供X或Y方向的,不支持斜线(11110000)-------------
//4点实4点虚间隔
//入口:(x1,y1)=起点
//		(x2,y2)=终点
//注意:终点坐标必须>=起点坐标
void Dashed(INT16U x1,INT16U y1,INT16U x2,INT16U y2,INT16U offset)
{
	INT16U i;
#ifndef LCD_DATABUS
	LCDCS = 0;
#endif
//画竖线
	if(x1==x2)
	{
		for(i=y1;i<=y2-3;i=i+8)
		{
			DisDot(x1,i,offset);
			DisDot(x1,i+1,offset);
			DisDot(x1,i+2,offset);
			DisDot(x1,i+3,offset);
		}
	}
//画横线
	else if(y1==y2)
	{			
		for(i=x1;i<x2-3;i=i+8)
		{
			DisDot(i,y1,offset);
			DisDot(i+1,y1,offset);
			DisDot(i+2,y1,offset);
			DisDot(i+3,y1,offset);
		}
	}
#ifndef LCD_DATABUS
	LCDCS = 1;
#endif
}
//----画实线-支持斜线-------------
//入口:neg=0,画,=1擦
//		(x1,y1)=起点,(x2,y2)=终点
//注意:画直线时终点坐标必须>=起点坐标
void Line(INT8U neg,INT16U x1,INT16U y1,INT16U x2,INT16U y2,INT16U offset)
{
	INT16U i;
	INT16U xerr=0,yerr=0;
    INT16U delta_x,delta_y,distance;
	INT16U  incx,incy;
#ifndef LCD_DATABUS
	LCDCS = 0;
#endif
//画竖线
	if(x1==x2)
	{
		for(i=y1;i<y2;i++)
		{
			if(neg)	DisClrDot(x1,i,offset);
			else	DisDot(x1,i,offset);	
		}
	}
//画横线
	else if(y1==y2)
	{			
		for(i=x1;i<x2;i++)
		{
			if(neg)	DisClrDot(i,y1,offset);
			else	DisDot(i,y1,offset);	
		}
	}
//画斜线	
	else
	{		
		if(x2>x1)
		{
			delta_x = x2-x1;		// 计算两个方向的距离
			incx = 1;
		}
		else
		{
			delta_x = x1-x2;
			incx = 2;
		}
		if(y2>y1)
		{
			delta_y = y2-y1;		// 计算两个方向的距离
			incy = 1;
		}
		else
		{
			delta_y = y1-y2;
			incy = 2;
		}
	
		if(delta_x>delta_y) 		//判断哪个方向增量大
			distance = delta_x;
		else 
			distance = delta_y;
	
		for(i=0;i<distance;i++) 	//画线
		{
			if(neg)	DisClrDot(x1,y1,offset);
			else	DisDot(x1,y1,offset);	
	 	   	xerr += delta_x ;
			yerr += delta_y ;
			if(xerr>=distance ) 	//计算哪些地方为45度斜线,哪些地方为横线或竖线
			{						//当x方向大于45度时,x+1,否则x不变 
				xerr -= distance;
	 		   	if(incx==2)	x1 -= 1;
	 		   	else 		x1 += incx;
			}
			if(yerr>=distance ) 
			{						//当y方向大于45度时,y+1,否则y不变
				yerr -= distance;
	 		    if(incy==2)	y1 -= 1;
	 		    else		y1 += incy;
			}
		}
	}		
#ifndef LCD_DATABUS
	LCDCS = 1;
#endif
}
//--------矩形框-----------------------------------------------------
//入口:(x1,y1)=左上角
//		(x2,y2)=右上角
void DisRec(INT16U x1,INT16U y1,INT16U x2,INT16U y2,INT16U offset)
{
#ifndef LCD_DATABUS
	LCDCS = 0;
#endif
	Line(0,x1,y1,x1,y2,offset);
	Line(0,x2,y1,x2,y2,offset);
	Line(0,x1,y1,x2,y1,offset);
	Line(0,x1,y2,x2+1,y2,offset);	
#ifndef LCD_DATABUS
	LCDCS = 1;
#endif
}
//-----在液晶屏指定位置显示一个8*12字符---------
//入口:neg=1 反白
//		(x,y)=起始坐标
//		ps=点阵指针
//注意:.x必须被8整除
void Dis8X12Chr(INT8U neg,INT16U x,INT16U y,INT8U chr,INT16U offset)
{
	INT8U i,temp;

#ifndef LCD_DATABUS
	LCDCS = 0;
#endif
	LcdCommand(0x4f);    			//光标向下移动 
	LcdLocate(x,y,offset);
	LcdCommand(0x42);    			//设置写命令
	for(i=0;i<12;i++)
	{
		temp = S8X12Tab[(chr-0x20)*12+i];
		if(neg) 	temp = ~temp;
		LcdDataWrite(temp);		//写数据
	}
#ifndef LCD_DATABUS
	LCDCS = 1;
#endif
}
//-----在液晶屏指定位置显示一个8*12字符串---------
//入口:neg=1 反白
//		(x,y)=起始坐标
//		ps=字符串指针
//注意:1.x必须被8整除,不处理换行
//		2.字符串为Ascii码
void Dis8X12Str(INT8U neg,INT16U x,INT16U y,INT8U *ps,INT16U offset)
{
	INT8U i;
	INT16U xbak;
#ifndef LCD_DATABUS
	LCDCS = 0;
#endif
	xbak = x;
	for(i=0;i<strlen((char *)(ps));i++)
	{
		Dis8X12Chr(neg,xbak,y,*(ps+i),offset);
		xbak += 8; 
	}	
#ifndef LCD_DATABUS
	LCDCS = 1;
#endif
}
//-----在液晶屏指定位置显示一个8*12字符串(无效0不显示)---------
//入口:neg=1 反白
//		(x,y)=起始坐标
//		ps=字符串指针
//注意:1.x必须被8整除,不处理换行
//		2.字符串为Ascii码
void Dis8X12DStr(INT8U neg,INT16U x,INT16U y,INT8U *ps,INT16U offset)
{
	INT8U i,flag=0;
	INT8U *pt;

	for(i=0;i<strlen((char *)(ps));i++)
		Dis8X12Chr(0,x+i*8,y,' ',offset);	
	for(i=0;i<strlen((char *)(ps));i++)
	{
		if(*ps == '-')	
		{
			ps++;
			flag = 1;
			continue;
		}	
		if((*ps == '0')&&(*(ps+1) != '.'))
			ps++;	
		else
			break;
	}	
	pt = ps;
	if(flag)	
	{
		Dis8X12Chr(neg,x,y,'-',offset);
		x += 8;
	}
	Dis8X12Str(neg,x,y,pt,offset);
}
//-----在液晶屏指定位置显示一个16*16汉字---------
//入口:neg=1 反白
//		(x,y)=起始坐标
//		p=点阵指针
//注意:x必须被8整除
void Dis16X16Chr(INT8U neg,INT16U x,INT16U y,INT8U *p,INT16U offset)
{
	INT8U i,j,temp;
	INT16U xbak;
#ifndef LCD_DATABUS
	LCDCS = 0;
#endif
	xbak = x;
	LcdCommand(0x4c);    		
	for(i=0;i<16;i++)//16
	{
		LcdLocate(xbak,y+i,offset);
		LcdCommand(0x42);    			//设置写命令
		for(j=0;j<2;j++)
		{
			temp = *(p+i*2+j);
			if(neg) 	temp = ~temp;	
			LcdDataWrite(temp);		//写数据
		}				
	}
#ifndef LCD_DATABUS
	LCDCS = 1;
#endif
}
/*
//-----在液晶屏指定位置显示一个16*16字符串---------
//字库按顺序排列,2分法查表
//x必须被8整除,不处理换行
//入口:neg=1 反白
//		(x,y)=起始坐标
//		p=字符串指针
//注意:1.x必须被8整除,不处理换行
//		2.字符串为汉字国标内码
void Dis16X16Str(INT8U neg,INT16U x,INT16U y,INT8U *p,INT16U offset)
{
	INT16U xbak,temp,i;
	INT8U *zikupoint;

	xbak = x;	
	while(*p != 0x00)		//0x00是字符串的结束标志
	{
		temp = *p;
		temp = (temp<<8)|*(p+1);
		i = Font2Tab(temp);	//2分法查	
		zikupoint = S16X16Tab+i*32;
		Dis16X16Chr(neg,xbak,y,zikupoint,offset);
		xbak += 16;
		p += 2;
	}
}
*/
//-----在液晶屏指定位置显示一个16*16字符串---------
//字库随机排列,从头顺序查表
//x必须被8整除,不处理换行
//入口:neg=1 反白
//		(x,y)=起始坐标
//		p=字符串指针
//注意:1.x必须被8整除,不处理换行
//		2.字符串为汉字国标内码
void Dis16X16Str(INT8U neg,INT16U x,INT16U y,INT8U *p,INT16U offset)  
{
	INT16U xbak,temp,i;
	INT8U *zikupoint;
	INT8U  j;

	xbak = x;	
	while(*p != 0x00)		//0x00是字符串的结束标志
	{
		for(i=0;;i++)
		{
			if(((GB_16[i].Index[0]== *p)&&(GB_16[i].Index[1]== *(p+1)))||(GB_16[i].Index[0]==0xff))
				break;	
		}
		
		zikupoint = &GB_16[i].Msk[0];
		Dis16X16Chr(neg,xbak,y,zikupoint,offset);
		xbak += 16;
		p += 2;
	}		
}
//-------在液晶屏指定位置显示一个32X32图标------------
void Dis32X32Chr(INT8U neg,INT16U x,INT16U y,INT16U chr,INT16U offset)
{
	INT8U i,j,temp;
	INT16U xbak;
#ifndef LCD_DATABUS
	LCDCS = 0;
#endif
	xbak = x;	
	LcdCommand(0x4c);    			//光标向右移动 
	for(i=0;i<32;i++)
	{
		LcdLocate(xbak,y+i,offset);
		LcdCommand(0x42);    			//设置写命令
		for(j=0;j<4;j++)
		{
			temp = S32X32Tab[chr*128+i*4+j];
			if(neg) 	temp = ~temp;	
			LcdDataWrite(temp);		//写数据
		}				
	}
#ifndef LCD_DATABUS
	LCDCS = 1;
#endif
}
/*
//------字库2分法查表---------------------
INT16U Font2Tab(INT16U ch)
{
	INT16U max,min,t;
	INT16U temp;
	min = 0;  max = strlen((INT8U *)(GB16X16Tab));
	do{
		t = ((max-min)/4)*2 + min;
		temp = GB16X16Tab[t];
		temp = (temp<<8)|GB16X16Tab[t+1];
		if(temp<ch)			min = t;
		else if(temp>ch) 	max = t;
		else	
		{
			min = t;	break;
		}
	}while((max-min)>2);
	return(min/2);
}*/
//-------在液晶屏指定位置显示一个图片PICTab[220*32]------------
void DisPic(INT16U x,INT16U y,INT16U offset)
{
	INT8U i,j,temp;
	INT16U xbak;
#ifndef LCD_DATABUS
	LCDCS = 0;
#endif
	xbak = x;	
	LcdCommand(0x4c);    			//光标向右移动 
	for(i=0;i<220;i++)
	{
		LcdLocate(xbak,y+i,offset);
		LcdCommand(0x42);    			//设置写命令
		for(j=0;j<32;j++)
		{
			temp = PICTab[i*32+j];
			LcdDataWrite(temp);		//写数据
		}				
	}
#ifndef LCD_DATABUS
	LCDCS = 1;
#endif
}
//--------光标定位在指定位置------------------
void LcdLocate(INT16U x,INT16U y,INT16U offset)
{
	INT16U add;
	LcdCommand(0x46);    			//设置光标地址,2个参数                
	add = x/8+y*40+offset;
	LcdDataWrite((unsigned char)add); 		//低位地址                
	LcdDataWrite((unsigned char)(add>>8)); 	//高位地址                  
}	
//-------读液晶显存 ----------------
unsigned char LcdRead(INT16U x,INT16U y,INT16U offset)
{
	INT8U temp=1;
	LcdLocate(x,y,offset);
	LcdCommand(0x43);    	//设置读命令   
	temp = LcdDataRead();
	return(temp);
}
//-------写液晶显存 ----------------
void LcdWrite(INT16U x,INT16U y,INT8U dat,INT16U offset)
{
	LcdLocate(x,y,offset);
	LcdCommand(0x42);    	//设置写命令                
	LcdDataWrite(dat);		//写数据
}
//-----写命令---------------------
void LcdCommand(INT8U c)
{
#ifndef LCD_DATABUS
	LCDRS = 1;
	LCDRD = 1;
	LCDWR = 0;
	_nop_();_nop_();
	LcmDataPort = c;
	_nop_();_nop_();
	LCDWR = 1;
#else
	LcdWriteCmd = c;
#endif
}
//-----写数据---------------------
void LcdDataWrite(INT8U d)
{
#ifndef LCD_DATABUS
	LCDRD = 1;
	LCDRS = 0;
	LCDWR = 0;
	_nop_();_nop_();
	LcmDataPort = d;
	_nop_();_nop_();
	LCDWR = 1;
#else
	LcdWriteData = d;
#endif
}
//-----读数据---------------------
INT8U LcdDataRead(void)
{
	unsigned char temp;
#ifndef LCD_DATABUS
	LCDRS = 1;
	LCDWR = 1;
	LcmDataPort = 0xff;
	LCDRD = 0;
	_nop_();_nop_();_nop_();_nop_();_nop_();
	temp = LcmDataPort;
	LCDRD = 1;	
#else	
	temp = LcdReadData;
#endif
	return(temp);	
}

//==============end==========================




⌨️ 快捷键说明

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