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

📄 lcd.c

📁 C8051FTest.rar 是C8051F系列处理器的基本测试程序
💻 C
字号:
#include <string.h>
#include <stdio.h>
#include <absacc.h>
#include "ASCII.h"
#include "LCD.h"
#include "System.h"

#define BASE 0x8000

//
unsigned char code line[] = {"肀肀肀肀肀肀肀肀肀肀肀肀肀肀肀肀肀肀肀肀"}; // 分割线
unsigned char code UpArrow[]={"芗"};
unsigned char code DownArrow[]={"兦"};
unsigned char code LeftArrow[]={"阼"};
unsigned char code RightArrow[]={"囿"};

//写命令函数
void CmdWrite(unsigned char n)    
{
     RES=1;
     A0=1;
     WR=0;
	 P6MDOUT = 0XFF;			
	 P6=n;
     WR=1;
     A0=0;   
}

//写数据函数
void DataWrite(unsigned char  m)
{   
   RES=1;
   A0=0;
   WR=0;
   P6MDOUT = 0XFF;
   P6=m;
   WR=1;
   A0=1;   
}


//清屏函数,清空LCDfrom行至to行
void Clear(int from,int to)
{
	int i,j;
	CS=0;
	CmdWrite(CSRDIR_RIGHT);   		//光标移动方向4cH
	Locatexy(0,from);
	CmdWrite(MWRITE);         		//数据写入显示缓冲区42H
	for(i=from;i<to;i++)
	{ 
		for(j=0;j<40;j++)
		DataWrite(0x00);
	}
	CS=1; 	
}

//LCD初始化函数
void Init_LCD()
{ 
  	mLES_SW=1;           //将LEDWS(P7^0)置1,LED由P5控制  
  	CS=0;                //片选LCD
  	RES=0;               //LCD Reset
  
  	CmdWrite(SYSTEMSET); //SYSTEM SET 指令代码 40H
  
  	DataWrite(0x30);   	//P1 00110000B B=1;无边界 W/S=0,为单屏结构;M0~M3=0; 8*8点阵
  	DataWrite(0x87);   	//P2 10000111B WF=1,FX=7,显示字符宽为8像素
  	DataWrite(0x07);   	//P3 00000111B FY=7,显示字符高为8像素
  	DataWrite(0x27);   	//P4_CR 一行能显示40(0X27)个字符,即320/8=40byte
  	DataWrite(0x42);   	//P5_TC/R=10MHz/(9*240*70Hz)=66(0x42)
  	DataWrite(0xf0);   	//P6_L/F 显示屏有 240行(0xEF)
  	DataWrite(0x28);   	//P7_APL显示屏一行所占显示缓冲区40字节,   
  	DataWrite(0x00);   	//P8_APH

	CmdWrite(SCROLL); 	//SCROLL 指令代码0x44H 显示区设置
   
  	DataWrite(0x00);  	//P1_SAD1L_第一显示区的起始地址从显示RAM0x00开始
  	DataWrite(0x00);  	//P2_SAD1H
  	DataWrite(0xf0);  	//P3_SL1___第一显示区共有240行

  	DataWrite(0x00);  	//P4_SAD2L_第二显示区的首地址从显示RAM 9600地址开始 2580H
  	DataWrite(0x00);  	//P5_SAD2H
  	DataWrite(0x00);  	//P6_SL2___第二显示区共有240行

  	DataWrite(0x80);  	//P7_SAD3L_第3显示区的首地址从显示RAM 0x7080地址开始
  	DataWrite(0x25);  	//P8_SAD3H  

  	DataWrite(0x00);  	//P9_SAD4L
  	DataWrite(0x00);  	//P10_SAD4H
   
  	CmdWrite(HDOTSCR);   //HDOTEST 指令代码 0x5AH 点位置设置,初始化时清零
  	DataWrite(0x00);

	CmdWrite(OVLAY);     //设置双层合成显示方式0x5BH 
  	DataWrite(0x0c);     //图形显示方式00001100,DM1=1,DM2=1;  二重合成显示方式,或逻辑, 图形显示方式
 
 	CmdWrite(DISPON);    //开显示0x59H
	DataWrite(0x44);     //0100 0100B第1,3显示区工作,光标不显示

	Clear(0,480);		 //1,3区全部清空
  	CS=1;
}

