以lcd12864作为显示屏,实现一个按钮控制的简单小游戏。主要工作集中于游戏的图形化以及相关逻辑的实现。人物场景设计通过字模提取软件转换成为段码预先储存在单片机中,动画的实现采取局部刷新的方式以提高显示的速度。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
代码:
- #include <reg51.h>
- #define LCDLCDDisp_Off 0x3e
- #define LCDLCDDisp_On 0x3f
- #define Page_Add 0xb8//ye
- #define LCDCol_Add 0x40//lie
- #define Start_Line 0xC0//hang
- /*****液晶显示器的端口定义*****/
- #define data_ora P1 /*液晶数据总线*/
- sbit LCDMcs=P2^4 ; /*片选1*/
- sbit LCDScs=P2^3 ; /*片选2*/
- sbit LCDDi=P2^2 ; /*数据/指令 选择*/
- sbit LCDRW=P2^1 ; /*读/写 选择*/
- sbit LCDEnable=P2^0 ; /*读/写 使能*/
- unsigned char flag;//flag=0,死亡,flag=1,闪避成功
- unsigned char code Ph[] =
- {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x04,0x74,0x44,0x5C,0xC0,0x00,0x00,0x00,0x00,0x00,0xE0,0x10,0x48,0xA4,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
- };
-
- void LCDdelay(unsigned int t)
- {
- unsigned int i,j;
- for(i=0;i<t;i++);
- for(j=0;j<10;j++);
- }
- void CheckState()
- {
- unsigned char dat,DATA;//状态信息(判断是否忙)
- LCDDi=0; // 数据\指令选择,D/I(RS)="L" ,表示 DB7∽DB0 为显示指令数据
- LCDRW=1; //R/W="H" ,E="H"数据被读到DB7∽DB0
- do
- {
- DATA=0x00;
- LCDEnable=1; //EN下降源
- LCDdelay(2);//延时
- dat=DATA;
- LCDEnable=0;
- dat=0x80 & dat; //仅当第7位为0时才可操作(判别busy信号)
- }
- while(!(dat==0x00));
- }
- void write_com(unsigned char cmdcode)
- {
- CheckState();//检测LCD是否忙
- LCDDi=0;
- LCDRW=0;
- P1=cmdcode;
- LCDdelay(2);
- LCDEnable=1;
- LCDdelay(2);
- LCDEnable=0;
- }
- void init_lcd()
- {
- LCDdelay(100);
- LCDMcs=1;//刚开始关闭两屏
- LCDScs=1;
- LCDdelay(100);
- write_com(LCDLCDDisp_Off); //写初始化命令
- write_com(Page_Add+0);
- write_com(Start_Line+0);
- write_com(LCDCol_Add+0);
- write_com(LCDLCDDisp_On);
- }
- void write_data(unsigned char LCDDispdata)
- {
- CheckState();//检测LCD是否忙
- LCDDi=1;
- LCDRW=0;
- P1=LCDDispdata;
- LCDdelay(2);
- LCDEnable=1;
- LCDdelay(2);
- LCDEnable=0;
- }
- //清屏函数
- void Clr_Scr()
- {
- unsigned char j,k;
- LCDMcs=0; //左、右屏均开显示
- LCDScs=0;
- write_com(Page_Add+0);
- write_com(LCDCol_Add+0);
- for(k=0;k<8;k++)
- {
- write_com(Page_Add+k);
- for(j=0;j<64;j++)
- {
- write_com(LCDCol_Add+j);
- write_data(0x00);
- }
- }
- }
- //显示函数
- void Display(unsigned char page,unsigned char column,unsigned char code *Bmp,unsigned char j,unsigned char i,
- unsigned char jm,unsigned char im,unsigned char dw)
- {
- unsigned char j1,i1;
- for(j1=j;j1<jm;j1++)
- {
- write_com(Page_Add+page+j1);
- write_com(LCDCol_Add+column);
- for(i1=i;i1<im;i1++)
- write_data(Bmp[dw*j1+i1]);
- }
- }
- /*******************局部擦除*************************/
- void ClearL(unsigned char page,unsigned char column)
- {
- unsigned char j=0,i=0;
- for(j=0;j<4;j++)
- {
- write_com(Page_Add+page+j);
- write_com(LCDCol_Add+column);
- for(i=0;i<64;i++)
- write_data(0x00);
- }
- }
- void Clear_Crash(unsigned char page,unsigned char column)
- {
- unsigned char j=0,i=0;
- for(j=0;j<2;j++)
- {
- write_com(Page_Add+page+j);
- write_com(LCDCol_Add+column);
- for(i=0;i<16;i++)
- write_data(0x00);
- }
- }
- /***********************************/
- //碰撞函数
- void Crash()
- {
- char i;
- LCDMcs=1; //右屏开显示
- LCDScs=0;
- for(i=48;i>=0;i=i-16)
- {
- Display(6,i,Ph1,0,0,2,16,16); //Bmp_Right_Disp(6,i,Ph1);
- LCDdelay(360000);
- Clear_Crash(6,i);
- if(i<=16)
- {
- EA=1; //总中断允许
- EX0=1;//外部中断0允许
- IT1=1;//外部中断0为下降沿触发
- }
- }
- }
- //成功躲闪函数
- void Miss()
- {
- char i,j,k;
- LCDMcs=0; //左屏开显示
- LCDScs=1;
- for(i=3,j=48,k=0;i>=0,j>=0;k++,j=j-16)
- {
- Display(i,0,Ph,0,0,4,64,64);//Bmp_Left_Disp(i,0,Ph);
- Display(6,j,Ph1,0,0,2,16,16);//Bmp_Right_Disp(6,j,Ph1);
- LCDdelay(360000);
- ClearL(i,0);
- Clear_Crash(6,j);
- if(k<2)
- i--;
- else
- i=i+2;
- }
- }
- //死亡函数
- void Died()
- {
- LCDMcs=0; //左屏开显示
- LCDScs=1;
- Display(0,0,Ph2,0,0,8,64,128);//Died_DispL(0,0,Ph2);
-
- LCDMcs=1; //右屏开显示
- LCDScs=0;
- Display(0,0,Ph2,0,64,8,128,128);//Died_DispR(0,0,Ph2);
- LCDdelay(100000000);
- }
- //总体过程函数
- void Whole()
- {
- LCDMcs=0; //左屏开显示
- LCDScs=1;
- Display(4,0,Ph,0,0,4,64,64);
-
- LCDMcs=1; //右屏开显示
- LCDScs=0;
- Display(6,48,Ph1,0,0,2,16,16);
- flag=0;
- Crash();
- if(flag==1)
- Miss();
- else
- Died();
-
- }
- //按键服务函数
- void PressButton() interrupt 0
- {
- flag=1;
- }
- void main()
- {
- init_lcd();
-
- while(1)
- {
- Clr_Scr();
- Whole();
- }
- }
所有资料51hei提供下载: