#include<AT89X52.H>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
#define L240DAT P1
#define N 60
sbit L240CD=P3^2;
sbit L240RD=P3^3;
sbit L240WR=P3^4;
sbit L240BC=P1^0;
sbit L240BD=P1^1;
sbit RST=P3^5;
uchar code dat0[61]={16,16,28,50,68,80,92,100,92,80,68,50,28,15,28,46,60,46,28,17,15,28,34,28,15,20,15,16,28,50,68,
80,92,100,92,80,68,50,28,15,28,46,60,46,28,17,15,28,34,28,15,20,15,16,18,20,27,38,49,62,80};
uchar dat1[5];
void Delay(int x)
{int k,m;
{ for(m=0;m<x;m++)
for(k=0;k<25;k++);
}
}
void LCD_NOP(void)
{
unsigned char i;
for(i=0;i<5;i++);
}
uchar l240rc(void)
{
uchar chk;
L240DAT=0xff;
L240RD=1;
L240CD=1;
L240RD=0;
chk=L240DAT;
L240RD=1;
return chk;
}
void l240wcl(uchar dat1,uchar dat2,uchar com)
{
while((l240rc()&0x03)!=0x03);
L240CD=0;
L240DAT=dat1;
L240WR=0;
LCD_NOP();
L240WR=1;
while((l240rc()&0x03)!=0x03);
L240CD=0;
L240DAT=dat2;
L240WR=0;
LCD_NOP();
L240WR=1;
while((l240rc()&0x03)!=0x03);
L240CD=1;
L240DAT=com;
L240WR=0;
LCD_NOP();
L240WR=1;
}
void l240wc(uchar dat)
{
while((l240rc()&0x03)!=0x03);
L240CD=1;
L240DAT=dat;
L240WR=0;
LCD_NOP();
L240WR=1;
}
void l240wd(uchar dat)
{
while((l240rc()&0x03)!=0x03);
L240CD=0;
L240DAT=dat;
L240WR=0;
LCD_NOP();
L240WR=1;
}
void l240wdz(uchar dat) //進入自動讀寫模式時判忙函數
{
while((l240rc()&0x08)!=0x08);
L240CD=0;
L240DAT=dat;
L240WR=0;
LCD_NOP();
L240WR=1;
}
void intl240(void)
{
L240CD=1;
L240WR=1;
L240RD=1;
L240BC=1;
L240BD=1;
l240wcl(0x00,0x00,0x40);//初始化
l240wcl(0x20,0x00,0x41);
l240wcl(0x00,0x08,0x42);
l240wcl(0x20,0x00,0x43);
l240wc(0xa7);
l240wc(0x81);
}
void writepoint(uchar x,uchar y,uchar show)
{
uchar x_pt,y_pt;
uint address;
x_pt=x;
if(show==1)
y_pt=y+128;
address=(y_pt&0x7f)*32+x_pt/8+0x0800; //計算顯示存儲器地址
l240wcl((uchar)(address),(uchar)(address>>8),0x24); //設置顯示存儲器地址
x_pt=(~(x_pt%8))&0x07;
y_pt=((y_pt&0x80)>>4)|0xf0;
l240wc(x_pt|y_pt); //寫入數據
}
//設置地址
void glcd_set_address(unsigned int addr){
l240wd((unsigned char)(addr));
l240wd(addr>>8);
l240wc(0x24); //0x24為設定地址命令
}
void clear_graph(void) // 圖形清屏
{
int i;
glcd_set_address(0x800); // 設置地址為圖形區基地址
for (i=0;i<3840*2;i++) // 必須為3840
{
l240wd(0); // 寫入數據0x00 則不顯示
l240wc(0xc0); // 0xc0為數據寫入、增加指針 命令
}
}
void clear_c(void) //清文本
{ int m;
l240wcl(0x00,0x00,0x24);
l240wc(0xb0);
for(m=0;m<0x0800;m++)
{
l240wdz(0x00);
}
l240wc(0xb2);
}
void line(int x1, int y1, int x2, int y2, unsigned char show)
{
int dy ;
int dx ;
int stepx, stepy, fraction;
dy = y2 - y1;
dx = x2 - x1;
if (dy < 0)
{
dy = -dy;
stepy = -1;
}
else
{
stepy = 1;
}
if (dx < 0)
{
dx = -dx;
stepx = -1;
}
else
{
stepx = 1;
}
dy <<= 1;
dx <<= 1;
if((x2<240&x1>0)|(x1<240&x2>0))
{writepoint(x1,y1,show);}
if (dx > dy)
{
fraction = dy - (dx >> 1);
while (x1 != x2)
{
if (fraction >= 0)
{
y1 += stepy;
fraction -= dx;
}
x1 += stepx;
fraction += dy;
if((x2<240&x1>0)|(x1<240&x2>0))
{writepoint(x1,y1,show); }
}
}
else
{
fraction = dx - (dy >> 1);
while (y1 != y2)
{
if (fraction >= 0)
{
x1 += stepx;
fraction -= dy;
}
y1 += stepy;
fraction += dx;
if((x2<240&x1>0)|(x1<240&x2>0))
{writepoint(x1,y1,show);}
}
}
if((x2<240&x1>0)|(x1<240&x2>0))
{ writepoint(x1,y1,show); }
}
uchar nihe(int y0,int y1,int y2,int i)
{ float y;
if (i==1)
y=21*y0/32+y1*7/16-y2*3/32;
else if(i==2)
y=-y0/2+y1*4/3+y2/6;
else y=-y0/3+y1+y2/3;
return(y);
}
void quxian(void)
{ int i,j;
uchar a;
signed char dy;
clear_graph();
line(1,0,1,127,1);
line(1,127,239,127,1);
for(i=0;i<N;i++)
{dat1[0]=dat0[i];
dat1[1]=nihe(dat0[i],dat0[i+1],dat0[i+2],1);
dat1[2]=nihe(dat1[0],dat1[1],dat0[i+1],2);
dat1[3]=nihe(dat1[1],dat1[2],dat0[i+1],3);
dat1[4]=dat0[i+1];
for(j=0;j<4;j++)
{ dy=dat1[j]-dat1[j+1];
line(4*i,127,4*i,127-dat0[i],1);
if(dy>=0)
{for(a=0;a<dy;a++) //下降
{writepoint(4*i+j,(128-(dat1[j]-a)),1);}
writepoint(4*i+j+1,(128-(dat1[j]-a)),1);
}
else
{for(a=0;a<(-(dy));a++) //上升
{writepoint(4*i+j,(128-(dat1[j]+a)),1);}
writepoint(4*i+j,(128-(dat1[j]+a)),1);
}
}
}
}
main()
{ RST=0;
Delay(10);
RST=1;
Delay(50);
intl240(); ///初始化必有
clear_c();
clear_graph();
l240wc(0x9c);
while(1){
quxian();
}
}