unsigned int LCD_RAM_ORG=LCD_Area1;	//设置工作区为1区
//光标定位,x以字节为单位,y以点为单位,LCD左上角为坐标原点,LCD_RAM_ORG控制LCD工作区
void Locatexy(unsigned char  x,unsigned char y)
{
    unsigned int temp;
    temp =(unsigned int) y*40+x+LCD_RAM_ORG;
    CmdWrite(CSRW);               // 光标Locate,定位
    DataWrite( (unsigned char)(temp) );  // 写入参数CSRL设置参数光标指针低8位
    DataWrite( (unsigned char)(temp>>8) );   // 写入参数CSRH设置参数光标指针高8位
}


/*******************画点函数*************************/
void Point(int x,unsigned char y)			//在x,y坐标处(都是点坐标)画点.x-[0,320),y-[0,240)
{
	unsigned char temp=0x80;
	unsigned char value;
	temp=(temp >> (x%8));
	CS=0;
	//先读出该点数据
	Locatexy(x/8,y);	//定位
	CmdWrite(MREAD);	//发读命令
	
	P6MDOUT=0x00;       //配置P6为数字输入 (数字输入=漏极开路+SFR写1)
	P6=0xff;	
	A0=1;
	RD=0;
	RD=1;
	value=P6;
	A0=0;
	P6MDOUT=0xFF;

	Locatexy(x/8,y);			//重新定位
	CmdWrite(MWRITE);
	DataWrite(temp|value);		//写入数据
	CS=1;
}
           
//写汉字和字符函数
void  dprintf(unsigned char  x,unsigned char  y, char *ptr)   
{
	unsigned char c1,c2;
	unsigned int i,j,uLen,uRow,uCol;
	unsigned char temp;
	unsigned int k;
	unsigned int offset;
   
	CS=0;
	uRow=x%40;
	uCol=y%240;
	uLen=0;
  
	CmdWrite(CSRDIR_DOWN);  /*光标移动方向定义,自动下移*/
	Locatexy(uRow,uCol);
	
	while((unsigned char)ptr[uLen]>=0x20){uLen++;};  /*探测字符串长度*/
	i=0;
	while(i<uLen)
	{
		c1=ptr[i];
		c2=ptr[i+1];

		if(c1 <=128)                        // ASCII
        {
            if (c1 >= 0x20) 
			{
                CmdWrite( MWRITE );         // 写数据(命令)
                for(j=0;j<16;j++) DataWrite( ASC_MSK[(c1-0x20)*16 +j ]);
            }
            uRow++;                     // 列数加1
        }
		else   // 汉字
    	{   
			offset=0;
			//调整bank页,从第3页中取常数
			PSBANK=0x31;
			while(CBYTE[BASE+offset]!=0xFF || CBYTE[BASE+offset+1]!=0xFF)
			{	
				unsigned cc1,cc2;
				cc1=CBYTE[BASE+offset];
				cc2=CBYTE[BASE+offset+1];
				if(CBYTE[BASE+offset]==c1 && CBYTE[BASE+offset+1]==c2)
				break;
				offset+=34;
			}
			for(k=0;k<2;k++)   //分两列显示该汉字字模,先显示左半部分,再显示右半部分
			{
				Locatexy(uRow+k,uCol);
      			CmdWrite(CSRDIR_DOWN);
				CmdWrite(MWRITE);     //写数据命令
				for(temp=0;temp<16;temp++) 
				{ 
					DataWrite( CBYTE[BASE+offset+2+temp*2+k]);
				}
			}
			PSBANK=0x11;
			uRow+=2;
			i++;

		}

		if(uRow >= 40)          // 光标后移
		{
			uCol += 16;
			uRow = 0;
			if( uCol >= 240 ) uCol = 0;
		}
     	Locatexy(uRow,uCol);
		i++;
	}
	CS=1;
}
//反色显示汉字,字符
void  Udprintf(unsigned char  x,unsigned char  y, char *ptr)   
{
   unsigned char c1,c2;
   unsigned int i,j,uLen,uRow,uCol;
   unsigned char temp;
   unsigned int k;
   unsigned int offset;
   
   CS=0;
   uRow=x%40;
   uCol=y%240;
   uLen=0;
	 
   CmdWrite(CSRDIR_DOWN);  /*光标移动方向定义,自动下移*/
   Locatexy(uRow,uCol);
	
   while((unsigned char)ptr[uLen]>=0x20){uLen++;};  /*探测字符串长度*/
   i=0;
   while(i<uLen)
   {
   c1=ptr[i];
   c2=ptr[i+1];

    if(c1 <=128)                        // ASCII
        {
            if (c1 >= 0x20) {
                CmdWrite( MWRITE );         // 写数据(命令)
                for(j=0;j<16;j++) DataWrite( ~ASC_MSK[(c1-0x20)*16 +j]);
            }
            uRow++;                     // 列数加1
        }

	else   // 汉字
    	{	
			offset=0;
			//调整bank页,从第3页中取常数   
		 	PSBANK=0x31;
			while(CBYTE[BASE+offset]!=0xFF || CBYTE[BASE+offset+1]!=0xFF)
			{
				if(CBYTE[BASE+offset]==c1 && CBYTE[BASE+offset+1]==c2)
				break;
				offset+=34;
			}
			for(k=0;k<2;k++)   //分两列显示该汉字字模,先显示左半部分,再显示右半部分
			{
				Locatexy(uRow+k,uCol);
      			CmdWrite(CSRDIR_DOWN);
				CmdWrite(MWRITE);     //写数据命令
				for(temp=0;temp<16;temp++) 
				{ 
					DataWrite( ~CBYTE[BASE+offset+2+temp*2+k]);
				}
			}
			PSBANK=0x11;
			uRow+=2;
			i++;
      }

   if(uRow >= 40)          // 光标后移
        {
           uCol += 16;
           uRow = 0;
           if( uCol >= 240 ) uCol = 0;
        }
     
      Locatexy(uRow,uCol);
      i++;
}
   CS=1;
}

