实际效果图如下:
C程序如下:
#include #include #define uchar unsigned char #define uint unsigned int #define LCD P0 uchar chip_select=1; bit color=0; sbit e=P2^1; sbit rw=P2^2; sbit rs=P2^3; sbit cs2=P2^4; sbit cs1=P2^5; uchar line=0; uchar select=0; void delay(uint i) { while(i--); } /*************************** check busy ************************/ void checkBusy() //检查LCD是否忙 { uchar dat; rs=0; //指令操作 rw=1; //读出操作 do { LCD=0xff; //P0设置为输入 e=1; //给使能信号 dat=0x80&LCD; //只判断DB7位的状态 e=0; } while(dat==0x80); //忙则继续检测 } void lcdWrite(bit ml,uchar zifu) { checkBusy(); rs=ml; rw=0; P0=zifu; e=1; delay(1); e=0; } void ClearLCD(uchar zifu) { uchar i,j; lcdWrite(0,0x3f); cs1=1; cs2=1; for(i=0;i<8;i++) { lcdWrite(0,0xb8+i); lcdWrite(0,0xc0); lcdWrite(0,0x40); for(j=0;j<64;j++) { lcdWrite(1,zifu); } } } void initLCD() { cs1=1; cs2=1; lcdWrite(0,0x3e); //关显示 lcdWrite(0,0x3f); //开显示 ClearLCD(0x0f); //初始化 //清屏 } /*液晶显示函数*/ /*x和y来控制显示的位置,x为行,y为列,x1和y1为字的像素行数,x2为显示几行,y2为显示几个字数 */ void jis(uchar x,uchar y,uchar x1,uchar y1,uchar x2,uchar y2,uchar code *hz) { uchar i,j,k,l,a; lcdWrite(0,0x3f); //开显示 for(i=0;i for(j=0;j for(k=0;k lcdWrite(0,0xb8+x+i*x1+k); lcdWrite(0,0xc0); lcdWrite(0,0x40+y+j*y1); a=i*x1*y1*y2+j*x1*y1+k*y1; for(l=0;l lcdWrite(1,hz[a+l]); } } } } } /***************************** write data ************************/ void WriteData(uchar dsp_data) { if(chip_select==1) { cs1=1; cs2=0; } else { cs1=0; cs2=1; } checkBusy(); lcdWrite(1,dsp_data); } /**************************** read data ***********************/ uchar ReadData(void) { uchar dsp_data; checkBusy(); LCD=0xFF; if(chip_select==1) { cs2=0; cs1=1; } else { cs2=1; cs1=0; } rw=1; rs=1; e=1; e=0; e=1; //E的下降沿,然后E持续拉高读才有效 dsp_data=LCD; e=0; return(dsp_data); } uchar j=0,i=0; uchar r=32; uchar code hz[]= { 0x20,0x30,0xAC,0x63,0x10,0x00,0x40,0x20,0x58,0x47,0x44,0x48,0x50,0x20,0x20,0x00, 0x22,0x23,0x22,0x12,0x12,0x00,0x42,0x62,0x5A,0x46,0x42,0x42,0x52,0xE2,0x42,0x00,/*\"绘\ 0x00,0xFE,0x42,0x42,0x22,0x1E,0xAA,0x4A,0xAA,0x9A,0x0A,0x02,0x02,0xFE,0x00,0x00, 0x00,0xFF,0x42,0x42,0x41,0x41,0x48,0x72,0x54,0x40,0x41,0x43,0x41,0xFF,0x00,0x00,/*\"图\ 0x10,0x21,0x86,0x60,0x00,0x0C,0xD4,0x54,0x55,0xF6,0x54,0x54,0xD4,0x0C,0x04,0x00, 0x04,0xFC,0x03,0x00,0x00,0x00,0x8F,0x69,0x09,0x0F,0x09,0x29,0xCF,0x00,0x00,0x00,/*\"演\ 0x00,0x20,0x20,0x22,0x22,0x22,0x22,0xE2,0x22,0x22,0x22,0x22,0x22,0x20,0x20,0x00, 0x10,0x08,0x04,0x03,0x00,0x40,0x80,0x7F,0x00,0x00,0x01,0x02,0x0C,0x18,0x00,0x00,/*\"示\ }; /***********************在LCD上任意坐标画点********************************/ void DrawPoint(uchar X,uchar Y,uchar Type) { //X,Y化点的坐标Type画点的类型:2反相点,0檫除点,1画点 uchar DX = (Y >> 3); //计算出属于哪个字节 uchar BX = Y - (DX << 3); //计算出属于字节哪一位 uchar TempData = 0; if (X > 63) { chip_select=2; X -= 64; } else { chip_select=1; } lcdWrite(0,0xb8+DX); //设行地址 lcdWrite(0,0x40+X); //设列地址 TempData = ReadData(); //读出所画点所在字节的内容 switch (Type) //对该字节进行相应操作 { case 0: TempData &= ~(1< break; case 1: TempData |= (1 << BX); //画点 break; case 2: TempData ^= (1 << BX); //反相 break; } lcdWrite(0,0xb8+DX); //设行地址 lcdWrite(0,0x40+X); //设列地址 WriteData(TempData); //把修改后的字节送回LCD,达到画点目的 } /********插值法画任意两点之间直线的函数,函数中只用加减法,程序运行效率很高**********/ DrawLine(uchar x1,uchar y1,uchar x2,uchar y2) { //x1,y1起点坐标;x2,y2终点坐标; uchar x,y; uchar d_x,d_y; char err=0; uchar temp=0; if(y2 x=x1; y=y1; x1=x2; y1=y2; x2=x; y2=y; } d_y=y2-y1; if (d_y==0) { if (x1>x2) { x=x1; x1=x2; x2=x; } for ( x=x1;x<=x2;x++ ) DrawPoint(x,y1,1); } else { if(x2>=x1) { temp=1; d_x=x2-x1; } else d_x=x1-x2; x=x1; y=y1; DrawPoint(x,y,1); if(temp&&(d_y<=d_x)) while(x!=x2) { if(err<0) { x=x+1; err=err+(y2-y); } else { x=x+1; y=y+1; err=err+(y2-y)-(x2-x); } DrawPoint(x,y,1); } else if(temp&&(d_y>d_x)) while(y!=y2) { d_x=x2-x; d_y=y2-y; if(err<0) { x=x+1; y=y+1; err=err+d_y-d_x; } else { y=y+1; err=err-d_x; } DrawPoint(x,y,1); } else if(!temp&&(d_y<=d_x)) while(x!=x2) { d_x=x-x2; d_y=y2-y; if(err<0) { x=x-1; err=err+d_y; } else { x=x-1; y=y+1; err=err+d_y-d_x; } DrawPoint(x,y,1); } else if(!temp &&(d_y>d_x)) while(y!=y2) { d_x=x-x2; d_y=y2-y; if(err<0) { x=x-1; y=y+1; err=err+d_y-d_x; } else { y=y+1; err=err-d_x; } DrawPoint(x,y,1); } } } /***********************************************************************/ void DrawLevel(void) { for(i=0;i<127;i++) { DrawPoint(i,32,1); } //画水平直线 } /************************************************************************************/ void DrawSineWave(void) { uchar xn=0; uchar yn=32; uchar i; uchar xi,yi; for(i=0;i<127;i++) { xi=i; yi=(sin(i*0.1)*32)+32; DrawLine(xn,yn,xi,yi); //在一系列零散的点上,两点两点之间连线,从而得到一条曲线 xn=i; yn=yi; } } /*************************************************************************************/ void DrawCircle(uchar x0,uchar y0,uchar r)//x0,y0为圆心坐标,r为圆半径 { uchar xn,yn,xi,yi; unsigned int j; xn=cos(0)*r+x0; yn=sin(0)*r+y0; for(j=0;j<630;j++) { xi=(cos(j*0.01)*r)+x0; yi=(sin(j*0.01)*r)+y0; DrawLine(xn,yn,xi,yi); //在一系列零散的点上,两点两点之间连线,从而得到一条曲线 xn=xi; yn=yi; } } /**************************************************************************************************/ void DrawRetic(uchar x0,uchar y0,uchar x1,uchar y1)//画正方形,x0,y0为左上角坐标,x1,y1为右下角坐标 { DrawLine(x0,y0,x1,y0); DrawLine(x0,y0,x0,y1); DrawLine(x1,y0,x1,y1); DrawLine(x0,y1,x1,y1); /* uchar i; for(i=0;i<=x1-x0;i++) { DrawPoint(x0+i,y0,1); DrawPoint(x0+i,y1,1); } for(i=0;i<=y1-y0;i++) { DrawPoint(x0,y0+i,1); DrawPoint(x1,y0+i,1); }*/ } /**************************************************************************************************/ void DrawTrigle(uchar x1,uchar y1,uchar x2,uchar y2,uchar x3,uchar y3)//画三角形,三个坐标为三角形顶点 { DrawLine(x1,y1,x2,y2); DrawLine(x2,y2,x3,y3); DrawLine(x1,y1,x3,y3); } /******************************** **********************************************************/ void main(void) { initLCD(); while(1) { ClearLCD(0x00); cs1=1; main cs2=0; jis(0,32,2,16,1,2,hz); cs1=0;cs2=1; jis(0,0,2,16,1,2,hz+2*32); DrawLine(0,63,127,0); DrawRetic(10,10,100,50); DrawTrigle(63,17,20,60,100,60); DrawLevel(); DrawSineWave(); DrawCircle(63,32,r); r-=4; if (r<8) { r=32; } } } 因篇幅问题不能全部显示,请点此查看更多更全内容