登录|立即注册|使用QQ帐号登录
论坛 > 51单片机
发帖|
看4088|回5|收藏
楼主 ID:658359 只看他
2019-12-26 10:50
        lcd12864作为显示屏,实现一个按钮控制的简单小游戏。主要工作集中于游戏的图形化以及相关逻辑的实现。人物场景设计通过字模提取软件转换成为段码预先储存在单片机中,动画的实现采取局部刷新的方式以提高显示的速度。

仿真原理图如下(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)
(下载次数: 80, 2019-12-26 10:49 上传)

下载积分: 黑币 -5



沙发 ID:102963 只看他
2020-2-14 22:03
楼主,
这个马小白小人图像怎么做的呢?
板凳 ID:658359 只看他
2020-2-20 10:54

引用:

songxia8013 发表于 2020-2-14 22:03
楼主,
这个马小白小人图像怎么做的呢?

自己先绘图,然后用字模软件提取成数据矩阵
地板 ID:709456 只看他
2020-3-19 08:30
LCD1602可以吗?换1602程序是不是也得改?
5# ID:740717 只看他
2020-5-11 15:31
压缩包打不开了,呜呜
6# ID:749570 只看他
2020-5-12 01:08
嘿嘿非常需要啊

51黑电子论坛

Powered by Discuz! X3.1

首页|标准版|触屏版|电脑版