待分类·

Nebula Pi 开发板应用(二)—网红10秒挑战器的实现

ii11nnocent

ii11nnocent

2483 0

这两年比较火的网红10秒挑战规则为:挑战者按下开始按钮开始计时,当挑战者认为10秒将到时,再次按下按钮计时暂停,数码管上显示当前的计时时间。再次按下按钮,时间清零,重新开始下一次挑战。 利用Nebula Pi开发板的按键KEY1和数码管可以完成网红10秒挑战器的制作,程序如下:

smg.h:

#ifndef _SMG_H
#define _SMG_H

#include "reg52.h"

sbit Duan = P0^6;  //位定义数码管段选
sbit Wei  = P0^7;  //位定义数码管位选

void DigDisplay(unsigned int Time);
void delay(unsigned int i);

#endif

smg.c:

#include "smg.h"

unsigned char i;

unsigned char code smgduan[] = {0x3F,0x06,0x5B,0x4F,
                     0x66,0x6D,0x7D,0x07,
                     0x7F,0x6F,0x77,0x7C,
                     0x39,0x5E,0x79,0x71,0X76};  //数码管0~F、H段码

void delay(unsigned int i)
{
 while(i--);
}

void DigDisplay(unsigned int Time)
{
    for(i=1;i<5;i++)
      {
       switch(i)
       {
        case(1):
         P2 = 0xFE; //选中第一个数码管
         Wei = 1;
         Wei = 0;  //位锁存
         P2 = smgduan[Time/1000]; //时间的十位
         Duan = 1;
         Duan = 0;
         break;
        case(2):
         P2 = 0xFD; //选中第二个数码管
         Wei = 1;
         Wei = 0;  //位锁存
         P2 = smgduan[Time/100%10] + 0x80; //时间的个位(+0x80是为了加小数点)
         Duan = 1;
         Duan = 0;
         break;
        case(3):
         P2 = 0xFB; //选中第二个数码管
         Wei = 1;
         Wei = 0;  //位锁存
         P2 = smgduan[Time/10%10]; //时间的0.1s位
         Duan = 1;
         Duan = 0;
         break;
        case(4):
         P2 = 0xF7; //选中第二个数码管
         Wei = 1;
         Wei = 0;  //位锁存
         P2 = smgduan[Time%10]; //时间的0.01s位
         Duan = 1;
         Duan = 0;
         break;  
       }
       delay(100);
       P2 = 0x00;
       Duan = 1;
       Duan = 0;   //消影   
     }
}

KeyState.h:

#ifndef _KEYSTATE_H
#define _KEYSTATE_H

#include "reg52.h"

unsigned char ReadKeyState(void);
void Timer_Init(void);

extern unsigned char Times;                     //用于按键按下次数的计算

#endif

KeyState.c:

#include "KeyState.h"

sbit Key1 = P1^0;                           //位定义KEY1按键
unsigned char KeyReturn;            //保存按键的返回值
unsigned char Times = 0;                                

/****宏定义按键的初始、按下和抬起状态****/
#define Key_State_Init  0
#define Key_State_Down  1
#define Key_State_Up        2

unsigned char ReadKeyState(void)
{
    static char KeyState = 0;           //按键的状态值,初始值为0
    unsigned char KeyPress;             //保存按键的电平值
    KeyPress = Key1;                            //保存P1.0口电平
    
    switch( KeyState )
    {
        case Key_State_Init:                //初始状态
            if( !KeyPress )                     //读取IO电平
            {
                KeyReturn = 0;                  //按键返回值为0
                KeyState = Key_State_Down;  //按键的状态转为按键按下的状态
            }
            break;
        case Key_State_Down:                //初始状态按下后转为按下状态
            if( !KeyPress )                     //读取IO电平确认按键是否真的被按下
            {
                KeyReturn = 1;                  //按键返回值为1
                Times++;                                        //每按下一次按键,按键按下次数+1
                KeyState = Key_State_Up;        //按键的状态转为按键释放的状态
            }
            else
            {
                KeyState = Key_State_Init;  //如果IO电平为0,证明按键已抬起,回到初始状态
            }
        case Key_State_Up:                  //按下以后转为抬起状态
//          if ( !KeyPress )                    //如果按键一直按下,即没有抬起
//          {
//              Times ++;                               //只要一直按下按键,Times就会10ms增加1
//              if( Times == 100 )          //Times=100时,1s定时时间到,标志位取反并且Times值清零
//              {
//                  Flag    = Flag;
//                  Times = 0;
//              }
//          }
            if( KeyPress )                      //如果按键抬起了
            {
                KeyReturn = 2;                  //按键返回值为2
                KeyState = Key_State_Init;  //读取IO电平,如果是1,证明按键已释放,回到初始状态
            }

    }
    return KeyReturn;
}

void Timer_Init(void)
{
    TMOD    = 0x11;     //定时器0、1均工作在方式1,定时器0用于时间计算,定时器用于按键值的读取
    TH0     = 0xDC;
    TL0     = 0x00;     //定时器0 10ms定时初值
    TH1     = 0xDC;
    TL1     = 0x00;     //定时器1 10ms定时初值
    ET0     = 1;            //开定时器0中断
    ET1     = 1;            //开定时器1中断
    EA      = 1;            //开总中断
    TR1     = 1;            //打开定时器1
    //TR0       = 1;            //打开定时器0    
}

main.c:

#include "reg52.h"
#include "smg.h"
#include "KeyState.h"

unsigned int time = 0;
unsigned char KeyNumber = 0;    //按键值保存变量

void main(void)
{
    Timer_Init();
    while(1)
    {       
        if( KeyNumber == 1 )                            //按下按键开启不同动作
        {
            if( Times == 1 )                                //按下一次按键后,开始计时
            {
                TH0 = 0xDC;                                 //重新赋初值,防止上次停止时TH0和TL0中存在遗留值
                TL0 = 0x00;  
                TR0 = 1;
            }
            if( Times == 2 )                                //按下两次按键后,停止计时
            {
                TR0 = 0;
            }       
            if( Times == 3 )                                //按下三次按键后,重新开始计时,并将次数清零
            {
                Times = 0;
                time = 0;
            }
        }
        DigDisplay(time);
    }
}

void Timer0() interrupt 1 using 1  
{  
     TH0 = 0xDC;   //重装初值,定时1ms初值高八位  
     TL0 = 0x00;   //定时1ms初值低八位  
         time++; //时间加一    
     if ( time == 9999) time = 0;
}

void Timer1() interrupt 3 using 2  
{  
     TH1 = 0xDC;   //重装初值,定时1ms初值高八位  
     TL1 = 0x00;   //定时1ms初值低八位  
         KeyNumber = ReadKeyState();        //读取按键值
}

视频: 10s.mp4

相关文章

优先推荐同专题、同标签和同作者内容,补足热门文章。

评论 0

登录 后参与评论

评论

成为第一个评论的人