欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標題: 基于51單片機8x8點陣顯示的貪吃蛇游戲 [打印本頁]

作者: jian930716    時間: 2016-4-28 12:42
標題: 基于51單片機8x8點陣顯示的貪吃蛇游戲

  說明:使用hc595驅(qū)動雙色點陣
            使用德飛萊51單片機開發(fā)板(DOFLY-V2.3)
                依據(jù)程序中的管腳定義用杜邦線接好管腳
                程序可以直接使用。
                程序部分參考自網(wǎng)上和學(xué)習(xí)板配套資料
------------------------------------------------*/
#include<reg52.h>    //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
#include <intrins.h>
       
/*------------------------------------------------
                硬件端口定義
------------------------------------------------*/
sbit LATCH= P1^0;            //鎖存
sbit SRCLK= P1^1;      //時鐘
sbit SER  = P1^2;      //數(shù)據(jù)
sbit LATCH_B= P2^2;    //鎖存
sbit SRCLK_B= P2^1;           //時鐘
sbit SER_B= P2^0;      //鎖存                                      
sbit LED=P1^3;                   //結(jié)束提示燈
//sbit key1=P3^0;           //上
//sbit key2=P3^1;           //下
//sbit key3=P3^2;           //左
//sbit key4=P3^3;      //右
//sbit key5=P3^4;           //暫停

