📄 lcd.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 + -