<>数字抢答器课程设计C语言
设计要求:
(1)抢答器同时供10名选手或10个代表队比赛。
(2)设置一个系统清除和抢答控制开关S,该开关由主持人控制。
(3)抢答器具有锁存与显示功能。即选手按动按钮,锁存相应的编号,并在LED数码管上显示,同时扬声器发出报警声响提示。选手抢答实行优先锁存,优先抢答选手的编号一直保持到主持人将系统清除为止。
(4)抢答器具有定时抢答功能,且一次抢答的时间由主持人设定(如20s)。当主持人启动“开始”键后,定时器进行减计时,同时扬声器发出短暂的声响,声响持续的时间0.5s左右。
(5)参赛选手在设定的时间内进行抢答,抢答有效,定时器停止工作,显示器上显示选手的编号和抢答的时间,并保持到主持人将系统清除为止。
(6)如果定时时间已到,无人抢答,本次抢答无效,系统报警并禁止抢答,定时显示器上显示00。
单片机型号:STC15F2K60S2单片机
程序重要包含四个部分:主程序,延时子程序,主持人按键子程序,选手按键子程序,数码管显示子程序
#include <stc15f2k60s2.h> sbit KEY0 = P3 ^4;//设置抢答时间 sbit KEY1 = P3 ^ 5;//开始
sbit KEY2= P3 ^ 6;//清除 sbit fqm = P5 ^ 4;//蜂鸣器 sbit K9 = P4 ^ 4;//选手 sbit K10 =
P4^ 2; unsigned char sbufNum[8] = {0}; //共阴 //unsigned char code Semg[] =
{0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39,
0x5e, 0x79, 0x71}; unsigned char code Semg[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99,
0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e}; unsigned char
key_new= 0; unsigned char key_can; unsigned int Mil=0; unsigned char second,
setSecond= 00;//倒计时时间 unsigned char SegCnt = 0; unsigned char state = 0, flagrun
= 0; #define DELAY 200 void DelaymsKey(int x)//按键毫秒延时函数 { int i, j; for (j = 0;
j< x; j++) { for (i = 0; i < 122; i++) } } //选手按键显示部分 void KeyScan(void) {
unsigned char temp = 0; if ((P2 != 0XFF) || (K9 == 0) || (K10 == 0) || (KEY0 ==
0) || (KEY1 == 0) || (KEY2 == 0)) // { DelaymsKey(10);//按键延时去抖 if (((P2 != 0XFF)
|| (K9 == 0) || (K10 == 0) || (KEY0 == 0) || (KEY1 == 0) || (KEY2 == 0)) && (
key_new== 1)) { key_new = 0; temp = P2;//选手接口 switch (temp) { case 0x7f: key_can
= 1;//赋值选手号码 break; case 0xbf: key_can = 2; break; case 0xdf: key_can = 3; break
; case 0xef: key_can = 4; break; case 0xf7: key_can = 5; break; case 0xfb:
key_can= 6; break; case 0xfd: key_can = 7; break; case 0xfe: key_can = 8; break;
} if (K9 == 0)//4.4接口单独赋值 key_can = 9; if (K10 == 0)//4.2接口单独赋值 key_can = 10; if
(KEY0 == 0)//设置抢答时间 key_can = 11; if (KEY1 == 0)//开始 key_can = 12; if (KEY2 == 0
)//清除 key_can = 13; } } else { key_new = 1; } } void Timer0Interrupt() interrupt
1 using 0 {//定时器中断 TH0 = (65536 - 5000) / 256; TL0 = (65536 - 5000) % 256; if (
Mil< DELAY) Mil++; else { Mil = 0; if (flagrun) { if (second > 0) { second--; }
} } SegCnt++; P2 = SegCnt % 8; P0 = Semg[sbufNum[SegCnt % 8]]; } //蜂鸣器持续时间 void
beepOut(int beeptime) { int i = 0, j; for (i = 0; i < beeptime; i++) { for (j =
0; j < 100; j++) fqm = ~fqm; } } void main(void) { unsigned char state = 0; P1M1
=0x00; P1M0=0xFF; TMOD = 0x01; //定时器0方式1 TH0 = (65536 - 5000) / 256; TL0 = (
65536 - 5000) % 256; TR0 = 1; ET0 = 1; IE0 = 1; IT0 = 1; EA = 1; beepOut(80);
//蜂鸣器响 while (1) { key_can = 0xff; KeyScan();//调用选手按键函数 switch (state) { case 0:
//设置抢答时间 if (key_can == 11) { if (setSecond < 30) setSecond++; else setSecond =
0; } //开始 if (key_can == 12) { flagrun = 1; second = setSecond; beepOut(250);
state= 1; } sbufNum[0] = setSecond / 10 % 10;//十位 sbufNum[1] = setSecond % 10;
//个位 sbufNum[2] = 0; sbufNum[3] = 0; break; case 1: sbufNum[0] = second / 10 %
10; sbufNum[1] = second % 10; //选手号码显示 if (key_can < 11) { if ((flagrun) && (
second> 0)) //抢答过程倒计时显示 { sbufNum[2] = key_can / 10 % 10;//十位 sbufNum[3] =
key_can% 10;//个位 flagrun = 0;//标志位清0 } } if ((flagrun == 0)&&(second==0))
//倒计时结束 { sbufNum[2] = 0; sbufNum[3] = 0; } //清除 if (key_can == 13) { flagrun =
0; second = setSecond; state = 0; } break; } } }
原理图采用AD绘制:
仿真图: