新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 51單片機項目實戰---貪吃蛇(測試版)

        51單片機項目實戰---貪吃蛇(測試版)

        作者: 時間:2018-08-06 來源:網絡 收藏

        一、元器件

        1、AT89C51

        本文引用地址:http://www.104case.com/article/201808/385449.htm

        關于就不在嗦了,相信大家都已經很熟悉了。

        2、8x8點陣

        點陣里面就是一些二極管啦,通過縱橫交叉連接,橫8豎8,每個交叉點都接一個二極管。這里給大家找到一個點陣的實物圖


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

        二、原理圖



        三、項目分析

        1、首先定義一個結構體

        struct snake{

        unsigned char x[20];

        unsigned char y[20];

        unsigned char length;

        unsigned char direction;

        }snk;

        數組x,y分別存放每一個點的橫縱坐標,length為蛇的長度,direction為蛇前進的方向

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

        假設現在有第2個點的坐標x[2] = 1, y[2] = 2,那么點亮這個點的方式為

        P2 = 0x04; //0000 0100

        P0 = 0xfb; //1111 1011

        3、按鍵產生外部中斷,在中斷里判斷按下那個方向get_direction(),并且同時設置坐標set_location()

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

        5、關于點的位置更新方式

        1)、向上移動

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

        2)、向下移動

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

        3)、向左移動

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

        4)、向右移動

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

        6、關于邊界問題:

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

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

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

        7、關于原理圖按鍵的設計

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

        四、源代碼

        main.c

        #include snake.h

        int error = 0;

        int time=0;

        void interrupt_init()

        {

        EA = 0; //關閉總中斷

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

        EA = 1; //開啟總中斷

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

        }

        void timer_init()

        {

        EA = 0; //關總中斷

        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

        {

        //按鍵產生外部中斷,獲取新的方向

        get_direction();

        //設置新的位置

        error = set_location();

        // matrix();

        }

        void timer0() interrupt 1

        {

        time++;

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

        if(time == 4000)

        {

        //每隔1s都需要重新設置位置,讓蛇前進

        error = set_location();

        time = 0;

        }

        }

        snake.c

        點擊(此處)折疊或打開

        #include snake.h

        //蛇的結構體,x為橫坐標,y為縱坐標,length為蛇的長度,direction為蛇的前進方向

        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;

        //關閉所有的點

        P2 = 0x00;

        P0 = 0xff;

        //根據蛇每一個點的坐標,將對應的點陣點亮

        for(i=0; i

        {

        P2 = 1

        P0 = ~(1

        }

        }

        void snk_init()

        {

        //初始化坐標,總共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()

        {

        //通過按鍵的狀態獲取方向

        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];

        }

        //如果向上運動,第0個點的橫坐標不變,縱坐標加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];

        }

        //如果向下運動,第0個點的橫坐標不變,縱坐標減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];

        }

        //如果向左運動,第0個點的橫坐標減1,縱坐標不變

        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];

        }

        //如果向右運動,第0個點的橫坐標加1,縱坐標不變

        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個點的坐標和其他任意一個點重復,那么蛇就自己撞自己,出錯

        for(i=1; i

        {

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

        return 1;

        }

        //如果蛇的坐標超出范圍,也出錯

        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;

        //定義一個復位按鍵

        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();

        『本文轉載自網絡,版權歸原作者所有,如有侵權請聯系刪除』



        關鍵詞: 51單片機 貪吃蛇

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 靖安县| 舞阳县| 宁蒗| 麻阳| 沛县| 临汾市| 廊坊市| 府谷县| 武城县| 三门峡市| 紫云| 张家界市| 道孚县| 加查县| 西藏| 新干县| 剑河县| 隆回县| 若尔盖县| 高州市| 霍城县| 沈阳市| 宝丰县| 孙吴县| 九龙坡区| 开阳县| 喀喇沁旗| 珠海市| 将乐县| 腾冲县| 江山市| 乳山市| 都匀市| 定安县| 璧山县| 克拉玛依市| 秦皇岛市| 内江市| 屏东县| 霍山县| 五寨县|