原理思路:
看了短视频里的火锅店搞了一个“挑战10秒免单”,学了大半年的单片机觉得这是生活中我为数不多的能大致实现的了,于是花了两天时间修修改改写成个下面这个“挑战10秒”。
原理其实很简单,就是用51单片机捕获高电平,纪录高电平也就是按下按钮的时间,当刚好按够10:00秒LCD的第二行显示'Victory!',否则显示'Defeat!'。为了显示'Victory!'我试了十多次才成功,看来想要免单还是很不容易的。
效果展示:
用51单片机“挑战10秒赢免单”
打包下载地址:
https://download.csdn.net/download/small_planet/33218591
https://download.csdn.net/download/small_planet/33218591
代码:
外部中断0,下降沿中断,松开按钮会触发这个中断,ic_sta高两位置10,表示完成一次挑战,可以接收下一次挑战
void exti0() interrupt 0 //注意:刚开始会有两次下降沿触发
{
if(flag>0)
{
ic_sta|=0x8000;
ic_sta&=0xbfff; //让高两位变成10,其他位不变
}
else
{
flag++;
}
}
定时器中断,定时器记的数溢出会触发这个中断
void time0() interrupt 1
{
TH0=(65535-46083)/256; //1.085us,溢出一次50ms
TL0=(65535-46083)%256;
if((ic_sta&0x4000)==0x0000) //第一次捕获到高电平
{
ic_sta=0x4001;
}
else //此前已经捕获到了高电平
{
ic_sta++;
}
}
主函数,循环显示
int main()
{
unsigned int i,t;
unsigned char num[6]={'0','0',':','0','0','\0'};
unsigned char victory[]={'V','i','c','t','o','r','y','!',' ',' ','\0'};
unsigned char defeat[]={'D','e','f','e','a','t','!',' ',' ',' ','\0'};
unsigned char goodluck[]={'G','o','o','d',' ','L','u','c','k','!','\0'};
p10=1;
time_init();
LCD_Initial();
while(1)
{
count=ic_sta&0x3fff;
time=50*count; //ms
for(i=0,t=10000;i<5;i++)
{
if(i==2)
{
continue;
}
num[i]=time/t+'0';
time-=(num[i]-'0')*t;
t/=10;
}
delay(100);
LCD_Initial();
LCD_Print(0,0,num);
if(ic_sta&0x8000) //已经完成一次挑战
{
if(num[0]=='1'&&num[1]=='0'&&num[3]=='0'&&num[4]=='0')
{
LCD_Print(0,1,victory);
}
else
{
//Defeat!
LCD_Print(0,1,defeat);
}
}
else
{
//Good Luck!
LCD_Print(0,1,goodluck);
}
}
}