黄河科技学院毕业设计说明书 第 26 页
模式
{// 数码管显示“FFFF”
dig[0]=ShowDig[15]; dig[1]=ShowDig[15]; dig[2]=ShowDig[15]; dig[3]=ShowDig[15]; while(!k2);// 等待按键释放 DelayMs(500);// 利用延时去抖
dig[1]=ShowDig[17]; // 数码管显示“F FF”
dig[2]=ShowDig[gAnswerTime/10];// 数码管显示“F 15” (15就是要设置答题时dig[3]=ShowDig[gAnswerTime];
while(k2)// 当再次按下按键2时,退出抢答时间设置模式,否则一直扫描“加”、{
间,15只是个例子,具体数字视具体情况而定)
“减”按键
if(k8==0) { }
if(k7==0)// 判断“减”按键是否被按下 {
DelayMs(250);// 利用延时去抖
gAnswerTime--;// 当前要设置的秒数自减1
if(gAnswerTime==-1) // 当自减到-1时,自动变成99
gAnswerTime=99; DelayMs(250);// 利用延时去抖
gAnswerTime++;// 当前要设置的秒数自加1
if(gAnswerTime==100) // 当自加到100时,自动清零
gAnswerTime=0;
// 擦除内部EEPROM(写入之前必须先擦除)
Sector_Erase(0x2000);
Byte_Program(0x2000,gWaitTime);// 将等待时间写入到内部EEPROMByte_Program(0x2001,gAnswerTime); // 将新设置的答题时间写入到dig[2]=ShowDig[gAnswerTime/10];// 更新数码管的秒数显式(十位) dig[3]=ShowDig[gAnswerTime];// 更新数码管的秒数显式(个位)
的0x2000这个地址
内部EEPROM的0x2001这个地址
黄河科技学院毕业设计说明书 第 27 页
}
Sector_Erase(0x2000);// 擦除内部EEPROM(写入之前必须先擦除) }
Byte_Program(0x2000,gWaitTime);// 将等待时间写入到内部EEPROMByte_Program(0x2001,gAnswerTime); // 将新设置的答题时间写入到内dig[2]=ShowDig[gAnswerTime/10];// 更新数码管的秒数显式(十位) dig[3]=ShowDig[gAnswerTime];// 更新数码管的秒数显式(个位)
的0x2000这个地址
部EEPROM的0x2001这个地址
while(!k2);// 等待按键释放 DelayMs(500);// 利用延时去抖
}
}
uchar KeyScanf(void) {
if(k1==0)// 选手1按下,返回1
return 1; return 2; return 3; return 4; return 5; return 6; return 7; return 8;
if(k2==0)// 选手2按下,返回2 if(k3==0)// 选手3按下,返回3 if(k4==0)// 选手4按下,返回4 if(k5==0)// 选手5按下,返回5 if(k6==0)// 选手6按下,返回6 if(k7==0)// 选手7按下,返回7 if(k8==0)// 选手8按下,返回8 if(k9==0)// 开始抢答按键按下,返回9 return 9; return 0;
黄河科技学院毕业设计说明书 第 28 页
}
void main(void) {
uchar ret;// ret用于保存按键扫描程序的返回值 TimerInit();
// 新单片机下载程序请打开,因为EEPROM的内部数据读取出来是乱码,下载完第一次之后就可以注释掉这3行代码 // Sector_Erase(0x2000); // Byte_Program(0x2000,30); // Byte_Program(0x2001,15);
gWaitTime = Byte_Read(0x2000);// 读取EEPROM中设置温度上限的报警值,并gAnswerTime = Byte_Read(0x2001);// 读取EEPROM中设置温度下限的报警值,并WaitTimeSet();// 判断是否要进入等待时间设置模式 AnswerTimeSet();// 判断是否要进入答题时间设置模式 dig[0]=ShowDig[0];// 数码管显示“0000” dig[1]=ShowDig[0]; dig[2]=ShowDig[0]; dig[3]=ShowDig[0]; while(1) {
if(KeyScanf()!=0)// 当按键扫描程序的返回值不是0时,代表有按键被按下 {
ret=KeyScanf()
// 保存按键扫描程序的返回值
while(KeyScanf());// 等待按键释放 DelayMs(500);// 利用延时去抖 if(ret==9)// 如果是开始抢答按键被按下 {
TR1=1;// 启动定时器,即开始秒数的倒计时 dig[0]=ShowDig[17]; // 数码管显示“ 00” dig[1]=ShowDig[17];
gSecond=gWaitTime;// 此时,gSecond代表了具体有多少秒需要倒计时 while(!KeyScanf())// 如果一直没有人按键,则一直判断秒数是不是计到 {
赋给全局变量 赋给全局变量
0了
黄河科技学院毕业设计说明书 第 29 页
}
}
if(gSecond==0)// 如果计数到0了,数码管显示“----”,表示此轮抢{ } { }
答结束
dig[2]=ShowDig[16]; dig[3]=ShowDig[16];
else // 如果没有计到0,则数码管一直显示当前倒数的秒数
dig[2]=ShowDig[gSecond/10]; dig[3]=ShowDig[gSecond];
ret=KeyScanf();// 保存按键扫描程序的返回值
dig[0]=ShowDig[ret];// 数码管第一位显示抢到答题权限的选手的编号 dig[1]=ShowDig[16]; // 数码管第二位显示“-”
gSecond=gAnswerTime; // gSecond代表了答题的时间(之前是代表抢答while(1) // 一直判断秒数是不是计到0了 { }
if(gSecond==0)// 如果计数到0了,数码管显示“----”,表示此轮抢{ } { }
时间)
答结束
dig[2]=ShowDig[16]; dig[3]=ShowDig[16];
else// 如果没有计到0,则数码管一直显示当前倒数的秒数
dig[2]=ShowDig[gSecond/10]; dig[3]=ShowDig[gSecond];
else// 如果不是开始抢答按键被按下,说明是选手按键被按下,此时是违规{
dig[0]=ShowDig[ret];// 数码管第一位显示违规选手的编号
的提前抢答
黄河科技学院毕业设计说明书 第 30 页
dig[1]=ShowDig[16]; // 数码管第二位显示“-” dig[2]=ShowDig[12]; // 数码管第三位显示“C” dig[3]=ShowDig[12]; // 数码管第四位显示“C” bp=0; // 蜂鸣器报警
while(1);
} } } }
void TimerInt0(void) interrupt 1 {
TH0 = (65536-2000)/256;// 给定时器0的TH0装初值 TL0 = (65536-2000)%6;// 给定时器0的TL0装初值 P0=0xff;
if(w4==1)// 数码管第一位显示 { } { } { } {
w4=0; w1=1; P0=dig[0];
else if(w1==1)// 数码管第二位显示
w1=0; w2=1; P0=dig[1];
else if(w2==1)// 数码管第三位显示
w2=0; w3=1; P0=dig[2];
else// 数码管第四位显示
w3=0; w4=1;
黄河科技学院毕业设计说明书 第 31 页
P0=dig[3]; } }
void TimerInt1(void) interrupt 3 { }
TH1 = (65536-50000)/256;// 给定时器1的TL1装初值 TL1 = (65536-50000)%6;// 给定时器1的TH1装初值 gCount++;// gCount每自加1,说明时间经过了50毫米 if(gCount==5)// 5代表250毫米 { } { }
gCount=0;// 将gCount清零,进入下一秒的计时 gSecond--;// 秒数自减1
if((gSecond<6)&&(gSecond>0))// 当剩最后5秒时,进入这个if语句的代码 { } { }
TR1=0;// 停止定时器 bp=0;// 蜂鸣器响
dig[0]=ShowDig[16]; // 数码管显示“----” dig[1]=ShowDig[16]; dig[2]=ShowDig[16]; dig[3]=ShowDig[16]; bp=0; bp=1;
if(gCount==20)// 20代表计数了1秒
if(gSecond==0)// 当计数到0时