单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 204|回复: 1
收起左侧

基于LCD12864和51单片机的简单小游戏Proteus仿真程序

[复制链接]
rolf 发表于 2019-12-26 10:50 | 显示全部楼层 |阅读模式
        lcd12864作为显示屏,实现一个按钮控制的简单小游戏。主要工作集中于游戏的图形化以及相关逻辑的实现。485868.com_【官方首页】-澳门金沙人物场景设计通过字模提取软件转换成为段码预先储存在单片机中,动画的实现采取局部刷新的方式以提高显示的速度。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.png


0.jpg

单片机源程序如下:
  1. #include <reg51.h>

  2. #define LCDLCDDisp_Off   0x3e
  3. #define LCDLCDDisp_On    0x3f
  4. #define Page_Add     0xb8//ye

  5. #define LCDCol_Add     0x40//lie
  6. #define Start_Line     0xC0//hang
  7. /*****液晶显示器的端口定义*****/
  8. #define data_ora P1 /*液晶数据总线*/
  9. sbit LCDMcs=P2^4 ;    /*片选1*/
  10. sbit LCDScs=P2^3 ;    /*片选2*/
  11. sbit LCDDi=P2^2 ;     /*数据/指令 选择*/
  12. sbit LCDRW=P2^1 ;     /*读/写 选择*/
  13. sbit LCDEnable=P2^0 ;     /*读/写 使能*/
  14. unsigned char flag;//flag=0,死亡,flag=1,闪避成功
  15. unsigned char code Ph[] =                  
  16. {
  17. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  18. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  19. 0x00,0x00,0x04,0x74,0x44,0x5C,0xC0,0x00,0x00,0x00,0x00,0x00,0xE0,0x10,0x48,0xA4,

  20. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00


  21. };
  22.         
  23. void LCDdelay(unsigned int t)
  24. {
  25.         unsigned int i,j;
  26.         for(i=0;i<t;i++);
  27.         for(j=0;j<10;j++);
  28. }
  29. void CheckState()               
  30. {
  31.    unsigned char dat,DATA;//状态信息(判断是否忙)
  32.    LCDDi=0; // 数据\指令选择,D/I(RS)="L" ,表示 DB7∽DB0 为显示指令数据
  33.    LCDRW=1; //R/W="H" ,E="H"数据被读到DB7∽DB0
  34.    do
  35.    {
  36.       DATA=0x00;
  37.       LCDEnable=1;        //EN下降源
  38.           LCDdelay(2);//延时
  39.           dat=DATA;
  40.       LCDEnable=0;
  41.       dat=0x80 & dat; //仅当第7位为0时才可操作(判别busy信号)
  42.     }
  43.     while(!(dat==0x00));
  44. }
  45. void write_com(unsigned char cmdcode)
  46. {
  47.     CheckState();//检测LCD是否忙
  48.         LCDDi=0;
  49.         LCDRW=0;
  50.         P1=cmdcode;               
  51.         LCDdelay(2);
  52.         LCDEnable=1;
  53.         LCDdelay(2);
  54.         LCDEnable=0;
  55. }
  56. void init_lcd()
  57. {
  58.         LCDdelay(100);        
  59.         LCDMcs=1;//刚开始关闭两屏
  60.         LCDScs=1;
  61.         LCDdelay(100);
  62.         write_com(LCDLCDDisp_Off);         //写初始化命令
  63.         write_com(Page_Add+0);
  64.         write_com(Start_Line+0);
  65.         write_com(LCDCol_Add+0);
  66.         write_com(LCDLCDDisp_On);
  67. }        
  68. void write_data(unsigned char LCDDispdata)
  69. {
  70.     CheckState();//检测LCD是否忙
  71.         LCDDi=1;
  72.         LCDRW=0;
  73.         P1=LCDDispdata;
  74.         LCDdelay(2);
  75.         LCDEnable=1;
  76.         LCDdelay(2);
  77.         LCDEnable=0;
  78. }
  79. //清屏函数
  80. void Clr_Scr()
  81. {
  82.         unsigned char j,k;
  83.         LCDMcs=0; //左、右屏均开显示
  84.         LCDScs=0;
  85.          write_com(Page_Add+0);
  86.          write_com(LCDCol_Add+0);
  87.          for(k=0;k<8;k++)
  88.          {
  89.                 write_com(Page_Add+k);
  90.                   for(j=0;j<64;j++)  
  91.                 {
  92.                       write_com(LCDCol_Add+j);
  93.                         write_data(0x00);
  94.                 }
  95.         }
  96. }        
  97. //显示函数
  98. void Display(unsigned char page,unsigned char column,unsigned char code *Bmp,unsigned char j,unsigned char i,
  99. unsigned char jm,unsigned char im,unsigned char dw)
  100. {
  101.         unsigned char j1,i1;
  102.         for(j1=j;j1<jm;j1++)
  103.         {
  104.                 write_com(Page_Add+page+j1);
  105.                 write_com(LCDCol_Add+column);
  106.                 for(i1=i;i1<im;i1++)
  107.                         write_data(Bmp[dw*j1+i1]);
  108.         }
  109. }
  110. /*******************局部擦除*************************/
  111. void ClearL(unsigned char page,unsigned char column)
  112. {
  113.         unsigned char j=0,i=0;
  114.         for(j=0;j<4;j++)
  115.         {
  116.                 write_com(Page_Add+page+j);
  117.                 write_com(LCDCol_Add+column);
  118.                 for(i=0;i<64;i++)
  119.                         write_data(0x00);
  120.         }
  121. }
  122. void Clear_Crash(unsigned char page,unsigned char column)
  123. {
  124.         unsigned char j=0,i=0;
  125.         for(j=0;j<2;j++)
  126.         {
  127.                 write_com(Page_Add+page+j);
  128.                 write_com(LCDCol_Add+column);
  129.                 for(i=0;i<16;i++)
  130.                         write_data(0x00);
  131.         }
  132. }
  133. /***********************************/


  134. //碰撞函数
  135. void Crash()
  136. {
  137.         char i;
  138.         LCDMcs=1; //右屏开显示
  139.     LCDScs=0;
  140.         for(i=48;i>=0;i=i-16)
  141.         {
  142.                 Display(6,i,Ph1,0,0,2,16,16);         //Bmp_Right_Disp(6,i,Ph1);
  143.                 LCDdelay(360000);
  144.                 Clear_Crash(6,i);
  145.                 if(i<=16)
  146.                 {
  147.                         EA=1; //总中断允许
  148.                         EX0=1;//外部中断0允许
  149.                         IT1=1;//外部中断0为下降沿触发
  150.                 }
  151.         }
  152. }
  153. //成功躲闪函数
  154. void Miss()
  155. {
  156.         char i,j,k;
  157.         LCDMcs=0; //左屏开显示
  158.         LCDScs=1;
  159.         for(i=3,j=48,k=0;i>=0,j>=0;k++,j=j-16)
  160.         {
  161.                 Display(i,0,Ph,0,0,4,64,64);//Bmp_Left_Disp(i,0,Ph);
  162.                 Display(6,j,Ph1,0,0,2,16,16);//Bmp_Right_Disp(6,j,Ph1);
  163.                 LCDdelay(360000);
  164.                 ClearL(i,0);
  165.                 Clear_Crash(6,j);
  166.                 if(k<2)
  167.                         i--;
  168.                 else
  169.                         i=i+2;
  170.         }               
  171. }
  172. //死亡函数
  173. void Died()
  174. {
  175.         LCDMcs=0; //左屏开显示
  176.         LCDScs=1;
  177.     Display(0,0,Ph2,0,0,8,64,128);//Died_DispL(0,0,Ph2);
  178.         
  179.     LCDMcs=1; //右屏开显示
  180.     LCDScs=0;
  181.         Display(0,0,Ph2,0,64,8,128,128);//Died_DispR(0,0,Ph2);

  182.         LCDdelay(100000000);

  183. }
  184. //总体过程函数
  185. void Whole()
  186. {
  187.         LCDMcs=0; //左屏开显示
  188.         LCDScs=1;
  189.     Display(4,0,Ph,0,0,4,64,64);
  190.         
  191.     LCDMcs=1; //右屏开显示
  192.     LCDScs=0;
  193.         Display(6,48,Ph1,0,0,2,16,16);

  194.         flag=0;
  195.         Crash();
  196.         if(flag==1)
  197.                 Miss();
  198.         else
  199.             Died();
  200.         
  201. }
  202. //按键服务函数
  203. void PressButton() interrupt 0
  204. {
  205.         flag=1;
  206. }

  207. void main()
  208. {
  209.         init_lcd();
  210.         

  211.         while(1)
  212.         {
  213.                 Clr_Scr();
  214.                 Whole();
  215.         }

  216. }
复制代码

所有资料51hei提供下载:
基于12864和51的小游戏.rar (69.49 KB, 下载次数: 12)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

songxia8013 发表于 2020-2-14 22:03 | 显示全部楼层
楼主,
这个马小白小人图像怎么做的呢?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|单片机论坛 |51黑电子论坛技术交流 QQ 管理员QQ:125739409;技术交流QQ群636986012

Powered by 单片机教程网

快速回复 返回顶部 返回列表

页面底部区域 foot.htm