系统能实现的功能:
本系统抢答器能实现如下功能:
①、由主持人控制答题开始,通过一个总的控制按钮,并且蜂鸣器 发声提示。再次按下时可以对单片机进行复位。
②、同时主持人按钮控制着30S的抢答倒计时,当时间到仍没有人抢答时,蜂鸣器发声报警,同时屏幕显示无人抢答,等待主持人按键复位,进行下一轮抢答 ③、当有一个抢答按钮被按下后,单片机进行锁存,屏蔽其他选手号,此时蜂鸣器报警提示,并进入答题倒计时30S,若超时,则蜂鸣器报警,屏幕显示答题超时,此时等待主持人复位。
六、主要程序
/*======================================================= 主函数
=======================================================*/ void main(void) {
system_init();//系统初始化 // IP = 0x20; while(1) {
seg_change();//转换显示的内容 key_handle();//键盘处理函数 switch(SPK_Flag) {
case SPK_NO: break;
case SPK_MUSIC: SpkMusic(); break; //播放音乐1 case SPK_ALARM: SpkAlarm(); break; } } }
/*======================================================= 系统初始化函数
=======================================================*/ void system_init(void) {
//定时器0 初始化 定时时间2ms TMOD = 0x01;
TH0 = 0x3c; //50微妙 TL0 = 0xb0;
EA = 1;
ET0 = 1; TR0 = 1;
SEG_RAM[0]=SEG_no; //这位不显示 有人抢答时,s显示抢答选手号 或则 无人抢答时 显示 F
SEG_RAM[1]=SEG_no; SEG_RAM[2]=SEG_no; SEG_RAM[3]=SEG_no;
SEG_RAM[4]=SEG_no;//初始化记分器分数 SEG_RAM[5]=SEG_no; SEG_RAM[6]=SEG_no;
SEG_RAM[7]=SEG_0;//始终显示0 }
/*======================================================= 键盘扫描函数
=======================================================*/ unsigned char key_scan(void) {
unsigned char keyvalue=NO_KEY; if(KEY_PORT != 0xff) {
delay();delay();delay();delay(); delay();delay();delay();delay(); delay();delay();delay();delay(); delay();delay();delay();delay(); switch (KEY_PORT) {
case 0xff: break;//无键按下 case 0xfe: keyvalue = PLAYER_1; break; case 0xfd: keyvalue = PLAYER_5; break; case 0xfb: keyvalue = PLAYER_2; break; case 0xf7: keyvalue = RST_KEY; break; case 0xef: keyvalue = PLAYER_3; break; case 0xdf: keyvalue = ADD_KEY; break; case 0xbf: keyvalue = PLAYER_4; break; case 0x7f: keyvalue = UP_KEY; break; }
while(KEY_PORT != 0xff);//松手检测 }
return (keyvalue);
}
/*======================================================= 键盘处理函数
=======================================================*/ void key_handle(void) {
unsigned char keytemp; keytemp = key_scan(); switch(keytemp) {
case NO_KEY: break;
case PLAYER_1: case PLAYER_2: case PLAYER_3: case PLAYER_4: case PLAYER_5:
if(QD_Flag==QD_GO) {
QD_Flag = QD_OK; //切换到抢答成功状态 SEG_RAM[0] = table_duan[keytemp+1]; //第一个数码管显示抢答选手号
QD_show_num = keytemp;
SPK_Flag = SPK_MUSIC; //蜂鸣器 播放音乐 }
break; case RST_KEY:
QD_Flag = QD_GO; SPK_Flag = SPK_NO; QD_timectr=100;
SEG_RAM[0] = SEG_no; break; case ADD_KEY:
JFQ_ctr[QD_show_num]++; //对应选手 记分器 加分 break; case UP_KEY:
QD_show_num++;
if(QD_show_num==5)QD_show_num=0;
SEG_RAM[0] = table_duan[QD_show_num+1];
break; } }
/*======================================================= 定时器0中断服务程序
=======================================================*/ void Timer0_ISR(void) interrupt 1 {
static unsigned char t0_2ms_counter = 0,tt; //50毫秒计数器 ET2=0;
TL0 = 0x30; //2ms TH0 = 0xf8;
t0_2ms_counter++;
seg_display(); //2毫秒 扫描数码管 if(t0_2ms_counter==250) //500ms / 2ms = 250 { //0.5s到 if(QD_timectr==0)
{ //抢答时间到,无人抢答,切换到抢答失败状态 QD_Flag = QD_NO;
tt++;
if(tt==1)SPK_Flag = SPK_ALARM; //蜂鸣器 播放报警音 else SPK_Flag = SPK_NO; }
if(QD_Flag==QD_GO) QD_timectr-=5; //在抢答倒计时期间 倒计时减0.5
}
ET2=1; }
/*======================================================= 数码管显示函数
=======================================================*/ void seg_display(void) {
static unsigned char i=0; LED_WEI = table_wei[i]; LED_DUAN = SEG_RAM[i]; i++;
if(i》7) i=0; }
/*======================================================= 数码管显示转换函数
=======================================================*/ void seg_change(void) {
if (QD_timectr《100) //取值为0~100
SEG_RAM[1]= SEG_no; //最高位为0则不显示 else
SEG_RAM[1]= SEG_1; //最高位显示1 SEG_RAM[2] = table_duandot[QD_timectr%100/10]; SEG_RAM[3] = table_duan[QD_timectr%10];
if(QD_Flag==2) SEG_RAM[0] = SEG_F; //显示‘F’ 无人抢答 if(JFQ_ctr[QD_show_num]》=100) {
SEG_RAM[4]=table_duan[JFQ_ctr[QD_show_num]/100];
SEG_RAM[5]=table_duan[JFQ_ctr[QD_show_num]%100/10]; SEG_RAM[6]=table_duan[JFQ_ctr[QD_show_num]%10]; }
else if (JFQ_ctr[QD_show_num]《100 && JFQ_ctr[QD_show_num]》=10) {
SEG_RAM[4]=SEG_no;//不显示0
SEG_RAM[5]=table_duan[JFQ_ctr[QD_show_num]%100/10]; SEG_RAM[6]=table_duan[JFQ_ctr[QD_show_num]%10]; }
else if (JFQ_ctr[QD_show_num]《10 && JFQ_ctr[QD_show_num]》0) {
SEG_RAM[4]=SEG_no;//不显示0 SEG_RAM[5]=SEG_no;//不显示0
SEG_RAM[6]=table_duan[JFQ_ctr[QD_show_num]%10]; } else {
SEG_RAM[4]=SEG_no;//不显示0 SEG_RAM[5]=SEG_no;//不显示0 SEG_RAM[6]=SEG_no;//不显示0 } }
/*======================================================= 延时函数(延时1毫秒)
=======================================================*/
void delay(void) //延时1MS {
unsigned char a,b; for(b=102;b》0;b--) for(a=3;a》0;a--); }
/*======================================================== 播放音乐 和 报警声音
=======================================================*/ unsigned int g_ucSoundLongCNT; //
/************************************************* * 函数名称:void T2Init(void) * 创建日期:2005.6.17
* 功能描述:定时器T2初始化 * 入口参数:uT2Reg:定时器初值 * 返回值: 无 * 修改日志:
*************************************************/ void T2Init(unsigned int uT2Reg) {
CP_RL2=0; //16位自动重载
T2MOD=0x00; //计数增加,外部捕获禁止 RCLK=0; TCLK=0;
TL2=RCAP2L=uT2Reg&0x00ff; TH2=RCAP2H=uT2Reg》》8;
TR2=1; // 启动定时器 ET2=1; //t2开中断 EA=1; }
/************************************************* * 函数名称:void MusicPlay(uchar ucSL[],uint uST[]) * 创建日期:2005.7.12
* 功能描述:播放某首音乐的函数
* 入口参数:ucSL[]:音节长度的数组;uST[]:音乐频率的数组 * 返回值: 无 * 修改日志:
*************************************************/
void MusicPlay(unsigned char ucSL[],unsigned int uST[])
{
unsigned char i=0; //float fTmp=“0”;
while((ucSL[i]!=0)||(uST[i]!=0)) {
//fTmp=(float)11059/(float)12000;
T2Init(0xffff-uST[i]*((float)11059/(float)12000)*4); //11。0592M的晶体 //我添加了*5
g_ucSoundLongCNT=((3*ucSL[i]*75000L)/8)/uST[i]; //*1000我改为 75000
while(g_ucSoundLongCNT!=0); //等待计数器为0 TR2=0; //暂时关闭定时器 i++; }
BUZZER = 1; }
/************************************************* * 函数名称:void T2Init(void) * 创建日期:2005.7.11
* 功能描述:用于音乐的音调半周期定时 * 入口参数:无 * 返回值: 无 * 修改日志:
*************************************************/ void T2ISR(void) interrupt 5 using 1 {
TF2=0; //手动清除溢出标志 if(g_ucSoundLongCNT!=0) {
g_ucSoundLongCNT--; }
BUZZER=~BUZZER; }
评论
查看更多