//在x,y处用n位显示一个无符号数,不足n位左端补齐字符c。TYPE=0正常显示,=1反色显示
void putufig(unsigned char  x,unsigned char  y, unsigned long ulong,char n,char TYPE,char c)
{
	char buf[12];
	char len,i;
	sprintf(buf,"%lu",ulong);
	len=strlen(buf);
	if( len<n )
	{
		for(i=n;i>=0;i--)
		{	
			if(len>=0)
			{
				buf[i]=buf[len];
				len--;
			}
			else
			{
				buf[i]=c;
			}
		}
	}
	if(TYPE==0)
	dprintf(x,y,buf);
	else
	Udprintf(x,y,buf);
}

//以十六进制形式显示uchar	例如: 16H
void puthex(unsigned char  x,unsigned char  y, unsigned char hex)
{
	unsigned int low,high;
	char buf[5];
	high=hex/16;
	low=hex%16;
	sprintf(buf,"%X%X%s",high,low,"H");
	dprintf(x,y,buf);
}

//以二进制形式显示uchar		例如: 00010110
void putbin(unsigned char  x,unsigned char  y, unsigned char bin)
{
	int i;
	char buf[10];
	for(i=7;i>=0;i--)
	{
		if(bin%2)	buf[i]='1';
		else		buf[i]='0';
		bin/=2;
	}
	buf[8]='\0';
	dprintf(x,y,buf);
}

