单片机源程序如下:
- #include<reg51.h>
- #define JZKEY P1
- #define GPIO_DIG P0
- sbit LSA=P2^2;
- sbit LSB=P2^3;
- sbit LSC=P2^4;
- sbit K1=P3^2;
- sbit K2=P3^3;
- sbit BEEP=P1^5;
- sbit LED1=P2^7;
- sbit LED2=P2^6;
- sbit LED3=P2^5;
- sbit LED4=P2^1;
- sbit LED5=P2^0;
- unsigned char code COMD_CODE[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
- //0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
- unsigned char COMD_Display[8];
- //用来存放要显示的8位数的值
- unsigned char k;
- unsigned char KeyValue;
- unsigned char flag=0;
- char Sec=10;
- char xuanshou=0;
- unsigned char Keyflag; //记录按键的状态,0没有,1有
- void Delay10ms(); //延时10ms
- void KeyDown(); //检测按键函数
- //--声明全局函数--//
- void DigDisplay(); //动态显示函数
- void Delay(unsigned int i) //无符号类型的int
- {
- char j;
- for(i; i > 0; i--)
- for(j = 200; j > 0; j--);
- }
- void Delay10ms2(unsigned int c) //误差 0us
- {
- unsigned char a,b;
- for(;c>0;c--)
- for(b=38;b>0;b--)
- for(a=130;a>0;a--);
- }
- void BZ1() //正确抢答蜂鸣器
- {
- unsigned int t;
- for(t=0;t<1000;t++)
- {
- BEEP= 1;
- Delay(10);
- BEEP= 0;
- Delay(10);
- }
- }
- void BZ2() //错误抢答蜂鸣器
- {
- unsigned int t;
- for(t=0;t<1000;t++)
- {
- BEEP= 1;
- Delay(10);
- BEEP= 0;
- Delay(10);
- }
- Delay10ms2(30);
- for(t=0;t<1000;t++)
- {
- BEEP= 1;
- Delay(10);
- BEEP= 0;
- Delay(10);
- }
- }
- void main(void)
- {
- unsigned char i=0;
- BEEP=1;
- Keyflag=0;
- TMOD=0x01; //定时器0方式1
- TH0=(65536-50000)/256; //定时器0:50ms
- TL0=(65536-50000)%256;
- TH1=(65536-50000)/256; //定时器0:50ms
- TL1=(65536-50000)%256;
- EA=1; //开启总中断
- ET1=1;TR1=1; //开启T1定时器 T1定时器允许中断
- while(1)
- {
- ET0=0;TR0=0;
- while(flag==0)
- {
- COMD_Display[0] = COMD_CODE[Sec/10%10];
- COMD_Display[1] = COMD_CODE[Sec%10];
- DigDisplay();
- if(K1==0)
- {
- flag=1;
- ET0=1;TR0=1;
- }
- if(K2==0)
- {
- Sec=10;
- COMD_Display[0] = COMD_CODE[Sec/10%10];
- COMD_Display[1] = COMD_CODE[Sec%10];
- flag=0;
- P2=0xff;
- xuanshou=0;
- }
- KeyDown();
- if(Keyflag==1)
- {
- if(KeyValue<5)
- {
- BZ2();
- COMD_Display[0]=COMD_CODE[(KeyValue+1)/10];
- COMD_Display[1]=COMD_CODE[(KeyValue+1)%10];
- xuanshou=(KeyValue+1);
- flag=3;
- }
- Keyflag=0;
- }
- }
- while(flag==1)
- {
- KeyDown();
- if(Keyflag==1)
- {
- Keyflag=0;
- if(KeyValue<5)
- {
- COMD_Display[0]=COMD_CODE[(KeyValue+1)/10];
- COMD_Display[1]=COMD_CODE[(KeyValue+1)%10];
- ET0=0;TR0=0;
- xuanshou=(KeyValue+1);
- flag=2;
- BZ1();
- }
- }
- DigDisplay();
- }
- ET0=0;TR0=0;
- while(flag==2)
- {
- if(K2==0)
- {
- Sec=10;
- COMD_Display[0] = COMD_CODE[Sec/10%10];
- COMD_Display[1] = COMD_CODE[Sec%10];
- flag=0;
- P2=0xff;
- xuanshou=0;
- }
- DigDisplay();
- }
- while(flag==3)
- {
- COMD_Display[0]=COMD_CODE[15];
- COMD_Display[1]=COMD_CODE[xuanshou];
- DigDisplay();
- if(K2==0)
- {
- Sec=10;
- COMD_Display[0] = COMD_CODE[Sec/10%10];
- COMD_Display[1] = COMD_CODE[Sec%10];
- flag=0;
- P2=0xff;
- xuanshou=0;
- Keyflag=0;
- }
- }
- }
- }
- void DigDisplay()
- {
- unsigned char i;
- unsigned int j;
- for(i=0;i<8;i++)
- {
- switch(7-i) //位选,选择点亮的数码管,
- {
- case(0):
- LSA=0;LSB=0;LSC=0; break;//显示第0位
- case(1):
- LSA=1;LSB=0;LSC=0; break;//显示第1位
- case(2):
- LSA=0;LSB=1;LSC=0; break;//显示第2位
- case(3):
- LSA=1;LSB=1;LSC=0; break;//显示第3位
- case(4):
- LSA=0;LSB=0;LSC=1; break;//显示第4位
- case(5):
- LSA=1;LSB=0;LSC=1; break;//显示第5位
- case(6):
- LSA=0;LSB=1;LSC=1; break;//显示第6位
- case(7):
- LSA=1;LSB=1;LSC=1; break;//显示第7位
- }
- GPIO_DIG=COMD_Display[i];//发送段码
- j=10; //扫描间隔时间设定
- while(j--);
- GPIO_DIG=0x00;//消隐
- }
- }
- void KeyDown(void)
- {
- JZKEY=0x0f;
- if(JZKEY!=0x0f)
- {
- Delay10ms();
- if(JZKEY!=0x0f)
- {
- Keyflag=1;//有按键按下
- //测试列
- JZKEY=0X0F;
- switch(JZKEY)
- {
- case(0X07): KeyValue=0;break;
- case(0X0b): KeyValue=1;break;
- case(0X0d): KeyValue=2;break;
- case(0X0e): KeyValue=3;break;
- }
- //测试行
- JZKEY=0XF0;
- Delay10ms();
- switch(JZKEY)
- {
- case(0X70): KeyValue=KeyValue;break;
- case(0Xb0): KeyValue=KeyValue+4;break;
- case(0Xd0): KeyValue=KeyValue+8;break;
- case(0Xe0): KeyValue=KeyValue+12;break;
- }
- while(JZKEY!=0xf0);
- }
- }
- }
- void Delay10ms(void)
- {
- unsigned char a,b,c;
- for(c=1;c>0;c--)
- for(b=38;b>0;b--)
- for(a=130;a>0;a--);
- }
- void Timer0() interrupt 1 //倒计时
- {
- unsigned char i;
- TH0=(65536-50000)/256; //恢复定时器0初值
- TL0=(65536-50000)%256;
- if(flag==1)
- i++;
- if(i>=20) //50ms*20=1s
- {
- i=0;
- Sec--;
- if(Sec==0)
- {
- ET0=0;TR0=0;
- BZ2();
- flag=2;
- }
- COMD_Display[0] = COMD_CODE[Sec/10%10];
- COMD_Display[1] = COMD_CODE[Sec%10];
- }
- }
- void Timer1() interrupt 3 //正确LED闪烁
- {
- TH1=(65536-50000)/256; //恢复定时器0初值
- TL1=(65536-50000)%256;
- k++;
- if(flag==2)
- {
- if(k>=200)
- {
- k=0;
- if(xuanshou==1)
- {
- LED1=!LED1;
- }
- if(xuanshou==2)
- {
- LED2=!LED2;
- }
- if(xuanshou==3)
- {
- LED3=!LED3;
- }
- if(xuanshou==4)
- {
- LED4=!LED4;
- }
- if(xuanshou==5)
- {
- LED5=!LED5;
- }
- }
- }
- if(flag==3) //错误抢答时的LED闪烁
- {
- if(k>=20)
- {
- k=0;
- if(xuanshou==1)
- {
- LED1=!LED1;
- }
- if(xuanshou==2)
- {
- LED2=!LED2;
- }
- if(xuanshou==3)
- {
- LED3=!LED3;
- }
- if(xuanshou==4)
- {
- LED4=!LED4;
- }
- if(xuanshou==5)
- {
- LED5=!LED5;
- }
- }
复制代码
|