標(biāo)題: 51單片機(jī)+12864液晶屏貪吃蛇(完美版) [打印本頁(yè)]

作者: 51hei團(tuán)團(tuán)    時(shí)間: 2018-7-1 03:19
標(biāo)題: 51單片機(jī)+12864液晶屏貪吃蛇(完美版)
我是一個(gè)普通二本學(xué)校電氣的學(xué)生。今年大三。
這個(gè)東西是我大二的時(shí)候做的玩的。

這里面有我做51單片機(jī)+12864液晶的貪吃蛇游戲機(jī)的詳細(xì)資料。仿真實(shí)物我都做過(guò),效果我自己比較滿意。花的精力也比較多,代碼也全都是自己一行一行的寫下來(lái)。所以做完之后想把這些東西都整理一下,然后放在csdn上面,方便后面要做這些東西的人。
open精神在國(guó)內(nèi)是很重要的說(shuō)···0 0、

聯(lián)系方式 : 湖北工業(yè)大學(xué) 08電氣2班

環(huán)境: keil V4.02    protues version 7.5

我先說(shuō)下我這個(gè)東西最主要的幾塊。

1.單片機(jī)用的是stc的,51內(nèi)核,你首先要會(huì)這個(gè)···

2.用狀態(tài)機(jī)實(shí)現(xiàn)按鍵。這個(gè)里面有別人寫的技術(shù)帖子··

3.液晶是12864,2種控制器都做過(guò),一個(gè)控制器是ST7920帶字庫(kù)的,一個(gè)控制器是KS0108不帶字庫(kù)的。2個(gè)的英文資料我都放在里面了。首先得弄懂液晶要怎么樣和單片機(jī)連接。
要在液晶上面做游戲,推薦先看英文資料,一定要看英文,研究液晶讀寫時(shí)序和初始化方法,然后找別人的程序,實(shí)現(xiàn)液晶的基本操作,畫點(diǎn),寫漢字什么的,讀液晶···然后自己寫程序?qū)崿F(xiàn)液晶的所有基本操作。這樣才能對(duì)液晶有充分的認(rèn)識(shí),才能開(kāi)始在上面做游戲。有了這個(gè)基礎(chǔ),以后學(xué)別的液晶也會(huì)快的多。

4.菜單,游戲少不了要用到菜單,比如選擇難度,選擇地圖什么的。我里面放了一個(gè)別人的論文,看了之后應(yīng)該就會(huì)自己寫了。(注意論文里面講的是用函數(shù)指針實(shí)現(xiàn)菜單,但是KEIL這個(gè)環(huán)境下用51函數(shù)指針會(huì)很困難,推薦像我那樣直接傳菜單號(hào))

5.貪吃蛇游戲,推薦先不要看別人的程序,自己在電腦上面下個(gè)貪吃蛇游戲,玩的時(shí)候就觀察貪吃蛇游戲的特征···比如蛇在怎么動(dòng),蛇要怎么描述,是每個(gè)點(diǎn)都描述還是只要蛇頭蛇尾···蛇轉(zhuǎn)彎的時(shí)候怎么寫?  對(duì)于上面的問(wèn)題,可以參考別人的程序,然后就開(kāi)始動(dòng)手畫圖什么的表示出來(lái)這些過(guò)程,一個(gè)功能一個(gè)功能逐一實(shí)現(xiàn)。(推薦看帶字庫(kù)的那個(gè)程序,那個(gè)程序代碼是最終優(yōu)化版本。思路很清晰···)

6.液晶的動(dòng)畫,動(dòng)畫實(shí)際上就是圖片一張一張的顯示,我在里面放了一個(gè)把彩色照片黑白二值化的工具,可以找到自己喜歡的GIF動(dòng)畫,用提取工具把照片一張一張?zhí)崛〕鰜?lái),然后黑白二值化,然后取模工具取模,然后實(shí)現(xiàn)···雖然過(guò)程蠻枯燥,但是效果還不過(guò),也可以學(xué)到不少東西。