unsigned char X,Y,F;                                  			//全局变量,记录屏幕坐标
//显示文本,在全局变量x,y中保存光标位置,如果一页显示满则F置一
char * tprintf(unsigned char  x,unsigned char  y, char *ptr)   	
{																//显示字符串,直到屏幕写满(F=1)或写完(F=0)。
    unsigned char c1,c2;										//返回指针指向所写最后一个字符的下一个。
    unsigned int  i,j,uLen;
    unsigned char temp,uRow,uCol;
    unsigned int k;
	unsigned int offset;

    CS=0;
    uRow=x;
    uCol=y;
    uLen=0;
  
    CmdWrite(CSRDIR_DOWN);  /*光标移动方向定义,自动下移*/
    Locatexy(uRow,uCol);
	
	uLen=strlen(ptr);
	i=0;
	while(i<uLen)
	{	
		c1=ptr[i];
    	c2=ptr[i+1];
	    if( c1 <= 128 )                         // ASCII
   		{
			if(uRow >= 40)						//ASCII换行
	    	{
        		uCol += 16;
        		uRow = 0;
       		}
			if( uCol >= 208)        			//写满一页    
			{
				F=1;
		   		return ptr+i;
			}
			Locatexy(uRow,uCol);
			if( c1==13 )			//文本文档中换行 = /r+/n (13+10)
			{
        		uRow = 0;
				i++;
			}
			else
			{
				if( c1==10 )			//文本文档中换行 = /r+/n (13+10)
				{
					uCol += 16;
					i++;
				}
       	 		else
				{	
           	 		CmdWrite( MWRITE );				// 写数据(命令)
           	 		for(j=0;j<16;j++) DataWrite( ASC_MSK[(c1-0x20)*16 +j]);
       				uRow++;							//将光标调整到下一位置
					i++;
				}
			}
   		}
		else  // 汉字
   		{   
			if(c2==0)				//数据不完整,放弃显示
			{
				F=0;
				return ptr+i;
			}
			if(uRow >= 39)				//汉字换行,可能空一列
    		{
        		uCol += 16;
        		uRow = 0;
       		}           
			if( uCol >= 208)        //写满一页    
			{
				F=1;
		   		return ptr+i;
			}
			offset=0;
			//调整bank页,从第3页中取常数 
			PSBANK=0x31;
			while(CBYTE[BASE+offset]!=0xFF || CBYTE[BASE+offset+1]!=0xFF)
			{
				if(CBYTE[BASE+offset]==c1 && CBYTE[BASE+offset+1]==c2)
				break;
				offset+=34;
			}
			for(k=0;k<2;k++)   //分两列显示该汉字字模,先显示左半部分,再显示右半部分
			{
				Locatexy(uRow+k,uCol);
      			CmdWrite(CSRDIR_DOWN);
				CmdWrite(MWRITE);     //写数据命令
				for(temp=0;temp<16;temp++) 
				{ 
					DataWrite(CBYTE[BASE+offset+2+temp*2+k]);
				}
			}
			PSBANK=0x11;
			uRow+=2;
			i+=2;
		}

	}//while(i<len)
    CS=1;
	X=uRow;
	Y=uCol;                     	//记录屏幕坐标
	F=0;							//表明正常写完字符串,未写满一页
    return ptr+i;				 	//写完返回'\0'
}

//给定两点连结一条直线(屏幕左上角为坐标原点)
void drawline(int x1,int y1,int x2,int y2)
{
	double k;						//斜率
	int minx,maxx,miny,i,j;
	int py;							//记录前一个点的纵坐标

	if(x1<x2)					
	{
		minx=x1;
		maxx=x2;
		miny=y1;
	}
	else
	{
		minx=x2;
		maxx=x1;
		miny=y2;
	}

	if(x1==x2)
	{
		if(y1<=y2)
		for(i=y1;i<=y2;i++)
		Point(x1,i);
		else
		for(i=y2;i<=y1;i++)
		Point(x1,i);
	}
	else
	{
		k=(double)(y2-y1)/(x2-x1);	
		py=miny;						//py初值
		for(i=minx;i<=maxx;i++)			
		{
			unsigned char y;			//当前点的纵坐标
			y=(unsigned char)(k*(i-minx)+miny+0.5);
			Point(i,y);
			if(y<py)					//插入点,使线连续
			for(j=y+1;j<py;j++)
			Point(i,j);
			if(y>py)
			for(j=py+1;j<y;j++)
			Point(i,j);
			py=y;
		}
	}
}

//将n个点连结起来
void link(int *pointlist)
{
	int n,i;
	n=pointlist[0];
	if(n<2)
	return;
	for(i=0;i<n-1;i++)
	drawline(pointlist[2*i+1],pointlist[2*i+2],pointlist[2*i+3],pointlist[2*i+4]);
}

void circle(unsigned char ox,unsigned char oy,unsigned char r)
{
	int x,y;
	for(x=r;x>=0;x--)
	{
		y=r;
		while(x*x+y*y>r*r)	y--;
		Point(ox-x,oy+y);
		Point(ox+x,oy+y);
		Point(ox+x,oy-y);
		Point(ox-x,oy-y);		
	}

}

⌨️ 快捷键说明

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