/*------------------------------------------------
                全局變量定義
------------------------------------------------*/
unsigned char x[30],y[30];     //蛇身坐標
unsigned char speed=10;        //控制速度變量         
unsigned char dx=0,dy=1;           //控制轉(zhuǎn)向變量,初始化為向左運動
bit stop_start,inverse;                   //開始/暫停標志位,顏色顯示標志位
bit up=1,down=1,left=1,right=1;//上下左右使能控制位
unsigned char tab[8];                   //顯示緩沖數(shù)組
unsigned char  segout[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //8列掃描
/*------------------------------------------------
uS延時函數(shù),含有輸入?yún)?shù) unsigned char t,無返回值
unsigned char 是定義無符號字符變量,其值的范圍是
0~255 這里使用晶振12M,精確延時請使用匯編,大致延時
長度如下 T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{   
    while(--t);
}
/*------------------------------------------------
mS延時函數(shù),含有輸入?yún)?shù) unsigned char t,無返回值
unsigned char 是定義無符號字符變量,其值的范圍是
0~255 這里使用晶振12M,精確延時請使用匯編
------------------------------------------------*/
void DelayMs(int t)         //大致延時1mS
{   
    while(t--)
    {     
             DelayUs2x(245);
                 DelayUs2x(245);
    }
}
/*------------------------------------------------
                發(fā)送字節(jié)程序
------------------------------------------------*/
void SendByte(unsigned char dat)
{   
          unsigned char i;        
    for(i=0;i<8;i++)
    {
             SRCLK=0;
             SER=dat&0x80;
             dat<<=1;
             SRCLK=1;
    }        
}
/*------------------------------------------------
                發(fā)送雙字節(jié)程序
     595級聯(lián),n個595,就需要發(fā)送n字節(jié)后鎖存
------------------------------------------------*/
void Send2Byte(unsigned char dat1,unsigned char dat2)
{   
    SendByte(dat1);
    SendByte(dat2);      
}
/*------------------------------------------------
                  595鎖存程序
                  595級聯(lián)發(fā)送數(shù)據(jù)后,鎖存有效
------------------------------------------------*/
void Out595(void)
{
    LATCH=0;
    _nop_();
    LATCH=1;
}
/*------------------------------------------------
                發(fā)送位碼字節(jié)程序
               使用另外一片單獨595
------------------------------------------------*/
void SendSeg(unsigned char dat)
{   
        unsigned char i;         
    for(i=0;i<8;i++)  //發(fā)送字節(jié)
    {
         SRCLK_B=0;
         SER_B=dat&0x80;
         dat<<=1;
         SRCLK_B=1;
    }
    LATCH_B=0;    //鎖存
    _nop_();
    LATCH_B=1;         
}                                                          
/*--------------------------------------------------------------
                                按鍵掃描函數(shù)
--------------------------------------------------------------*/
void key_scan()
{
         switch(P3)
         {
                 case 0xfe: if(up)                                                            //up
                                   {
                                           dx=-1;dy=0;                                                //執(zhí)行向上功能
                                           down=0;left=1;right=1;                           //向下功能失效,其他功能可用
                                   }                                              
                                        break;
                case 0xfd: if(down)                                                                //down
                                   {dx=1;dy=0;up=0;left=1;right=1;}     //                          
                                        break;
                case 0xfb: if(left)                                                                //left
                                   {dx=0;dy=1;down=1;up=1;right=0;}     //                       
                                        break;
                case 0xf7: if(right)                                                        //right
                                   {dx=0;dy=-1;down=1;left=1;up=1;}     //                 
                                         break;
                case 0xef:                                             //暫停/開始鍵
                                        DelayMs(10);                         //延時去抖
                                        if(P3==0xef)                         //再次確認按鍵是否按下
                                        stop_start=~stop_start;         //暫停/開始標志位取反(按一下暫停再按一下開始)
                                        while(P3==0xef);                 //等待按鍵釋放
                                        break;
                case 0xbf:
                                        DelayMs(10);                         //延時去抖
                                        if(P3==0xbf)                         //再次確認按鍵是否按下
                                        speed+=2;                                   //速度增大
                                        while(P3==0xbf);                 //等待按鍵釋放
                                        break;
                case 0x7f:         DelayMs(10);                         //延時去抖
                                        if(P3==0x7f)                         //再次確認按鍵是否按下               
                                        speed-=2;                                   //速度減小
                                        while(P3==0x7f);                 //等待按鍵釋放
                                        break;
                default: break;
         }
}                                                                                                                                                                                         
/*--------------------------------------------------------------
                        清除顯示緩沖區(qū),即清屏
--------------------------------------------------------------*/
void clr_ram(void)
{
    unsigned char i;
    for(i = 0; i < 8; i++)
        tab[i] = 0x00;           //逐個清除數(shù)組內(nèi)容
}                                                                                                                                 
/*--------------------------------------------------------------
畫點函數(shù),擦點或者繪點
點陣左上角坐標為(0, 0)    右下角坐標為(7, 7)
橫坐標為x:0~7        縱坐標為y:0~7
k = 1 --繪點      k = 0 --擦點
-------------------------------------------------------------*/   
void point1(unsigned char x, unsigned char y, bit k)
{
    if(k) tab[y] |= 0x01 << x;                 //保留原始點,繪制新點
    else  tab[y] &= ~(0x01 << x);         //保留其它點,只擦其中一個點
}


/*------------------------------------------------------------
                                定時器0初始化
--------------------------------------------------------------*/
void T0_init(void)
{
    TMOD|= 0x01;
    TH0  = 0xf8;        //2ms
    TL0  = 0x36;
    IE  |= 0x82;
    TR0  = 1;
}
/*--------------------------------------------------------------
                                定時器1初始化
--------------------------------------------------------------*/
void T1_init(void)                    
{                                                                          
    TMOD|= 0x01;
    TH1  = 0x00;        //65ms
    TL1  = 0x00;
    IE  |= 0x88;
    TR1  = 1;
}
/*------------------------------------------------
                   主程序
------------------------------------------------*/
void main()
{
        unsigned char i=0,foodx, foody;        //食物坐標
        unsigned char num=2;            //蛇長度
        bit food,over;                  //食物和結(jié)束標志位
          IT0  = 1;                                                  //外部中斷0(即P3^2腳)選擇邊沿觸發(fā),下降沿有效
        EX0  = 1;                                                  //打開外部中斷0
        T0_init();                                                //定時器0初始化
        T1_init();                                                //定時器1初始化
        stop_start=0;                   //開始/暫停標志位置為開始                  
        while(1)
        {
                x[0] += dx;   y[0] += dy;        //根據(jù)dxdy不同的值來使蛇頭移動
        x[0] &= 0x07; y[0] &= 0x07; //作用穿墻,x或y加到8時變?yōu)?
                if(!food)                   //放置食物
        {
  again:    foodx = TL0&0x07;           //隨機取食物坐標,0~7,但不會超過7            
            foody = TH0&0x07;
            for(i = 0; i < num; i++)
            {
                if(foodx==x[i]&&foody==y[i])  //若食物與蛇身重疊,               
                                goto again;                                          //則重放食物。
            }
                //        inverse=0;                                                  //顏色標志位置0,顯示紅色
            point1(foodx, foody, 1);          //顯示食物
            food = 1;                         //置食物標志位
        }
                if(x[0] == foodx && y[0] == foody)    //吃到食物   
        {
            num++;                            //蛇長增加1節(jié)
            food = 0;                         //清食物標志位
        }

                for(;stop_start;);                                          //按下暫停鍵程序在此進入死循環(huán)

        //        inverse=1;                                                      //顏色標志位置1,顯示綠色
                for(i = 0; i < num; i++)              //顯示蛇身
                point1(x[i], y[i], 1);

        point1(x[i], y[i], 0);                //清蛇尾
                for(i = 1; i < num; i++)              //判斷是否自撞
        {
            if((x[0]==x[i])&&(y[0]==y[i]))
            over = 1;                         //置結(jié)束標志位
        }
                for(i=0;i<speed;i++) DelayMs(15);           //蛇運動速度

        for(i = 0; i < num; i++)              //蛇移動蛇身
        {
            x[num-i] = x[num-i-1];
            y[num-i] = y[num-i-1];
        }
                if(over)                      //判斷是否結(jié)束
        {
                        for(i=0;i<10;i++)                  //LED閃5次
                        {                                                  
                                LED=~LED;                         
                                DelayMs(100);
                        }
                        clr_ram();                //清除屏幕
                        num = 2;                  //重新設(shè)定蛇長
            point1(foodx, foody, 1);  //重新放置食物
            x[0] = 0; y[0] = 0;       //起點位置
            dx=0;dy=1;                //向左運動
            over = 0;                                   //清除結(jié)束標志
                }
        }
}
/*--------------------------------------------------------------
                                定時器1中斷服務(wù)
--------------------------------------------------------------*/
void T1_intservice(void) interrupt 3
{

        TH1  = 0x00;
    TL1  = 0x00;
        key_scan();                                                                                                         
}
/*--------------------------------------------------------------
                                定時器0中斷服務(wù)
--------------------------------------------------------------*/
void T0_intservice(void) interrupt 1
{
    static unsigned char n;                //定義靜態(tài)變量
    TR1 = 0;                                        //關(guān)閉定時器1
    TH0  = 0xf8;                       
    TL0  = 0x36;                        //重裝初值,2ms
        SendSeg(segout[n]);                    //發(fā)送列碼(相當于數(shù)碼管中的位碼)
        if(inverse)       
            Send2Byte(0xff,~tab[n]);//發(fā)送點碼(相當于數(shù)碼管中的段碼),顯示綠色,交換兩個量可改變顏色
    else
                Send2Byte(~tab[n],0xff);//發(fā)送點碼(相當于數(shù)碼管中的段碼),顯示紅色,交換兩個量可改變顏色
        Out595();                                        //595鎖存程序
        DelayMs(1);       
        Send2Byte(0xff,0xff);       //防止重影
        Out595();       
        n++; if(n == 8) n = 0;      //循環(huán)掃描
    TR1 = 1;                                        //打開定時器1
}                                                                               


作者: 壹個人    時間: 2017-7-1 20:07
左鍵清屏?沒找到原因
作者: love羅    時間: 2018-11-15 16:34
有接線圖嗎

作者: 969866    時間: 2020-10-22 19:13
love羅 發(fā)表于 2018-11-15 16:34
有接線圖嗎

你還會嗎




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