基于STC89C52的限时问答机

    xiaoxiao2022-07-15  142

    引言:

    本文利用STC89C52设计制作了一个限时问答机,能够通过显示设备显示简单的随机算式1,并在规定时间内通过按键读取用户输入,并判断输入结果的正误以及输入是否超时。完整代码请参考:https://github.com/PPPerry/Time-limited-question-and-answer-machine

    1.硬件模块

    电源采用 5V 实验电源供电 4×4矩阵键盘按键输入 LCD1602显示屏

    2.软件模块

    顶层代码:

    #include <stdlib.h> #include <reg52.h> #include "lcd.h" #include "key.h" #include "time.h" //12.8第一次更新: 定时器开启提前 删去两个timestart //12.8第二次更新: 避免出现长按按键超过3s的bug //12.8第三次更新: 三位数选项 //12.8第四次更新: 时间限制选项 u8 code result1[]="true :-)"; u8 code result2[]="false :-("; u8 code result3[]="time out!!!"; u8 code mode1[]="MODE SELECT"; u8 code mode2[]="TIME SELECT"; u8 code over11[]="YOU WIN!!!"; u8 code over12[]="CONGRATULATIONS!"; u8 code over21[]="Game over"; u8 code over22[]="..."; u8 timenum,p,r,limittime,t,f; void delay(u16 ms) { int x,y; for(x=ms;x>0;x--) { for(y=110;y>0;y--); } } void timestart() //定时器重装初值 { TH0=(65536-50000)/256; TL1=(65536-50000)%256; timenum=0; } /*void randnum(char*str) //随机计算式产生函数 { u16 n; for(n=0;n<5;n++) { if(n==2) //随机加减号 { if(timenum%2) *(str+n)='+'; else *(str+n)='-'; } else if(n==0||n==3) //保证个位数不为0 { do { srand((u16)timenum); *(str+n)=rand()%9; }while(*(str+n)==0); } else { srand((u16)timenum); *(str+n)=rand()%9; } } *(str+5)='='; }*/ u8 keyboard(u8 key) //键盘对应符号 { switch(key) { case 2:return '1'; case 3:return '2'; case 4:return '3'; case 9:return '-'; case 6:return '4'; case 7:return '5'; case 8:return '6'; case 10:return '7'; case 11:return '8'; case 12:return '9'; case 15:return '0'; default:return ' '; } } void main() { u8 key; u8 cal[12]; u16 n; int answer; r=1; //记录是否超时的状态参数 TR0=1; //开启定时器 while(1) { t=0;f=0; lcdinit(); write_exact(11,0x00,mode1); key=keyscan(); //矩阵键盘,返回值为按下的按键 if(key==1) //开机键,模式为2位数 { lcdinit(); write_exact(11,0x00,mode2); timeinit(); limittime=' '; while(limittime==' ') //时间限制 {key=keyscan();limittime=keyboard(key);} while(1) { lcdinit(); if(f==5){write_exact(9,0x00,over21);write_exact(3,0x40,over22);timestart();while(timenum!=60);break;} if(t==5){write_exact(10,0x00,over11);write_exact(16,0x40,over12);timestart();while(timenum!=60);break;} r=1; key=' '; cal[6]=' '; cal[7]=' '; cal[8]=' '; for(n=0;n<5;n++) { if(n==2) //随机加减号 { if((p-'0')%2) cal[n]='+'; else cal[n]='-'; } else if(n==0||n==3) //保证十位数不为0 { srand((p-'0')+n); cal[n]='1'+rand()%8; } else { srand((p-'0')+2*n); cal[n]='0'+rand()%9; } } cal[5]='='; if(cal[2]=='+') answer=(cal[0]-'0')*10+(cal[1]-'0')+(cal[3]-'0')*10+(cal[4]-'0'); //算出正确答案 else if(cal[2]=='-') answer=(cal[0]-'0')*10+(cal[1]-'0')-(cal[3]-'0')*10-(cal[4]-'0'); if((answer<0&&answer>-10)||(answer>=10&&answer<=99)) //判断位数 {cal[8]=0;} //置为0后下面代码的while判断就可以跳过 else if(answer>=0&&answer<10) {cal[7]=0;cal[8]=0;} //三位数或负两位数不需置0 write_exact(6,0x00,cal); writetf(); timestart(); if(cal[6]==' ') //输入 { while(key==' ') { key=keyscan(); if(!r)break; if(limittime>3&&(limittime-t-'0')<3){ if(timenum==(limittime-'0')*20) { timenum=0; write_exact(11,0x40,result3); while(timenum!=40); timestart(); r=0; f++; break; } }else{ if(timenum==(limittime-t-'0')*20) { timenum=0; write_exact(11,0x40,result3); while(timenum!=40); timestart(); r=0; f++; break; } } } if(r!=0&&key!=' ') { cal[6]=keyboard(key); write_com(0x80+0x06); write_data('0'+(cal[6]-'0')); } } key=' '; if(r==0)continue; if(cal[7]==' ') { while(key==' ') { key=keyscan(); if(!r)break; if(limittime>3&&(limittime-t-'0')<3){ if(timenum==(limittime-'0')*20) { timenum=0; write_exact(11,0x40,result3); while(timenum!=40); timestart(); r=0; f++; break; } }else{ if(timenum==(limittime-t-'0')*20) { timenum=0; write_exact(11,0x40,result3); while(timenum!=40); timestart(); r=0; f++; break; } } } if(r!=0&&key!=' ') { cal[7]=keyboard(key); write_com(0x80+0x07); write_data('0'+(cal[7]-'0')); } } key=' '; if(r==0)continue; if(cal[8]==' ') { while(key==' ') { key=keyscan(); if(!r)break; if(limittime>3&&(limittime-t-'0')<3){ if(timenum==(limittime-'0')*20) { timenum=0; write_exact(11,0x40,result3); while(timenum!=40); timestart(); r=0; f++; break; } }else{ if(timenum==(limittime-t-'0')*20) { timenum=0; write_exact(11,0x40,result3); while(timenum!=40); timestart(); r=0; f++; break; } } } if(r!=0&&key!=' ') { cal[8]=keyboard(key); write_com(0x80+0x08); write_data('0'+(cal[8]-'0')); } }//完成输入 if(r) //未超时,开始判断正误 { timestart(); if(answer<=-10) { if(cal[6]=='-'&&((cal[7]-'0')*10+(cal[8]-'0'))==-answer){write_exact(8,0x40,result1);t++;while(timenum!=40);} else{write_exact(9,0x40,result2);f++;while(timenum!=40);} } else if(answer<0&&answer>-10) { if(cal[6]=='-'&&(cal[7]-'0')==-answer){write_exact(8,0x40,result1);t++;while(timenum!=40);} else{write_exact(9,0x40,result2);f++;while(timenum!=40);} } else if(answer>=0&&answer<10) { if((cal[6]-'0')==answer){write_exact(8,0x40,result1);t++;while(timenum!=40);} else{write_exact(9,0x40,result2);f++;while(timenum!=40);} } else if(answer>=10&&answer<=99) { if(((cal[6]-'0')*10+(cal[7]-'0'))==answer){write_exact(8,0x40,result1);t++;while(timenum!=40);} else{write_exact(9,0x40,result2);f++;while(timenum!=40);} } else if(answer>=100) { if((cal[6]-'0')*100+(cal[7]-'0')*10+(cal[8]-'0')==answer){write_exact(8,0x40,result1);t++;while(timenum!=40);} else{write_exact(9,0x40,result2);f++;while(timenum!=40);} } } } } if(key==5) //开机键,模式为3位数 { lcdinit(); write_exact(11,0x00,mode2); timeinit(); limittime=' '; while(limittime==' ') //时间限制 {key=keyscan();limittime=keyboard(key);} while(1) { lcdinit(); if(f==5){write_exact(9,0x00,over21);write_exact(3,0x40,over22);timestart();while(timenum!=40);break;} if(t==5){write_exact(10,0x00,over11);write_exact(16,0x40,over12);timestart();while(timenum!=40);break;} r=1; key=' '; cal[8]=' '; cal[9]=' '; cal[10]=' '; cal[11]=' '; for(n=0;n<7;n++) { if(n==3) //随机加减号 { if((p-'0')%2) cal[n]='+'; else cal[n]='-'; } else if(n==0||n==4) //保证百位数不为0 { srand((p-'0')+n); cal[n]='1'+rand()%8; } else { srand((p-'0')+2*n); cal[n]='0'+rand()%9; } } cal[7]='='; if(cal[3]=='+') answer=(cal[0]-'0')*100+(cal[1]-'0')*10+(cal[2]-'0')+(cal[4]-'0')*100+(cal[5]-'0')*10+(cal[6]-'0'); //算出正确答案 else if(cal[3]=='-') answer=(cal[0]-'0')*100+(cal[1]-'0')*10+(cal[3]-'0')-(cal[4]-'0')*100-(cal[5]-'0')*10-(cal[6]-'0'); if((answer<0&&answer>-10)||(answer>=10&&answer<=99)) //判断位数 {cal[10]=0;cal[11]=0;} //置为0后下面代码的while判断就可以跳过 else if(answer>=0&&answer<10) {cal[9]=0;cal[10]=0;cal[11]=0;} else if((answer>=100&&answer<1000)||(answer>-100&&answer<=-10)) {cal[11]=0;} write_exact(8,0x00,cal); writetf(); timestart(); if(cal[8]==' ') //输入 { while(key==' ') { key=keyscan(); if(!r)break; if(limittime>3&&(limittime-t-'0')<3){ if(timenum==(limittime-'0')*20) { timenum=0; write_exact(11,0x40,result3); while(timenum!=40); timestart(); r=0; f++; break; } }else{ if(timenum==(limittime-t-'0')*20) { timenum=0; write_exact(11,0x40,result3); while(timenum!=40); timestart(); r=0; f++; break; } } } if(r!=0&&key!=' ') { cal[8]=keyboard(key); write_com(0x80+0x08); write_data('0'+(cal[8]-'0')); } } key=' '; if(r==0)continue; if(cal[9]==' ') { while(key==' ') { key=keyscan(); if(!r)break; if(limittime>3&&(limittime-t-'0')<3){ if(timenum==(limittime-'0')*20) { timenum=0; write_exact(11,0x40,result3); while(timenum!=40); timestart(); r=0; f++; break; } }else{ if(timenum==(limittime-t-'0')*20) { timenum=0; write_exact(11,0x40,result3); while(timenum!=40); timestart(); r=0; f++; break; } } } if(r!=0&&key!=' ') { cal[9]=keyboard(key); write_com(0x80+0x09); write_data('0'+(cal[9]-'0')); } } key=' '; if(r==0)continue; if(cal[10]==' ') { while(key==' ') { key=keyscan(); if(!r)break; if(limittime>3&&(limittime-t-'0')<3){ if(timenum==(limittime-'0')*20) { timenum=0; write_exact(11,0x40,result3); while(timenum!=40); timestart(); r=0; f++; break; } }else{ if(timenum==(limittime-t-'0')*20) { timenum=0; write_exact(11,0x40,result3); while(timenum!=40); timestart(); r=0; f++; break; } } } if(r!=0&&key!=' ') { cal[10]=keyboard(key); write_com(0x80+0x0A); write_data('0'+(cal[10]-'0')); } } key=' '; if(r==0)continue; if(cal[11]==' ') { while(key==' ') { key=keyscan(); if(!r)break; if(limittime>3&&(limittime-t-'0')<3){ if(timenum==(limittime-'0')*20) { timenum=0; write_exact(11,0x40,result3); while(timenum!=40); timestart(); r=0; f++; break; } }else{ if(timenum==(limittime-t-'0')*20) { timenum=0; write_exact(11,0x40,result3); while(timenum!=40); timestart(); r=0; f++; break; } } } if(r!=0&&key!=' ') { cal[11]=keyboard(key); write_com(0x80+0x0B); write_data('0'+(cal[11]-'0')); } }//完成输入 if(r) //未超时,开始判断正误 { timestart(); if(answer<=-100) { if(cal[8]=='-'&&((cal[9]-'0')*100+(cal[10]-'0')*10+(cal[11]-'0'))==-answer){write_exact(8,0x40,result1);t++;while(timenum!=40);} else{write_exact(9,0x40,result2);f++;while(timenum!=40);} } else if(answer<=-10&&answer>-100) { if(cal[8]=='-'&&((cal[9]-'0')*10+(cal[10]-'0'))==-answer){write_exact(8,0x40,result1);t++;while(timenum!=40);} else{write_exact(9,0x40,result2);f++;while(timenum!=40);} } else if(answer<0&&answer>-10) { if(cal[8]=='-'&&(cal[9]-'0')==-answer){write_exact(8,0x40,result1);t++;while(timenum!=40);} else{write_exact(9,0x40,result2);f++;while(timenum!=40);} } else if(answer>=0&&answer<=9) { if((cal[8])==answer){write_exact(8,0x40,result1);t++;while(timenum!=40);} else{write_exact(9,0x40,result2);f++;while(timenum!=40);} } else if(answer>=10&&answer<100) { if((cal[8]-'0')*10+(cal[9]-'0')==answer){write_exact(8,0x40,result1);t++;while(timenum!=40);} else{write_exact(9,0x40,result2);f++;while(timenum!=40);} } else if(answer>=100&&answer<1000) { if((cal[8]-'0')*100+(cal[9]-'0')*10+(cal[10]-'0')==answer){write_exact(8,0x40,result1);t++;while(timenum!=40);} else{write_exact(9,0x40,result2);f++;while(timenum!=40);} } else if(answer>=1000) { if((cal[8]-'0')*1000+(cal[9]-'0')*100+(cal[10]-'0')*10+(cal[11]-'0')==answer){write_exact(8,0x40,result1);t++;while(timenum!=40);} else{write_exact(9,0x40,result2);f++;while(timenum!=40);} } } } } } } void Time0()interrupt 1 { TH0=(65536-50000)/256; TL1=(65536-50000)%256; timenum++; p++;if(p==100)p++; }

    3.说明

    本题出自 电子科技大学 2018/12 CIE训练赛。


    随机算式包括随机两位数算式和随机三位数算式 ↩︎

    最新回复(0)