附录A系统完整程序注:以下内容是直接复制写在Keil中的完整程序。//*******************程序开始******************////作用:数字抢答器//时间:2012.05//作者:林海/*项目要求:接通电源后,系统自动复位,无需手动按复位键。抢答器处于禁止状态,选手按抢答键无效,也不作提示。数码管显示030,主持人这时可以按动ADD键与DEC键设置抢答剩余时间;主持人接通START后,抢答器开始工作。扬声器给出声响提示。抢答时间开始减少,直到有选手抢答为止。选手在定时时间内抢答时,抢答器完成:优先判断、编号显示、扬声器提示。当一轮抢答之后,禁止二次抢答、数码管显示剩余时间。选手答题结束后,主持人按下RESET键,抢答器复位,方可进行下一轮的抢答。该数字抢答器的预期目标如下:1.抢答器同时供8名选手或8个代表队比赛,分别用8个按钮SW1~SW8表示。2.设置一个系统复位键RESET,一个系统开始键START,由主持人控制。3.抢答器可自动识别抢答成功的选手,并在LED数码管上显示该选手编号,同时蜂鸣器发出报警声响提示。选手抢答成功后其他选手不可抢答,及按下抢答键后无效。4.抢答器具有定时抢答功能,且一次抢答的时间由主持人设定(默认30秒)。当主持人启动START键后,中断程序开始计时。抢答时间开始减少。同时扬声器发出短暂的声响,声响持续的时间0.5秒。5.参赛选手在设定的时间内进行抢答,抢答有效,报警0.5秒,数码管上显示选手的编号和抢答的时间,并保持到主持人启动RESET复位键为止。6.如果定时时间已到,无人抢答,本次抢答无效,系统报警并禁止抢答,定时显示器上显示030。*/#includereg52.h#defineuintunsignedint#defineucharunsignedcharsbitSW1=P1^0;//******sbitSW2=P1^1;//*八*sbitSW3=P1^2;//*路*sbitSW4=P1^3;//*抢*sbitSW5=P1^4;//*答*sbitSW6=P1^5;//*按*sbitSW7=P1^6;//*钮*sbitSW8=P1^7;//******sbitSTART=P2^3;//开始;sbitRESET=P2^4;//复位;sbitADD=P2^5;//加一;sbitDEC=P2^6;//减一;sbitA=P2^7;//蜂鸣器;sbitH1=P2^0;//选手编号位baisbitH2=P2^1;//剩余时间十位shisbitH3=P2^2;//剩余时间个位ge/*显示部分:段选:P0.0~P0.6;7段位选:P2.0~P2.2;三位注:共阳极LED*/ucharcodetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,};//数码管显示字符定义对应0~9;voidkeyscan();//键盘扫描函数申明;voiddisplay();//显示函数申明voiddelay(uint);//延时函数申明voidFUWEI();//复位函数申明voidqushu();//拆分任意两位数uintinput=30;//默认剩余时间30秒;ucharge,shi,bai=0,n=1,m=0,t=0,temp;//定义变量;//***************************************************************////*********************主函数开始**************************////***************************************************************//voidmain(){TMOD=0x01;//设置定时器0为工作方式1.(M1M0为1)TH0=(65536-46080)/256;//装初值。11.0592M晶振定时50ms数为19456.TL0=(65536-46080)%256;//低位EA=1;//开启总中断。ET0=1;//开定时器0中断/*********中断服务子程序每结束一次都回到原来中断的地方这点***********/while(1)//主程序死循环,保证抢答器一直运行下去{keyscan();//*************************qushu();//****依次扫描此3个函数***display();//*************************}}//系统复位函数voidFUWEI(){TR0=0;//关定时器TH0=(65536-46080)/256;//重装初值。TL0=(65536-46080)%256;//低8位t=0;//中断函数计数清零A=0;//***********delay(500);//报警500毫秒A=1;//***********bai=0;//选手编号清零input=30;//设置剩余时间}//系统显示函数voiddisplay(){H1=0;//**************************************P0=table[bai];//*********选手编号显示*************delay(1);//**************************************H1=1;//关一位数码管,保证选手编号位不被干扰**H2=0;//**************************************P0=table[shi];//*********剩余时间十位显示*********delay(1);//**************************************H2=1;//*********关二位数码管*************H3=0;//**************************************P0=table[ge];//*********剩余时间个位显示*********delay(1);//**************************************H3=1;//*********关三位数码管*************}//拆分任意两位数函数voidqushu(){shi=input/10;//取整ge=input%10;//取余}//键盘扫描函数voidkeyscan(){//复位操作,无论何时,都可以复位,节省时间if(RESET==0){delay(200);//延时200毫秒,防止按键机械振动引起的误差FUWEI();//系统复位n=1;//复位后开启主持人其他权限}//n为1时,表示还没开始抢答,可以操作if(n)if(START==0)//开始抢答需要自锁{A=0;//*************delay(500);//报警500毫秒*A=1;//*************TR0=1;//开定时器m=1;//开启选手抢答权限n=0;//自锁,有效防止在选手答题时主持人误操作。}//调整时间函数,抢答前可操作。if(n){if(ADD==0){delay(200);//防止按键抖动重复加一input++;//时间加一}if(DEC==0){delay(200);input--;//时间减一}}//主持人启动START按钮后,开始检查选手按钮。if(m){if(P1!=0xFF)//如果有选手抢答,则找出他的编号{temp=P1;m=0;//自锁,此后不再检测选手抢答键,直到主持人启动START.switch(temp){case0xFE:bai=1;//一号选手答题break;case0xFD:bai=2;//二号选手答题break;case0xFB:bai=3;//三号选手答题break;case0xF7:bai=4;//四号选手答题break;case0xEF:bai=5;//五号选手答题break;case0xDF:bai=6;//六号选手答题break;case0xBF:bai=7;//七号选手答题break;case0x7F:bai=8;//八号选手答题break;}TR0=0;//关定时器,剩余时间不再减少,显示剩余时间}}}//中断方式一服务程序。voidtimer()interrupt1{TH0=(65536-46080)/256;//重装初值。TL0=(65536-46080)%256;t++;//每累加一次,判断是否到20.if(t==20)//如果到了20次,说明1秒时间到。{t=0;//然后把t清零重新再记20次。input--;//减一秒if(input==0)//如果没人回答,自动复位;FUWEI();//系统复位qushu();//刷新显示}}//延时函数,利用系统计算时间延时,不占用计时器。voiddelay(uintz){uintx,y;for(x=100;x0;x--)for(y=z;y0;y--);}