用51单片机设计一款记忆力测试小游戏

有一种常见的益智小游戏:

游戏中,屏幕会显示一组10位数字,并很快消失,
             玩家通过瞬时记忆,输入相同的内容,如正确,进入下一关;错误,将重新开始
             随着关卡后移,屏幕显示数组的时间会越来越短,以提高难度


51虽然是一款最基础的单片机,但这次,我想实现上面的游戏功能。

需要的外设:(如图)51开发板 ,集成一体的红外接收头  遥控器  LCD1602

用51单片机设计一款记忆力测试小游戏_第1张图片

先预想好按键功能:

用51单片机设计一款记忆力测试小游戏_第2张图片

分析几个问题:

1、产生随机数的方法:rand函数,种子则通过定时器的TH 和TL读取

2、红外遥控数据的读取:好在开发板接到的是单片机的外部中断1引脚 P3.3 通过外部中断,读取按键数据按照红外协议即可

3、存储游戏记录:好不容易玩到成绩很高的记录,一定要存储下来,这里利用开发板上的AT24C02可实现,通过单片机IO口模拟IIC的存取,记录游戏最高记录

4、游戏中原本该按确认键(或其他),结果按错了:做一个按键过滤机制,当前游戏处于某一状态下,其他按键按下无效。


有了上面的几条分析,在写程序的时候就会顺利很多。下面贴出来主要函数的代码:

获取随机数:

void getrand()
{
    uchar i=0;
    uchar t;               //随机种子,通过定时器1读取
    for(i=0;i<10;i++)
    {
        if(i%2==0)
            t= TL1;
        else
            t= TH1;
        srand(t);
        cnum[i]=ASCII[(char)(rand()%10)]; //取随机数('0'~'9')
    }
}


外部中断的红外遥控数据读取:

void exint1()interrupt 2
{
    uchar i=0,j=0,k=0,us=0;
    uchar addr[4]={0};

    EX1=0;

    for(i=0;i<255;i++)  //9ms内有高电平认为是干扰
    {
        if(P3&0x08)        //255的值实际时间为800us
        {
            EX1=1;
            return;
        }
    }
    while(!(P3&0x08));    //等待9ms低电平过去
       for(i=0;i<4;i++)
    {
        for(j=0;j<8;j++)
        {
            while(P3&0x08);    //等待4.5ms高电平过去    
            while(!(P3&0x08));    //等待0.56ms低电平后面的高电平
            while(P3&0x08)        //计算这个高电平的时间
            {
                for(us=0;us<=64;us++);    //100us的延时语句
                if((k++)>=30)        //高电平时间过长退出程序
                {
                    EX1=1;
                    return;
                }
            }
            addr[i]=addr[i]>>1;    //接收一位数据
            if(k>=8)
                addr[i]=addr[i]|0x80;    //高电平大于0.56ms,则为1
            k=0;
        }
    }    
    flag_r = 1;
    revd = addr[2];
    EX1=1;      
}


IIC模拟:

bit WriteNByte(unsigned int sla,unsigned int suba,unsigned int *s,unsigned int n)
{
        unsigned int i;
        I2C_Start();//启动I2C
        SendData(sla);//发送器件地址
        Test_Ack();
         if(i2c_flag==0)        
                  return(0);
        SendData(suba);
        Test_Ack();
        if(i2c_flag==0)
                  return(0);
        for(i=0;i         {
                SendData(*(s+i));
                Test_Ack();
                if(i2c_flag==0)        
                             return(0);
        }
        I2C_Stop();
        return(1);
}

bit ReadNByte(unsigned int sla,unsigned int suba,unsigned int *p,unsigned int n)
{
        unsigned int i;
        I2C_Start();//启动I2C
        SendData(sla);//发送器件地址
        Test_Ack();
        //if(i2c_flag==0)        return(0);
        SendData(suba);//发送器件内部地址
        Test_Ack();
        //if(i2c_flag==0)        return(0);

        I2C_Start();
        SendData(sla+1);
        Test_Ack();
        if(i2c_flag==0)        return(0);
        for(i=0;i         {
                *(p+i)=ReceiveData();//读取数据
                Ack();
        }
        *(p+n-1)=ReceiveData();
        
        NoAck();
        I2C_Stop();
        return(1);
}


简单的过滤机制:

            if(status == 0)            //状态过滤机制    0
            {
                if(revd !=0x45) revd = 0;
            }
            if(status == 1)            //状态过滤机制    1
            {
                if(revd !=0x45 && revd !=0x43) revd = 0;
            }

好了,编译通过就开始游戏吧:

用51单片机设计一款记忆力测试小游戏_第3张图片

每天一段单片机小知识,我们的微信公众号:mcu_51     请记得推荐给身边每一位朋友
用51单片机设计一款记忆力测试小游戏_第4张图片

你可能感兴趣的:(单片机小车,红外遥控,51单片机,益智游戏)