最后希望大家在看這個(gè)的時(shí)候,特別是貪吃蛇游戲?qū)崿F(xiàn)的時(shí)候,哪一個(gè)方面有更好的辦法一定通知我,因?yàn)槲矣X(jué)得我實(shí)現(xiàn)貪吃蛇游戲的方法已經(jīng)很不錯(cuò)了。如果能有更好的,我會(huì)非常希望學(xué)習(xí)下····

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機(jī)源程序如下:
  1. #include <12864.h>
  2. #include <tcs_resource.h>
  3. #define num 15

  4. //用來(lái)描述蛇在液晶上面一個(gè)點(diǎn)的結(jié)構(gòu)體
  5. struct she
  6. {
  7.         unsigned char x,y,value;
  8.         unsigned char direction;       
  9. };

  10. struct loop_queue  //利用循環(huán)數(shù)組實(shí)現(xiàn)循環(huán)隊(duì)列,拐點(diǎn)不會(huì)超過(guò)15個(gè)。所以大小選15足以。
  11. {   
  12.         unsigned int front;
  13.         unsigned int rear;
  14.         unsigned int count;
  15.         struct she dat[num];
  16. };
  17. //不熟悉數(shù)組實(shí)現(xiàn)循環(huán)隊(duì)列的可以在紙上畫一下操作過(guò)程

  18. struct she tou,wei,food; //蛇的頭尾節(jié)點(diǎn)  和食物點(diǎn)
  19. struct loop_queue queue;//循環(huán)隊(duì)列  蛇轉(zhuǎn)彎則形成拐點(diǎn) 將拐點(diǎn)入隊(duì)列  尾巴到達(dá)拐點(diǎn)則拐點(diǎn)出隊(duì)列

  20. unsigned char flag_exit_game; //返回標(biāo)志  為1時(shí)  從貪吃蛇游戲返回菜單
  21. unsigned char flag_game_over; //結(jié)束標(biāo)志  為1時(shí)  顯示游戲結(jié)束畫面 同時(shí)使返回標(biāo)志為1
  22. unsigned char tcs_stop;//暫停標(biāo)志
  23. unsigned char tcs_nd; //難度標(biāo)志
  24. unsigned char tcs_dt; //地圖標(biāo)志
  25. unsigned char tcs_key_flag;  //貪吃蛇在一次移動(dòng)中   只允許捕獲一次按鍵  也就是只能產(chǎn)生一個(gè)拐點(diǎn)
  26. unsigned char tcs_key_state; //用于按鍵狀態(tài)機(jī)的實(shí)現(xiàn)

  27. unsigned int  tcs_df;//得分
  28. unsigned int  tcs_highest_df;//最高得分···沒(méi)有使用這個(gè)  因?yàn)椴恢酪趺丛谶\(yùn)行時(shí)寫單片機(jī)的ROM

  29.           
  30. void tcs_game();
  31. void tcs_bianjie(unsigned int );  //貪吃蛇邊界  
  32. void tcs_game_initial();         //游戲初始化

  33. void timer0_initial();          //定時(shí)器0初始化
  34. void timer1_initial();          
  35. void food_produce();          //產(chǎn)生食物

  36. unsigned char test_point_exist(unsigned char x, unsigned char y, unsigned char value);

  37. void queue_initial(struct loop_queue *q);  
  38. void queue_in(struct loop_queue *q,struct she h)  ;
  39. struct she queue_out(struct loop_queue *q)  ;

  40. void wei_you();
  41. void wei_xia();
  42. void wei_zuo();
  43. void wei_shang();
  44. void tcs_game()
  45. {
  46.         struct she check;  //用與暫存蛇即將移動(dòng)的點(diǎn)  從而進(jìn)行判斷
  47.         unsigned char he;
  48.         unsigned char hui,i;

  49.         flag_exit_game=0;
  50.         flag_game_over=0;
  51.         tcs_key_state=0;
  52.         tcs_df=0;
  53.         tcs_stop=1;

  54.         draw_lcd_picture(&tcs_picture[0]); //貪吃蛇游戲畫面
  55.         delay_ms(2000);
  56.         clear_lcd();//清屏12864
  57.         tcs_bianjie(tcs_dt); //貪吃蛇游戲邊界
  58.         tcs_game_initial();//貪吃蛇初始化  主要是設(shè)定蛇頭蛇尾  并顯示蛇
  59.         timer0_initial(); //定時(shí)器0工作在方式2  8位自動(dòng)裝初值  只計(jì)數(shù)不中斷 用來(lái)產(chǎn)生隨機(jī)數(shù)
  60.         timer1_initial(); //定時(shí)器1工作在方式1        16位     10ms中斷一次掃描鍵盤

  61.         do
  62.         {
  63.                 food_produce();//產(chǎn)生一個(gè)隨機(jī)數(shù) 即隨即產(chǎn)生x y value3個(gè)值確定一個(gè)點(diǎn)為食物
  64.                 he=test_point_exist(food.x,food.y,food.value);//檢測(cè)產(chǎn)生的點(diǎn)的地方是否已經(jīng)有點(diǎn)存在
  65.         }
  66.         while(he==food.value);//如果隨機(jī)數(shù)產(chǎn)生在蛇的身體以及邊界上 則重新再產(chǎn)生一個(gè)  
  67.         draw_lcd_point(food.x,food.y,food.value);//顯示食物 先讀取這個(gè)點(diǎn)所在8位的情況 以免破壞現(xiàn)場(chǎng)
  68.        
  69.         queue_initial(&queue);//初始化循環(huán)隊(duì)列  使隊(duì)列空  front rear 即頭尾指針為0
  70.         check.x=0;
  71.         check.y=0;
  72.         check.value=0;
  73.         check.direction=0;
  74.         for(i=0;i<num;i++)
  75.                 queue.dat[i]=check;

  76.         while(1)
  77.         {
  78.                 if(flag_exit_game==1)//如果游戲過(guò)程中按下返回鍵  則立即結(jié)束游戲  返回菜單
  79.                         break;
  80.                 if(flag_game_over==1)
  81.                         break;
  82.                
  83.                 ET1=1;   //允許掃描按鍵          貪吃蛇游戲難度決定蛇2次移動(dòng)之間的間隔時(shí)間  也就是檢測(cè)按鍵的時(shí)間
  84.                 tcs_key_flag=0; //允許捕獲按鍵  在檢測(cè)按鍵時(shí)間內(nèi)  只允許生產(chǎn)一個(gè)拐點(diǎn)  即捕獲到一個(gè)有效的
  85.                                                 //按鍵以后  就置一這個(gè)變量 不允許再增加拐點(diǎn)
  86.                 while(tcs_stop==0);
  87.                 switch(tcs_nd)
  88.                 {
  89.                         case 0:  {delay_ms(10); break;}
  90.                         case 1:  {delay_ms(50); break;}
  91.                         case 2:  {delay_ms(100); break;}
  92.                 }
  93.                 ET1=0;

  94.                 switch(tou.direction)//這個(gè)switch用來(lái)根據(jù)蛇頭的x y value值以及當(dāng)前蛇頭移動(dòng)的方向
  95.                                                          //取出蛇頭要到達(dá)的下一個(gè)點(diǎn)  存入check中  來(lái)判斷是否撞墻 吃到食物 什么的···
  96.                 {       
  97.                         case 0: {        
  98.                                                 check.x=tou.x;
  99.                                                 if(tou.y==63)  
  100.                                                         check.y=0;
  101.                                                 else
  102.                                                         check.y=tou.y+1;
  103.                                                 check.value=tou.value;
  104.                                                  break ;
  105.                                         }//->向右y+1 其他不變

  106.                         case 1: {                                          //↓ 向下y不變
  107.                                                 check.y=tou.y;
  108.                                                  if(tou.value==0x80)// value==0x80 則 x+1 value=0x01
  109.                                                 {
  110.                                                         if(tou.x==7)
  111.                                                                 check.x=0;
  112.                                                         else
  113.                                                                 check.x=tou.x+1;
  114.                                                         check.value=0x01;
  115.                                                 }
  116.                                                 else
  117.                                                 {
  118.                                                         check.x=tou.x;
  119.                                                         check.value=tou.value<<1;
  120.                                                 }
  121.                                             break ;
  122.                                         }

  123.                         case 2: {        
  124.                                                 check.x=tou.x;
  125.                                                 if(tou.y==0)  
  126.                                                         check.y=63;
  127.                                                 else
  128.                                                         check.y=tou.y-1;
  129.                                                 check.value=tou.value;
  130.                                                 break ;
  131.                                         }//<-向左y-1 其他不變

  132.                         case 3: {                                            //↑         向上y不變
  133.                                                 check.y=tou.y;
  134.                                                  if(tou.value==0x01)// value==0x01 則 x-1 value=0x80
  135.                                                 {
  136.                                                         if(tou.x==0)
  137.                                                                 check.x=7;
  138.                                                         else
  139.                                                                 check.x=tou.x-1;
  140.                                                         check.value=0x80;
  141.                                                 }
  142.                                                 else
  143.                                                 {
  144.                                                         check.x=tou.x;
  145.                                                         check.value=tou.value>>1;
  146.                                                 }
  147.                                             break ;
  148.                                         }       
  149.                 }                       
  150.                        
  151.                 he=test_point_exist(check.x,check.y,check.value); // 檢測(cè)蛇頭移動(dòng)的下一個(gè)點(diǎn)是否幾經(jīng)有點(diǎn)存在
  152.                 if(he==check.value) //如果前面的點(diǎn)已經(jīng)存在        則可以是食物 或者是墻和蛇身
  153.                 {
  154.                         if(        (check.x==food.x) && (check.y==food.y) && (check.value==food.value) )//吃到食物
  155.                         {
  156.                                 tcs_df++;
  157.                                 cs1=1; cs2=0;
  158.                                 write_lcd_shuzi(2,32,tcs_shuzi[tcs_df/100]       );                         //顯示分?jǐn)?shù)的百位
  159.                                 write_lcd_shuzi(2,40,tcs_shuzi[ (tcs_df%100)/10] );                                //                        十
  160.                                 write_lcd_shuzi(2,48,tcs_shuzi[tcs_df%10]        );                                //          個(gè)
  161.                                 cs1=0; cs2=1;
  162.                                 food.direction=tou.direction;//食物本沒(méi)有方向 但是為了下面的語(yǔ)句
  163.                                 tou=food; //食物就成了蛇頭···蛇頭的方向依然不變
  164.                                 hui=wei.direction; //先記錄下尾巴本來(lái)的移動(dòng)方向  
  165.                                 wei.direction=611;//這次行動(dòng)尾巴不動(dòng)  這樣蛇身就自然加一了···611代表下面的尾巴不動(dòng)
  166.                                 do
  167.                                 {
  168.                                         food_produce();
  169.                                         he=test_point_exist(food.x,food.y,food.value);
  170.                                 }
  171.                                 while(he==food.value);  
  172.                                 draw_lcd_point(food.x,food.y,food.value);//上面有說(shuō)過(guò)  這個(gè)是產(chǎn)生并顯示食物
  173.                         }
  174.                         else//撞到身體或者墻
  175.                         {
  176.                                 flag_game_over=1; // 游戲結(jié)束
  177.                         }
  178.                 }
  179.                 else  //什么都么有遇到 繼續(xù)前進(jìn)
  180.                 {
  181.                         check.direction=tou.direction;//這么做的理由同上 為了保持蛇頭當(dāng)前的移動(dòng)方向
  182.                         tou=check;
  183.                         draw_lcd_point(tou.x,tou.y,tou.value);//畫出此時(shí)的蛇頭
  184.                 }

  185.                 //下面是對(duì)尾巴的操作               
  186.                
  187.                 if (  (wei.x == queue.dat[queue.front].x) && ( wei.y==queue.dat[queue.front].y ) && ( wei.value== queue.dat[queue.front].value)  ) //如果尾巴到達(dá)拐點(diǎn)
  188.                 {
  189.                          check=queue_out(&queue);        
  190.                         wei.direction=check.direction; //尾巴按照拐點(diǎn)指示的方向走
  191.                 }
  192.                 else //如果沒(méi)有到達(dá)拐點(diǎn) 尾巴移動(dòng)的方向不變
  193.                 {
  194.                                
  195.                 }                                               
  196.                                                                
  197.                 switch( wei.direction ) //這個(gè)是尾巴的移動(dòng)  以及尾巴節(jié)點(diǎn)數(shù)據(jù)的修改
  198.                 {
  199.                         case 0:        { wei_you(); break; }
  200.                         case 1:        { wei_xia(); break; }                                                                               
  201.                         case 2:        { wei_zuo(); break; }
  202.                         case 3:        { wei_shang();         break; }       
  203.                         case 611: { wei.direction=hui;  break;}  //這次移動(dòng) 吃到實(shí)物   還原尾巴本來(lái)的移動(dòng)方向
  204.                   }                                               
  205.         }       
  206.         TR0=0;
  207.         TR1=0;
  208.         ET1=0;  //退出游戲時(shí) 關(guān)閉游戲過(guò)程中用到的定時(shí)器0和1  然后定時(shí)器中斷也要關(guān)閉


  209. }


  210. void timer0_initial()
  211. {        
  212.         TMOD=(0xf0 & TMOD) | 0x01; //定時(shí)器0 8位自動(dòng)裝初值(TH0->TL0)定時(shí)器模式   用來(lái)產(chǎn)生隨機(jī)數(shù)
  213.         TH0=0x00;
  214.         TL0=0x00;
  215.         TR0=1;   
  216. }

  217. void timer1_initial()
  218. {        
  219.         EA=1;
  220.         TMOD= (0x0f & TMOD) | 0x10 ; //定時(shí)器一16位定時(shí)器模式         10ms中斷一次  用來(lái)掃描鍵盤
  221.         TH1=0xDC;//10ms中斷一次
  222.         TL1=0x00;
  223.         TR1=1;   
  224. }


  225. void timer1() interrupt 3
  226. {       
  227.         unsigned char tou_last_direction; //記錄蛇頭原來(lái)的移動(dòng)方向
  228.        
  229.         TR1=0;
  230.         TH1=0xDC;               
  231.         TL1=0x00;

  232.         switch (tcs_key_state)
  233.         {
  234.                 case 0:        {                // 按鍵初始態(tài)
  235.                                         if ( (P2 & 0x7f) != 0x7f )   tcs_key_state = 1;        // 鍵被按下,狀態(tài)轉(zhuǎn)換到鍵確認(rèn)態(tài)
  236.                                                 else          tcs_key_state = 0;
  237.                                         break;
  238.                                 }
  239.        
  240.                 case 1:        {                        // 按鍵確認(rèn)態(tài)
  241.                                         if ( (P2 & 0x7f) != 0x7f)
  242.                                         {
  243.                                                 // 按鍵仍按下,此時(shí)確定記錄一次有效按鍵
  244.                                                         tcs_key_state = 2;        // 狀態(tài)轉(zhuǎn)換到鍵釋放態(tài)
  245.                                                         if(tcs_key_flag==0)
  246.                                                         {
  247.                                                                 tou_last_direction=tou.direction;
  248.                                                                 switch(P2 & 0x7f)
  249.                                                                 {       
  250.                                                                         case 0x6f:        break; // 確定鍵  不進(jìn)行任何操作
  251.                                                                         case 0x5f:        {  flag_exit_game=1;   break; }//返回鍵           結(jié)束游戲 返回菜單
  252.                                                                         case 0x7e:        {  tou.direction=3;break; }//↑
  253.                                                                         case 0x7b:        {  tou.direction=2;break; }//←
  254.                                                                         case 0x7d:        {  tou.direction=1;break; }//↓
  255.                                                                         case 0x77:        {  tou.direction=0;break; }//->         
  256.                                                                         case 0x3f:  {  if(tcs_stop==0) tcs_stop=1; else tcs_stop=0; break;}//暫停鍵
  257.                                                                 }
  258.                                                
  259.                                                                 if( (tou.direction==tou_last_direction) || (tou.direction+tou_last_direction==2) || (tou.direction+tou_last_direction==4) )
  260.                                                                 //如果本來(lái)就是按此方向移動(dòng)   或者按鍵給的方向與蛇移動(dòng)方向相反 則不做任何操作 此次按鍵無(wú)效
  261.                                                                 {
  262.                                                                         tou.direction=tou_last_direction; //   還原蛇頭的移動(dòng)方向
  263.                                                                 }
  264.                                                                 else //否則記錄此頭結(jié)點(diǎn)成為拐點(diǎn)           
  265.                                                                 {                       
  266.                                                                         queue_in(&queue,tou);
  267.                                                                         tcs_key_flag=1; //已經(jīng)捕獲到一次按鍵信息 這次移動(dòng)拐點(diǎn)已經(jīng)產(chǎn)生 關(guān)閉捕獲鍵盤
  268.                                                                 }
  269.                                                         }
  270.                                         }
  271.                                         else
  272.                                         {
  273.                                                 tcs_key_state = 0;        // 按鍵已抬起,轉(zhuǎn)換到按鍵初始態(tài)
  274.                                                 break;
  275.                                         }
  276.                                 }

  277.                 case 2:        {           //等待按鍵彈起狀態(tài)
  278.                                                 if ( (P2 & 0x7f) == 0x7f) tcs_key_state=0;        //按鍵已釋放,轉(zhuǎn)換到按鍵初始態(tài)
  279.                                                 else          tcs_key_state = 2;
  280.                                                 break;
  281.                                 }       
  282.         }                        
  283.         TR1=1;
  284. }


  285. void food_produce()
  286. {
  287.                  unsigned char j1,j2;
  288.                 unsigned char code a[]={0x01,0x02,0x04,0x08, 0x10,0x20,0x40,0x80,0x01,0x02,0x04,0x08, 0x10,0x20,0x40,0x80};
  289.                 unsigned char code b[]={0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7};
  290.                    
  291.                 j1 = TL0 & 0x0f;  //取TL0的低四位
  292.                 food.value = a[j1];  //用0-15的數(shù)確定食物的value值
  293.                
  294.                 j2 = (TL0 & 0xf0)>>4; //取TL0的高4位
  295.                 food.x=b[j2];                        //同理確定食物的x值                                       
  296.                
  297.                 j2=j1+j2; // 0-30            
  298.                
  299.                 food.y=j2 +( TL0 & 0x0f ) + ( (TL0 & 0xf0)>>4 ) + 1;//3次0-15的值和一次1-16的值相加,產(chǎn)生1-61的數(shù)       

  300. }

  301. unsigned char test_point_exist(unsigned char x, unsigned char y, unsigned char value)
  302. {
  303.         unsigned char he;
  304.         set_lcd_xy(x,y);
  305.         he=read_lcd_dat();
  306.         he=read_lcd_dat();
  307.         he=he&value; //如果液晶上這個(gè)點(diǎn)是亮的 則he為value 若不亮則為 0
  308.         return (he);
  309. }

  310. void tcs_game_initial()
  311. {
  312.         unsigned char i;
  313.         cs1=0;        cs2=1;
  314.         tou.x=0;
  315.         tou.y=5;
  316.         tou.value=0x08;      //初始化蛇頭
  317.         tou.direction=0;    // 初始化蛇頭移動(dòng)方向?yàn)橄蛴?

  318.         wei.x=0;
  319.         wei.y=1;
  320.         wei.value=0x08;                //初始化蛇尾
  321.         wei.direction=0;
  322.        
  323.         for(i=wei.y;i<=tou.y;i++)
  324.                 draw_lcd_point(tou.x,i,tou.value);//形成蛇
  325. }




  326. void tcs_bianjie(unsigned int he)
  327. {
  328.         unsigned char i;
  329.         cs1=0;        cs2=1;
  330.         set_lcd_xy(0,0);
  331.         for(i=0;i<=63;i++)
  332.                 write_lcd_dat(0x01);

  333.         set_lcd_xy(7,0);
  334.         for(i=0;i<=63;i++)
  335.                 write_lcd_dat(0x80);
  336.        
  337.         for(i=0;i<=7;i++)
  338.         {
  339.                 set_lcd_xy(i,0);
  340.                 write_lcd_dat(0xff);

  341.                 set_lcd_xy(i,63);
  342.                 write_lcd_dat(0xff);
  343.         }

  344.         if(he==2)
  345.         {
  346.                
  347.                 unsigned char i,j;
  348.                 for(i=0;i<8;i++)
  349.                 {         
  350.                         cs1=0;cs2=1;
  351.                         set_lcd_xy(i,0);
  352.                         for(j=0;j<64;j++)
  353.                                 write_lcd_dat(tcs_dt2[i*64+j]);
  354.                 }               
  355.         }
  356.        
  357.         if(he==3)
  358.         {
  359.                 unsigned char i,j;
  360.                 for(i=0;i<8;i++)
  361.                 {         
  362.                         cs1=0;cs2=1;
  363.                         set_lcd_xy(i,0);
  364.                         for(j=0;j<64;j++)
  365.                                 write_lcd_dat(tcs_dt3[i*64+j]);
  366.                 }
  367.         }       

  368.         if(he==4)
  369.         {
  370.                 unsigned char i,j;
  371.                 for(i=0;i<8;i++)
  372.                 {         
  373.                         cs1=0;cs2=1;
  374.                         set_lcd_xy(i,0);
  375.                         for(j=0;j<64;j++)
  376.                                 write_lcd_dat(tcs_dt4[i*64+j]);
  377.                 }
  378.         }       


  379.         cs1=1;        cs2=0;
  380.         write_lcd_hanzi(0,0,df[0]);
  381.         write_lcd_hanzi(0,16,df[1]);

  382.         write_lcd_shuzi(2,32,tcs_shuzi[tcs_df/100]       );                         //顯示分?jǐn)?shù)的百位
  383.         write_lcd_shuzi(2,40,tcs_shuzi[ (tcs_df%100)/10] );                                //                        十
  384.         write_lcd_shuzi(2,48,tcs_shuzi[tcs_df%10]        );                                //          個(gè)

  385.         write_lcd_hanzi(4,0,jb[0]);
  386.         write_lcd_hanzi(4,16,jb[1]);

  387.         switch(tcs_nd)
  388.         {
  389.                 case 0 :  { write_lcd_hanzi(6,32,tcs_bt[0]); write_lcd_hanzi(6,48,tcs_bt[1]);  break;}
  390.                 case 1 :  { write_lcd_hanzi(6,32,tcs_kn[0]); write_lcd_hanzi(6,48,tcs_kn[1]);  break;}
  391.                 case 2 :  { write_lcd_hanzi(6,32,tcs_jd[0]); write_lcd_hanzi(6,48,tcs_jd[1]);  break;}
  392.         }
  393. }

  394. void queue_initial(struct loop_queue *q)   
  395. {   
  396.     q->front =q->rear=0;   
  397.     q->count = 0;   
  398. }   

  399. void queue_in(struct loop_queue *q,struct she h)  
  400. {   
  401.         q->dat[q->rear] = h;   
  402.         q->rear = (q->rear + 1) % num;   
  403.         q->count = q->count + 1;   
  404. }   
  405.   
  406. struct she queue_out(struct loop_queue *q)   
  407. {   
  408.         struct she he;
  409.                 he = q->dat[q->front];   
  410.         q->front = (q->front + 1) % num;   
  411.         q->count = q->count - 1;
  412.                 return (he);   
  413. }  



  414. void wei_you()
  415. {
  416.         unsigned char he;

  417.         set_lcd_xy(wei.x,wei.y);
  418.         he=read_lcd_dat();
  419.         he=read_lcd_dat();
  420.    
  421.         set_lcd_xy(wei.x,wei.y);
  422.         write_lcd_dat(he-wei.value);  //取當(dāng)前位置的值,去掉尾巴這個(gè)點(diǎn),然后顯示
  423.         if(wei.y==63)
  424.                 wei.y=0;
  425.         else
  426.                 wei.y++;
  427. }

  428. void wei_zuo()
  429. {
  430.         unsigned char he;

  431.         set_lcd_xy(wei.x,wei.y);
  432.         he=read_lcd_dat();
  433.         he=read_lcd_dat();
  434.    
  435.         set_lcd_xy(wei.x,wei.y);
  436.         write_lcd_dat(he-wei.value); //取當(dāng)前位置的值,去掉尾巴這個(gè)點(diǎn),然后顯示
  437.         if(wei.y==0)
  438.                 wei.y=63;
  439.         else
  440.                 wei.y--;
  441. }

  442. void wei_shang()
  443. {
  444. ……………………

  445. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

所有資料51hei提供下載:

51單片機(jī) 12864液晶貪吃蛇游戲機(jī)(完美版).rar (7.79 MB, 下載次數(shù): 1231)





作者: lin123456789    時(shí)間: 2018-11-25 00:25
優(yōu)秀大學(xué)生 失敬失敬,用Proteus7.5打開(kāi)dsn文件即可仿真,不過(guò)大家記得要重新選擇hex文件

51hei.png (13.42 KB, 下載次數(shù): 147)

51hei.png

51hei.png (13.51 KB, 下載次數(shù): 141)

51hei.png

作者: 鈴戀仙    時(shí)間: 2018-11-25 22:16
不愧是大神
作者: 鈴戀仙    時(shí)間: 2018-11-25 22:17
有的研究了
作者: tbqpdfhk    時(shí)間: 2018-11-26 22:31
優(yōu)秀項(xiàng)目
作者: samdcn    時(shí)間: 2018-11-27 16:53
真不錯(cuò),向你學(xué)習(xí)
作者: 悠悠吾心    時(shí)間: 2018-11-27 17:20
這才是大神啊
作者: motorn    時(shí)間: 2018-12-6 17:31
怎么才能聯(lián)系到你,需要的幫助,可以的話加一下我的qq給你留言了,謝謝
作者: Semiton    時(shí)間: 2018-12-7 01:17
厲害了 研究一下
作者: 天涯明月刀    時(shí)間: 2018-12-10 16:20
如果改成20引腳的那個(gè)怎么改呢?
作者: 我叫電烙鐵    時(shí)間: 2018-12-10 17:17
很不錯(cuò)  值得學(xué)習(xí)

作者: kampoer    時(shí)間: 2019-3-16 20:14
感謝分享
作者: ekomicka    時(shí)間: 2019-4-25 22:28
你好大神,我剛接觸proteus,文件里的仿真文件里我能用proteus打開(kāi)的只有DSN格式的文件,想問(wèn)一下如何仿真
作者: 19980403hN    時(shí)間: 2019-4-28 09:12
優(yōu)秀,學(xué)習(xí)了
作者: pangjineng    時(shí)間: 2019-5-3 10:10
優(yōu)秀大學(xué)生,厲害。
作者: YHY232    時(shí)間: 2019-5-5 08:29
膜拜大神,確實(shí)厲害啊
作者: xiayupeng    時(shí)間: 2019-5-7 06:53
大神厲害 頂呱呱
作者: 陳必成    時(shí)間: 2019-5-7 20:10
優(yōu)秀大學(xué)生學(xué)習(xí)了  
作者: wzxn    時(shí)間: 2019-5-10 14:33
下載后到proteus里仿真了一下,真心不錯(cuò)!值得初學(xué)者學(xué)習(xí)!
作者: yuanweilong789    時(shí)間: 2019-5-10 15:20
學(xué)習(xí)一下。看做的很不錯(cuò)的
作者: mochun    時(shí)間: 2019-5-22 10:57
太厲害了。!學(xué)習(xí)了,關(guān)鍵是無(wú)私分享的的精神很贊
作者: odiwuano    時(shí)間: 2019-5-22 11:41
我也來(lái)看看
作者: 尼古拉斯凱奇    時(shí)間: 2019-5-23 15:13
厲害,學(xué)習(xí)學(xué)習(xí)學(xué)習(xí)
作者: YXun    時(shí)間: 2019-7-3 16:22
  有的研究了, 感謝大佬
作者: szzxl10    時(shí)間: 2019-7-9 17:08
優(yōu)秀大學(xué)生,厲害
作者: 黑科技cc.    時(shí)間: 2019-7-19 08:57
我得好好研究研究正好要參加比賽
作者: 綠洲    時(shí)間: 2019-7-23 19:04
你好,請(qǐng)問(wèn)樓主
51單片機(jī)+12864液晶屏貪吃蛇(完美版)
用的是什么芯片
作者: L1BB    時(shí)間: 2019-9-18 16:08
niubi,太厲害餓了
作者: bryan_guan    時(shí)間: 2019-10-10 15:34
想你學(xué)習(xí)學(xué)習(xí)
作者: babyvoxsky    時(shí)間: 2019-10-10 22:45
感謝大神,下載學(xué)習(xí)一下!
作者: No.23    時(shí)間: 2019-10-13 21:32
優(yōu)秀的大學(xué)生學(xué)習(xí)了
作者: 李克農(nóng)    時(shí)間: 2019-10-21 15:57

優(yōu)秀,學(xué)習(xí)了
作者: p4466001    時(shí)間: 2019-11-28 14:54
優(yōu)秀,學(xué)習(xí)了
作者: 大白菜啊    時(shí)間: 2020-3-28 21:26
兄弟,太優(yōu)秀了!!
作者: jidan0015    時(shí)間: 2020-5-1 10:58
感謝分享
作者: xingyusky111    時(shí)間: 2020-5-10 11:13
厲害,學(xué)習(xí)了
作者: xiahouyide    時(shí)間: 2020-5-10 20:20
優(yōu)秀的學(xué)習(xí)資料
作者: 千與千尋9527    時(shí)間: 2020-5-12 15:50
絕對(duì)的高手,示波器是不是也可以這么做
作者: 51學(xué)習(xí)中    時(shí)間: 2020-5-16 16:36
仿真很完美,只是有字庫(kù)的接線還是不會(huì)
作者: GCmumu    時(shí)間: 2020-7-17 01:13
謝謝樓主!正好需要學(xué)習(xí)LCD的使用和貪吃蛇的編程!
作者: hanshanyike    時(shí)間: 2020-10-10 09:08
程序結(jié)構(gòu)體里面的value是干什么的呀,博主
作者: Lanmrt    時(shí)間: 2021-5-6 17:58
有沒(méi)有人遇到lcd沒(méi)有任何字出現(xiàn)的問(wèn)題?
作者: 熊朱偉    時(shí)間: 2022-1-11 10:03
寫的很好非常棒
作者: 熊朱偉    時(shí)間: 2022-1-11 15:53
如果用點(diǎn)陣會(huì)不會(huì)復(fù)雜一點(diǎn)

作者: 阿芝莎    時(shí)間: 2023-1-16 20:39
大神感謝,卑微大一新生在線感謝
作者: Lchangjaing    時(shí)間: 2023-1-30 22:56
膜拜大神
作者: hjh800512    時(shí)間: 2023-2-3 21:55
五六百行的大程序,值得收藏,我先收藏下,慢慢學(xué)習(xí)。
作者: lixiaonin    時(shí)間: 2023-4-13 02:21
先謝謝了,一個(gè)液晶屏編程的好教程!
作者: duanlian    時(shí)間: 2023-4-15 17:24
好好收藏!再慢慢消化!
作者: ronin111    時(shí)間: 2023-6-19 09:11
lin123456789 發(fā)表于 2018-11-25 00:25
優(yōu)秀大學(xué)生 失敬失敬,用Proteus7.5打開(kāi)dsn文件即可仿真,不過(guò)大家記得要重新選擇hex文件

太厲害了




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1