#includereg51.h#defineucharunsignedchar#defineuintunsignedintucharkey;uintb,n,j;sbitp4=P1^4;sbitp5=P1^5;sbitp6=P1^6;sbitp7=P1^7;sbitin1=P0^0;sbitin2=P0^1;sbitin3=P0^2;sbitin4=P0^3;sbitena=P0^4;sbitenb=P0^5;ucharturn1[]={0x02,0x06,0x04,0x0c,0x08,0x09,0x01,0x03};ucharturn2[]={0x03,0x01,0x09,0x08,0x0c,0x04,0x06,0x02};voiddelayms(uintj){uchari;for(;j0;j--){i=250;while(--i);i=249;while(--i);}}ucharksm(void){P1=0XF0;if((P1&0XF0)!=0XF0){delayms(10);if((P1&0XF0)!=0XF0){P1=0XFE;if(p4==0)key=16;if(p5==0)key=1;if(p6==0)key=2;if(p7==0)key=3;P1=0XFD;if(p4==0)key=4;if(p5==0)key=5;if(p6==0)key=6;if(p7==0)key=7;P1=0XFB;if(p4==0)key=8;if(p5==0)key=9;if(p6==0)key=10;if(p7==0)key=11;P1=0XF7;if(p4==0)key=12;if(p5==0)key=13;if(p6==0)key=14;if(p7==0)key=15;}}return(key);}voidmain(void){//P2=0x03;while(1){ksm();if(key==16)n=1;if(key==1)n=2;if(key==2)n=3;if(key==3)n=4;if(key==4)n=5;if(key==5)n=6;if(key==6)n=7;if(key==7)n=8;if(key==8)n=9;{for(b=0;b8;b++)if(n==1){P2=turn1[b];delayms(50);}}{for(b=0;b8;b++)if(n==2){P2=turn2[b];delayms(50);}}{if(n==3)P2=0x00;}{if(n==4)ena=1;in1=1;in2=0;}{if(n==5)ena=1;in1=0;in2=1;}{if(n==6)ena=0;in1=0;in2=0x00;}{if(n==7)enb=1;in3=1;in4=0;}{if(n==8)enb=1;in3=0;in4=1;}{if(n==9)enb=0;in3=0;in4=0;}}}12864unsignedcharY_i;//储存列unsignedcharPage_i;//储存页/**************************************************函数功能:检测LCD忙碌状态***********************************************/bitCheckBusy(void){bitflag;RW=1;//RW=1,RS=0时,在E=1时,状态送到数据总线RS=0;E=1;_nop_();_nop_();_nop_();_nop_();P2=0xff;//先将P2写1flag=(bit)P2&0x80;//读取数据位DB7的状态,DB7=1,则表示液晶忙碌(不可读写)E=0;//读完后,将E置低电平RS=1;//读完后,RS和RW需重新置1RW=1;returnflag;}/**************************************************函数功能:写指令到LCD***********************************************/voidWriteInstruction(unsignedcommand){while(CheckBusy==1);//若忙,等待RW=0;//写指令时,RW需置低电平0RS=0;//在RS=0时,于E的下降沿写入指令P2=command;//将指令通过P2口写入液晶_nop_();_nop_();E=1;_nop_();_nop_();E=0;//下降沿写入RS=1;//指令写完后,RS和RW需重新置1RW=1;}/**************************************************函数功能:写数据到LCD***********************************************/voidWriteData(unsigneddat){while(CheckBusy==1);//若忙,等待RW=0;//写数据时,RW需置0RS=1;//写数据时,RS=1E=1;_nop_();_nop_();P2=dat;//写入数据_nop_();_nop_();E=0;//在E的下降沿写入数据_nop_();_nop_();RS=0;//写完数据后,RS需置0RW=1;//写完数据后,RW需置1}/***********************************************************************函数功能:清屏***********************************************************************/voidClearLCD(void){unsignedchari,j;CS1=0;CS2=1;WriteInstruction(LCD_ON);//写指令,显示器打开WriteInstruction(BEGIN);//写指令,设置开始坐标for(i=0;i8;i++){WriteInstruction(SET_PAGE+i);//写指令,在第i页显示,每屏幕共8页WriteInstruction(SET_Y);//写指令,指定显示列for(j=0;j64;j++)WriteData(0x00);}//写数据,从0到64列均写0(不显示)CS1=1;CS2=0;WriteInstruction(LCD_ON);//写指令,显示器打开WriteInstruction(BEGIN);//写指令,设置开始坐标for(i=0;i8;i++){WriteInstruction(SET_PAGE+i);//写指令,在第i页显示,每屏幕共8页WriteInstruction(SET_Y);//写指令,指定显示列for(j=0;j64;j++)WriteData(0x00);}}/***********************************************************************函数功能:显示图形***********************************************************************/voidDraw(unsignedcharpage,unsignedcharyi,unsignedchar*ps,unsignedcharn){unsignedchari;WriteInstruction(SET_PAGE+page);//设置页WriteInstruction(SET_Y+yi);//设置列for(i=0;in;i++)//每次写n列{WriteData(*ps);//将指针ps所指的数据写入液晶ps++;//指向下一个数据}}/***********************************************************************函数功能:显示一个汉字***********************************************************************/voidDisplay_Character(unsignedchar*p){if(Y_i64)//屏幕1显示{CS1=0;//选中屏幕1CS2=1;Draw(Page_i,Y_i,p,8);//在Page_i页,Y_i列显示,每次显示8个数据Draw(Page_i,Y_i+8,p+8,8);Draw(Page_i+1,Y_i,p+16,8);Draw(Page_i+1,Y_i+8,p+24,8);//每个字32个点阵数据}else//屏幕2显示{CS1=1;//选中屏幕2CS2=0;Draw(Page_i,Y_i-64,p,8);Draw(Page_i,Y_i-56,p+8,8);Draw(Page_i+1,Y_i-64,p+16,8);Draw(Page_i+1,Y_i-56,p+24,8);}Y_i=Y_i+16;//每个字占16列,第一个字显示完后,指向显示第二个字的开始列。每行最多可显示8个汉字}/***********************************************************************函数功能:显示一个英文字符或数字***********************************************************************/voidDisplay_English(unsignedchar*p){if(Y_i64){CS1=0;//选中屏幕1CS2=1;Draw(Page_i,Y_i,p,8);//在gy页,gx列显示,每次显示8个数据Draw(Page_i+1,Y_i,p+8,8);}else{CS1=1;//选中屏幕2CS2=0;Draw(Page_i,Y_i-64,p,8);Draw(Page_i+1,Y_i-64,p+8,8);}Y_i=Y_i+8;//每个字占16列,第一个字显示完后,指向显示第二个字的开始列}/***********************************************************************函数功能:指定显示位置入口参数:page_i:指定显示页y_i:指定显示列***********************************************************************/voidgotoxy(unsignedpage_i,unsignedy_i){Page_i=page_i;//在第Page_i页显示Y_i=y_i;//在第Y_i列显示}/***********************************************************************函数功能:初始化12864LCD。说明:清屏,指定按键的显示位置。***********************************************************************/voidLCD_Init(void){ClearLCD;//清屏gotoxy(3,0);//在第3页,0列显示Display_Character(dian);//显示汉字“按”Display_Character(d6);//显示汉字“键”Display_Character(d3);//显示汉字“按”Display_Character(zhao);//显示汉字“键”Display_Character(guang);//显示汉字“按”Display_Character(yao);//显示汉字“键”//gotoxy(3,80);//Display_English(L);//显示“L”//Display_English(pe