<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 51單片機(jī)項目實戰(zhàn)---貪吃蛇(測試版)

          51單片機(jī)項目實戰(zhàn)---貪吃蛇(測試版)

          作者: 時間:2018-08-06 來源:網(wǎng)絡(luò) 收藏

          一、元器件

          1、AT89C51

          本文引用地址:http://www.ex-cimer.com/article/201808/385449.htm

          關(guān)于就不在嗦了,相信大家都已經(jīng)很熟悉了。

          2、8x8點陣

          點陣?yán)锩婢褪且恍┒O管啦,通過縱橫交叉連接,橫8豎8,每個交叉點都接一個二極管。這里給大家找到一個點陣的實物圖


          我想大家看到這個圖就應(yīng)該知道如何去點亮一個點陣了。假如要點亮最左上角那個,那么9號引腳拉高,13號引腳拉低,這樣既可。

          二、原理圖



          三、項目分析

          1、首先定義一個結(jié)構(gòu)體

          struct snake{

          unsigned char x[20];

          unsigned char y[20];

          unsigned char length;

          unsigned char direction;

          }snk;

          數(shù)組x,y分別存放每一個點的橫縱坐標(biāo),length為蛇的長度,direction為蛇前進(jìn)的方向

          2、坐標(biāo)系:點陣的左下角為點(0,0),橫縱坐標(biāo)都是正向增長,P2控制橫坐標(biāo);P0控制縱坐標(biāo)。通過坐標(biāo)可以找到點陣中點的位置,然后將其點亮

          假設(shè)現(xiàn)在有第2個點的坐標(biāo)x[2] = 1, y[2] = 2,那么點亮這個點的方式為

          P2 = 0x04; //0000 0100

          P0 = 0xfb; //1111 1011

          3、按鍵產(chǎn)生外部中斷,在中斷里判斷按下那個方向get_direction(),并且同時設(shè)置坐標(biāo)set_location()

          4、定時器每隔1s就應(yīng)該更新位置,因為蛇要不停的前進(jìn)。定時器不需要更新方向,因為方向只有按鍵才會改動,定時器用前一步的方向

          5、關(guān)于點的位置更新方式

          1)、向上移動

          后面的點去覆蓋前面的點,第一個點用新坐標(biāo)表示x[0]不變,y[0]+1

          2)、向下移動

          后面的點去覆蓋前面的點,第一個點用新坐標(biāo)表示x[0]不變,y[0]-1

          3)、向左移動

          后面的點去覆蓋前面的點,第一個點用新坐標(biāo)表示x[0]-1,y[0]不變

          4)、向右移動

          后面的點去覆蓋前面的點,第一個點用新坐標(biāo)表示x[0]+1,y[0]不變

          6、關(guān)于邊界問題:

          1)、任何一個點的橫坐標(biāo) 0 = x[i] 8

          2)、任何一個點的縱坐標(biāo) 0 = y[i] 8

          3)、第一個點在移動的時候不能和其他點重復(fù),否則就自己追尾了

          7、關(guān)于原理圖按鍵的設(shè)計

          要求系統(tǒng)能迅速響應(yīng)按鍵,因此輪詢的方式并不可取,只有靠外部中斷。然而51只有2個外部中斷,我們起碼需要4個方向鍵,這樣就不能一個按鍵配一個外部中斷,通過使用4輸入與門,將所有按鍵狀態(tài)集合在一起,然后送給外部中斷0。我們將4個按鍵都接在與門,只要有一個按下,那么與門的輸出就會產(chǎn)生一個下降沿,從而產(chǎn)生外部中斷。

          四、源代碼

          main.c

          #include snake.h

          int error = 0;

          int time=0;

          void interrupt_init()

          {

          EA = 0; //關(guān)閉總中斷

          IT0 = 1; //外部中斷0方式 下降沿

          EA = 1; //開啟總中斷

          EX0 = 1; //開啟外部中斷

          }

          void timer_init()

          {

          EA = 0; //關(guān)總中斷

          ET0 = 1; //開定時器0中斷

          TMOD = 0x02; //定時器0工作方式2

          TL0 = 6; //定時250us

          TH0 = 6;

          EA = 1; //開總中斷

          TR0 = 1; //開始定時

          }

          int main()

          {

          // unsigned char tempx, tempy;

          // unsigned char i,j;

          interrupt_init();

          timer_init();

          snk_init();

          while(1)

          {

          //如果位置錯了就重新初始化蛇

          if(error)

          snk_init();

          //點亮點陣

          matrix();

          }

          }

          void inter0() interrupt 0

          {

          //按鍵產(chǎn)生外部中斷,獲取新的方向

          get_direction();

          //設(shè)置新的位置

          error = set_location();

          // matrix();

          }

          void timer0() interrupt 1

          {

          time++;

          //定時器為250us 積累4000次就是1s

          if(time == 4000)

          {

          //每隔1s都需要重新設(shè)置位置,讓蛇前進(jìn)

          error = set_location();

          time = 0;

          }

          }

          snake.c

          點擊(此處)折疊或打開

          #include snake.h

          //蛇的結(jié)構(gòu)體,x為橫坐標(biāo),y為縱坐標(biāo),length為蛇的長度,direction為蛇的前進(jìn)方向

          struct snake{

          unsigned char x[20];

          unsigned char y[20];

          unsigned char length;

          unsigned char direction;

          }snk;

          void matrix()

          {

          unsigned char i;

          int count=500;

          //關(guān)閉所有的點

          P2 = 0x00;

          P0 = 0xff;

          //根據(jù)蛇每一個點的坐標(biāo),將對應(yīng)的點陣點亮

          for(i=0; i

          {

          P2 = 1

          P0 = ~(1

          }

          }

          void snk_init()

          {

          //初始化坐標(biāo),總共4個點(3,0) (2,0) (1,0) (1,0)

          snk.x[0] = 3;

          snk.y[0] = 0;

          snk.x[1] = 2;

          snk.y[1] = 0;

          snk.x[2] = 1;

          snk.y[2] = 0;

          snk.x[3] = 0;

          snk.y[3] = 0;

          //初始長度4

          snk.length = 4;

          //初始移動方向 向右

          snk.direction = RIGHT;

          //點亮點陣

          matrix();

          }

          void get_direction()

          {

          //通過按鍵的狀態(tài)獲取方向

          if(!up)

          snk.direction = UP;

          if(!down)

          snk.direction = DOWN;

          if(!left)

          snk.direction = LEFT;

          if(!right)

          snk.direction = RIGHT;

          }

          int set_location()

          {

          unsigned char i;

          int err = 0;

          if(snk.direction == UP)

          {

          for(i=snk.length-1; i>0; i--)

          {

          snk.x[i] = snk.x[i-1];

          snk.y[i] = snk.y[i-1];

          }

          //如果向上運(yùn)動,第0個點的橫坐標(biāo)不變,縱坐標(biāo)加1

          snk.x[0] = snk.x[0];

          snk.y[0] = snk.y[0] + 1;

          }

          else if(snk.direction == DOWN)

          {

          for(i=snk.length-1; i>0; i--)

          {

          snk.x[i] = snk.x[i-1];

          snk.y[i] = snk.y[i-1];

          }

          //如果向下運(yùn)動,第0個點的橫坐標(biāo)不變,縱坐標(biāo)減1

          snk.x[0] = snk.x[0];

          snk.y[0] = snk.y[0] - 1;

          }

          else if(snk.direction == LEFT)

          {

          for(i=snk.length-1; i>0; i--)

          {

          snk.x[i] = snk.x[i-1];

          snk.y[i] = snk.y[i-1];

          }

          //如果向左運(yùn)動,第0個點的橫坐標(biāo)減1,縱坐標(biāo)不變

          snk.x[0] = snk.x[0] - 1;

          snk.y[0] = snk.y[0];

          }

          else

          {

          for(i=snk.length-1; i>0; i--)

          {

          snk.x[i] = snk.x[i-1];

          snk.y[i] = snk.y[i-1];

          }

          //如果向右運(yùn)動,第0個點的橫坐標(biāo)加1,縱坐標(biāo)不變

          snk.x[0] = snk.x[0] + 1;

          snk.y[0] = snk.y[0];

          }

          err = is_location_error();

          return err;

          }

          int is_location_error()

          {

          unsigned char i;

          //如果第0個點的坐標(biāo)和其他任意一個點重復(fù),那么蛇就自己撞自己,出錯

          for(i=1; i

          {

          if((snk.x[0]==snk.x[i]) (snk.y[0]==snk.y[i]))

          return 1;

          }

          //如果蛇的坐標(biāo)超出范圍,也出錯

          if(snk.x[0]>7 || snk.y[0]>7)

          return 1;

          return 0;

          }

          snake.h

          #include

          //定義四個方向按鍵

          sbit up = P3^4;

          sbit down = P3^5;

          sbit left = P3^6;

          sbit right = P3^7;

          //定義1個游戲級別按鍵

          sbit level = P3^0;

          //定義一個復(fù)位按鍵

          sbit reset = P3^1;

          //定義4個方向的值

          #define RIGHT 0

          #define UP 1

          #define LEFT 2

          #define DOWN 3

          void delay_us();

          void delay_10us();

          void delay_ms();

          void delay_10ms();

          void delay_100ms();

          void delay_s();

          int is_location_error();

          void matrix();

          void snk_init();

          void set_direction();

          int get_location();

          int is_location_error();

          『本文轉(zhuǎn)載自網(wǎng)絡(luò),版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系刪除』



          關(guān)鍵詞: 51單片機(jī) 貪吃蛇

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();