3
相比大家对51架构都是比较了解的。在这里呢,我就只陈述整个流程和思路以及主函数架构讲解。对于51单片机的配置问题就不再赘述了。
先让大家看看原理图吧。手边没有开发板,简单的使用了一下protues来搭建我的实验电路。至于仿真器的问题呢,的确有很多。如果你们手边有开发板呢,那就用实物验证一下吧。
这就是整个系统的原理图了,很简单的是吧!但是它的功能可不是看上去这么简单哦~
系统的流程:
主持人可以通过设置抢答的时限和回答的时限来控制整个流程。当主持人按下抢答键以后,选手才可以正式抢答,否则,选手抢答键无效。选手如果抢答成功,则可以加分,并显示分数。如果抢答失败,则需要减分,并显示分数。同时在本系统中还加入了一个倒计时闪烁功能。即当抢答时间和回答时间倒计时低于10s的时候,倒计时数码管会闪烁显示,提示选手时间不多。
整个程序的思路则是采用单进程处理方式,通过系统中断实现多线程处理多任务。虽然从程序上看上去是单线程,其实它的处理速度还是很理想的。几乎能够及时响应用户操作,且能够达到很理想的精准。
废话了这么多,现在就是压轴戏了。开始讲解主函数架构。
//主函数
void main(void)
{
unsigned char AscTable[]={0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10};
unsigned char DisBuff[4]={0x40,0x40,0x40,0x40};
unsigned char score[8]={5,5,5,5,5,5,5,5};//初始分数
unsigned char Qdtemp,Hdtemp,Btval,K;
Boolean Confirmval;
STAR = 0x00 ;//初始化
Qdtime = 12 ;
Hdtime = 12 ;
K = 0;
Confirmval=false;
InitDevices();//51硬件初始化
ClearSegBuff(DisBuff);//初始化显存缓冲区
while(1)
{
SetParaTime(DisBuff,AscTable);//设置时间参数,即抢答时限和回答时限的设定
if(ConfirmVal())//主持人按下抢答键
{
Qdtemp = Qdtime;Hdtemp = Hdtime;//将设定好的时限值赋予临时变量
TR0 = 1;//计时器开始工作
while(Qdtemp&&Hdtemp&&!Confirmval)//判断结束条件,抢答倒计时为0或回答倒计时为0或主持人按下回答完成按键
{
if(STAR&0x20)//选手抢答按键按下
{
Confirmval = ConfirmVal();
if((STAR&0x1F)==20){Hdtemp --; STAR&=~0x1F;}//回答倒计时计数
DisBuff[0] = AscTable[Btval];//写显存缓冲区
DisBuff[2] = AscTable[Hdtemp/10];//写显存缓冲区
DisBuff[3] = AscTable[Hdtemp%10];//写显存缓冲区
}
else//没有选手抢答键按下
{
Btval = BottonVal();
if((STAR&0x1F)==20){Qdtemp --; STAR&=~0x1F;}//抢答倒计时计数
if(Btval>=1&&Btval<=8)/检测到选手抢答按键按下
{
TR0 = 0 ;//停止计时器
LED=~LED;//提示LED灯
STAR&=~0x1F;//清零计数状态位
TH0 = (65536-50000)/256;//设定计时器初值
TL0 = (65536-50000)%256;
STAR|=0x20;//抢答按键按下标志位置位
TR0 = 1;//重新运行计时器
}
DisBuff[2] = AscTable[Qdtemp/10];//写显存缓冲区
DisBuff[3] = AscTable[Qdtemp%10];//写显存缓冲区
}
//时间显示
if(STAR&0x20)//回答倒计时显存缓冲区显示
{
if(Hdtemp >= 10) DisStatueSel(DisBuff,1,K);//如果倒计时时间大于10s则正常显示
else DisStatueSel(DisBuff,0,(STAR&0x1F));//如果倒计时时间小于10s则闪烁显示,提醒选手时间不多
}
else//抢答倒计时显存缓冲区显示
{
if(Qdtemp >= 10) DisStatueSel(DisBuff,1,K);//如果倒计时时间大于10s则正常显示
else DisStatueSel(DisBuff,0,(STAR&0x1F));//如果倒计时时间小于10s则闪烁显示,提醒选手时间不多
}
}
TR0 = 0 ;//一道抢答题周期结束,关闭计时器
if(STAR&0x20)//选手抢答过本题,则进入分数计算和显示
{
while(!PlayersScore(Btval,score))//设置选手分数
{
DisBuff[0] = AscTable[Btval];
DisBuff[1] = AscTable[score[Btval-1]/10];
DisBuff[2] = AscTable[score[Btval-1]%10];
DisBuff[3] = AscTable[0];
Seg7Dispaly(DisBuff,4);
}
}
//任务执行完成,清除所有相关设置
STAR=0;//清除标志位
TH0 = (65536-50000)/256;//重置计时器
TL0 = (65536-50000)%256;
ClearSegBuff(DisBuff);//初始化显存缓冲区
}
}
}
系统工作截图:
抢答倒计时显示
5号选手抢答成功
回答完成,设置3号选手分数
|
|