|
这是我自己花了好久,查了很多资料做的八位抢答器,其他功能现已全部实现,但是关于液晶屏显示方面,依然有些问题。
我用液晶屏做了一个分数显示器,一开始八个选手都是零分时显示没有问题,但是我在抢答结束后进行加减分操作后,显示就出现了问题,检查了很多地方都不知道哪儿出现了问题,希望有大佬看到帮忙解答一下,万分感谢!!源程序实在过长,都放在附件里了,麻烦了。
单片机源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- void delay(uint z) //1ms延时
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //编码表1-F和-
- 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};
- uchar code tablewei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//各位灯亮
- const uchar code ZF_tab[] =
- {
- 0xF8,0xFC,0x04,0xC4,0x24,0xFC,0xF8,0x00, // -0-
- 0x07,0x0F,0x09,0x08,0x08,0x0F,0x07,0x00,
- 0x00,0x10,0x18,0xFC,0xFC,0x00,0x00,0x00, // -1-
- 0x00,0x08,0x08,0x0F,0x0F,0x08,0x08,0x00,
- 0x08,0x0C,0x84,0xC4,0x64,0x3C,0x18,0x00, // -2-
- 0x0E,0x0F,0x09,0x08,0x08,0x0C,0x0C,0x00,
- 0x08,0x0C,0x44,0x44,0x44,0xFC,0xB8,0x00, // -3-
- 0x04,0x0C,0x08,0x08,0x08,0x0F,0x07,0x00,
- 0xC0,0xE0,0xB0,0x98,0xFC,0xFC,0x80,0x00, // -4-
- 0x00,0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,
- 0x7C,0x7C,0x44,0x44,0xC4,0xC4,0x84,0x00, // -5-
- 0x04,0x0C,0x08,0x08,0x08,0x0F,0x07,0x00,
- 0xF0,0xF8,0x4C,0x44,0x44,0xC0,0x80,0x00, // -6-
- 0x07,0x0F,0x08,0x08,0x08,0x0F,0x07,0x00,
- 0x0C,0x0C,0x04,0x84,0xC4,0x7C,0x3C,0x00, // -7-
- 0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,
- 0xB8,0xFC,0x44,0x44,0x44,0xFC,0xB8,0x00, // -8-
- 0x07,0x0F,0x08,0x08,0x08,0x0F,0x07,0x00,
- 0x38,0x7C,0x44,0x44,0x44,0xFC,0xF8,0x00, // -9-
- 0x00,0x08,0x08,0x08,0x0C,0x07,0x03,0x00,
- };
- sbit beep=P2^3;//蜂鸣器
- sbit deng=P2^5;//灯锁存
- sbit duan=P2^6;//段锁存
- sbit wei=P2^7;//位锁存
- sbit key1=P1^0;//八个选手
- sbit key2=P1^1;
- sbit key3=P1^2;
- sbit key4=P1^3;
- sbit key5=P1^4;
- sbit key6=P1^5;
- sbit key7=P1^6;
- sbit key8=P1^7;
- sbit keyks=P2^0;//开始
- sbit keyjia=P2^1;//加
- sbit keyjian=P2^2;//减
- sbit keyfw=P2^4;//复位
- sbit keysz=P3^0;//设置,按一次设置抢答时间,按两次设置答题时间,按三次返回
- sbit keyqc=P3^1;//清除积分
- sbit ye=P3^2;//液晶锁存
- sbit Reset = P3^3; //复位
- sbit RS = P3^5; //指令数据选择
- sbit E = P3^4; //指令数据控制
- sbit CS1 = P3^6; //左屏幕选择,低电平有效
- sbit CS2 = P3^7; //右屏幕选择
- uchar *ZF; //数据指针,ZF为首地址
- uchar d,x,y;
- uchar num;//选手编号
- uchar t0,t1,t2,t3,t4,s3;//定时器时间
- uchar dtds,dtds1;//答题定时,设置答题定时
- uchar ds,ds1;//抢答定时,设置抢答定时
- uchar kaif;//开始标记,0表示未开始,1表示开始
- uchar wanf;//抢答完成标记,0表示未完成,1表示完成
- uchar daf;//开始答题标记,0表示未开始答题,1表示3s倒计时,2表示开始答题倒计时
- uchar setf;//设置标记,0表示未在设置中,1表示正在设置抢答定时,2表示正在设置答题定时
- uchar temp;//流水灯
- uchar q;//8人按键选择
- uchar fen;//分数的中间量
- uchar fen1;//八个选手的分数
- uchar fen2;
- uchar fen3;
- uchar fen4;
- uchar fen5;
- uchar fen6;
- uchar fen7;
- uchar fen8;
- uchar f1,f2,f3,f4,f5,f6,f7,f8;
- void init() //初始化子程序
- {
- deng=0;//关灯锁存
- duan=0;//关段锁存
- wei=0;//关位锁存
- beep=1;//关蜂鸣器
- keyks=1;//开始按键置1
- keyfw=1;//复位按键置1
- keyjia=1;//加时间按键置1
- keyjian=1;//减时间按键置1
- P1=0xff;//P1口置1
- dtds=dtds1;//设置答题时间
- ds=ds1;//设置抢答时间
- temp=0xfe;
- t0=0;
- t1=0;
- t2=0;
- t3=0;
- t4=0;
- s3=3;
- kaif=0;//开始标记置0
- wanf=0;//抢答完成标记置0
- daf=0;//答题标记置0
- setf=0;//设置标记置0
- TMOD=0x11;//设置定时器0为方式1
- TH0=(65536-50000)/256;//设置50ms
- TL0=(65536-50000)%256;
- EA=1;//开总中断
- ET0=1;//开定时器0中断
- TR0=0;//启动定时器0
- TH1=(65536-50000)/256;//设置50ms
- TL1=(65536-50000)%256;
- ET1=1;//开定时器1中断
- TR1=1;//启动定时器1
- }
- void Time0() interrupt 1 //定时器0中断
- {
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- if(daf==0)//未开始答题,显示抢答倒计时
- {
- t0++;
- if(t0==20)//1s计时
- {t0=0;ds--;}
- }
- if(daf==1)//开始答题之前的3秒倒计时
- {
- t2++;
- if(t2==20)
- {
- t2=0;
- s3--;
- if(s3==0)
- {
- beep=0;
- delay(100);
- beep=1;
- daf=2;
- }
- }
- }
- if(daf==2)//开始答题倒计时
- {
- t3++;
- if(t3==20)
- {t3=0;dtds--;}
- }
- if(ds<=6||dtds<=6)//5秒内蜂鸣器报警
- {
- t4++;
- if(t4==20)
- {
- t4=0;
- beep=0;
- delay(100);
- beep=1;
- }
- }
- if(ds==0||dtds==0)//计时到0,关闭定时器
- {
- wanf=1;
- beep=0;
- delay(5);
- TR0=0;
- }
- }
- void Time1() interrupt 3 //定时器1中断
- {
- TH1=(65536-50000)/256;
- TL1=(65536-50000)%256;
- t1++;
- if(t1==10)//1s计时
- {t1=0;temp=_crol_(temp,1);}//流水灯循环左移
- }
- void liushui() //流水灯
- {
- P0=temp;//灯亮
- deng=1;
- deng=0;
-
- P0=0xfe;
- wei=1;
- wei=0;
- }
- void chushi() //数码管初始化 显示四个-
- {
- P0=table[16];//第一位显示-
- duan=1;
- duan=0;
- delay(5);
-
- P0=0xfd;
- wei=1;
- wei=0;
- P0=table[16];//第二位显示-
- duan=1;
- duan=0;
- delay(5);
-
- P0=0xfb;
- wei=1;
- wei=0;
- P0=table[16];//第三位显示-
- duan=1;
- duan=0;
- delay(5);
-
- P0=0xf7;
- wei=1;
- wei=0;
- P0=table[16];//第四位显示-
- duan=1;
- duan=0;
- delay(5);
- }
- void shuzi(uchar a,uchar b) //数码管时间号码显示
- {
- uchar shi,ge;
- shi=a/10;
- ge=a%10;
-
- P0=0xfe;
- wei=1;
- wei=0;
-
- P0=table[shi];//第一位显示十位
- duan=1;
- duan=0;
- delay(5);
-
- P0=0xfd;
- wei=1;
- wei=0;
- P0=table[ge];//第二位显示各位
- duan=1;
- duan=0;
- delay(5);
-
- P0=0xfb;
- wei=1;
- wei=0;
- P0=table[16];//第三位显示-
- duan=1;
- duan=0;
- delay(5);
-
- P0=0xf7;
- wei=1;
- wei=0;
- P0=table[b];//第四位显示选手号码
- duan=1;
- duan=0;
- delay(5);
-
- }
- void baojing(uchar c) //违规报警
- {
- P0=0xfe;
- wei=1;
- wei=0;
-
- P0=table[15];//第一位显示F
- duan=1;
- duan=0;
- delay(5);
-
- P0=0xfd;
- wei=1;
- wei=0;
- P0=table[15];//第二位显示F
- duan=1;
- duan=0;
- delay(5);
-
- P0=0xfb;
- wei=1;
- wei=0;
- P0=table[16];//第三位显示-
- duan=1;
- duan=0;
- delay(5);
-
- P0=0xf7;
- wei=1;
- wei=0;
- P0=table[c];//第四位显示选手号码
- duan=1;
- duan=0;
- delay(5);
-
- beep=0;//蜂鸣器报警
- delay(5);
- }
- void szxianshi(uchar d,uchar e) //数码管设置时的显示
- {
- uchar dshi,dge,eshi,ege;
- dshi=d/10;
- dge=d%10;
- eshi=e/10;
- ege=e%10;
-
- P0=0xfe;
- wei=1;
- wei=0;
-
- P0=table[dshi];//第一位显示抢答定时十位
- duan=1;
- duan=0;
- delay(5);
-
- P0=0xfd;
- wei=1;
- wei=0;
- P0=table[dge];//第二位显示抢答定时个位
- duan=1;
- duan=0;
- delay(5);
-
- P0=0xfb;
- wei=1;
- wei=0;
- P0=table[eshi];//第三位显示答题定时十位
- duan=1;
- duan=0;
- delay(5);
-
- P0=0xf7;
- wei=1;
- wei=0;
- P0=table[ege];//第四位显示答题定时个位
- duan=1;
- duan=0;
- delay(5);
- }
- void shezhi() //设置抢答时间和答题时间
- {
- if(keysz==0)//判断按下一次设置按键
- {
- delay(5);//延时消抖
- if(keysz==0)
- {
- while(!keysz);//松手判断
- setf++;//setf标志加1
- while(setf==1)//设置抢答时间
- {
- liushui();
- szxianshi(ds1,dtds1);//显示抢答时间和答题时间
- if(keyjia==0)//加抢答时间
- {
- delay(5);
- if(keyjia==0)
- {
- while(!keyjia);
- ds1++;
- ds=ds1;
- if(ds1>99)ds1=0;
- }
- }
- if(keyjian==0)//减抢答时间
- {
- delay(5);
- if(keyjian==0)
- {
- while(!keyjian);
- ds1--;
- ds=ds1;
- }
- }
- if(keysz==0)//判断按下第二次设置按键
- {
- delay(5);//延时消抖
- if(keysz==0)
- {
- while(!keysz);//松手判断
- setf++;//setf标志加1
- }
- }
- }
- while(setf==2)//设置答题时间
- {
- liushui();
- szxianshi(ds1,dtds1);//显示抢答时间和答题时间
- if(keyjia==0)//加答题时间
- {
- delay(5);
- if(keyjia==0)
- {
- while(!keyjia);
- dtds1++;
- dtds=dtds1;
- if(dtds1>99)dtds1=0;
- }
- }
- if(keyjian==0)//减答题时间
- {
- delay(5);
- if(keyjian==0)
- {
- while(!keyjian);
- dtds1--;
- dtds=dtds1;
- }
- }
- if(keysz==0)//判断按下第三次设置按键
- {
- delay(5);//延时消抖
- if(keysz==0)
- {
- while(!keysz);//松手判断
- setf++;//setf标志加1
- }
- }
- }
- if(setf==3)//setf标志满3清0
- {
- setf=0;
- chushi();//数码管初始化
- }
- }
- }
- }
- void xuanze() //8个选手按键选择
- {
- switch (q)//num对q进行选择
- {
- case 0xfe:num=1;break;
- case 0xfd:num=2;break;
- case 0xfb:num=3;break;
- case 0xf7:num=4;break;
- case 0xef:num=5;break;
- case 0xdf:num=6;break;
- case 0xbf:num=7;break;
- case 0x7f:num=8;break;
- }
- P0=tablewei[num-1];//对应灯亮
- deng=1;
- deng=0;
- }
- void scan() //键盘扫描
- {
- if(P1!=0xff&&wanf==0&&kaif==1)//判断是否有人按下
- {
- delay(5);//延时消抖
- if(P1!=0xff&&wanf==0&&kaif==1)
- {
- q=P1;
- while(P1!=0xff);//松手判断
- beep=0;
- delay(100);
- beep=1;
- wanf=1;//抢答完成
- daf=1;//开始答题
- xuanze();//8人按键选择
- }
- }
- }
- void jifen() //计分子函数
- {
- switch(num)//对选手号码进行选择,给fen赋值
- {
- case 1:fen=fen1;break;
- case 2:fen=fen2;break;
- case 3:fen=fen3;break;
- case 4:fen=fen4;break;
- case 5:fen=fen5;break;
- case 6:fen=fen6;break;
- case 7:fen=fen7;break;
- case 8:fen=fen8;break;
- }
- if(keyjia==0)//加分
- {
- delay(5);
- if(keyjia==0)
- {
- while(!keyjia);
- fen=fen+10;
- }
- }
- if(keyjian==0)//减分
- {
- delay(5);
- if(keyjian==0)
- {
- while(!keyjian);
- fen=fen-10;
- }
- }
- switch(num)//对选手号码进行选择, 把fen值赋给选手
- {
- case 1:fen1=fen;f1=fen1;break;
- case 2:fen2=fen;f2=fen2;break;
- case 3:fen3=fen;f3=fen3;break;
- case 4:fen4=fen;f4=fen4;break;
- case 5:fen5=fen;f5=fen5;break;
- case 6:fen6=fen;f6=fen6;break;
- case 7:fen7=fen;f7=fen7;break;
- case 8:fen8=fen;f8=fen8;break;
- }
- }
- void delayus(uint time) //延时
- {
- while(time --);
- }
- void writedata(uchar dat) //写数据
- {
- delayus(5);
- E = 1;
- RS = 1;
- P0 = dat;
- ye=1;
- ye=0;
- E = 0;
- }
- void writecmd(uchar cmd) //写地址/命令
- {
- delayus(5);
- E = 1;
- RS = 0;
- P0 = cmd;
- ye=1;
- ye=0;
- E = 0;
- }
- void setPM(uchar PM) //选择屏幕( 0-左屏,1-右屏,2-全屏 )
- {
- switch(PM)
- {
- case 0 : CS1 = 0; CS2 = 1; break;
- case 1 : CS1 = 1; CS2 = 0; break;
- default : CS1 = 0; CS2 = 0;
- }
- }
- void set_x( x) //x -> 0 : 7 页
- {
- x = x&0x07|0xb8;
- writecmd(x);
- }
-
- void set_y( y) //y -> 0 :63 列
- {
- y = y & 0x3f|0x40;
- writecmd(y);
- }
- void chearPM(uchar PM) //清屏(0-清左屏,1-清右屏,2-清全屏 )
- {
- uchar i,j;
- setPM(PM);
- for(i = 0;i < 8;i++)
- {
- set_x(i); //从第0到第7页
- set_y(0); //从第0列开始
- for(j = 0;j < 64; j++) //在PM=2的情况下左右半屏同时全写0.
- writedata(0x00);
- }
- }
- void InitLcd() //LCD初始化
- {
- Reset = 0;
- delayus(2);
- Reset = 1;
- delayus(2);//软件复位
- chearPM(2); //清屏
- }
- void showZF( x, y, uchar *ZF) //显示一个字符
- {
- uchar i;
- set_x(x); set_y(y); //设置页地址,设置列地址
- for(i = 0;i < 8;i ++) writedata(*(ZF++)); // 写字符的上半部分
- set_x(x + 1);set_y(y);
- for(i = 0;i < 8;i ++) writedata(*(ZF++)); // 写字符的下半部分
- }
- void display()//液晶显示
- {
- setPM(0);
- showZF(0,1,ZF_tab+16);
- showZF(0,17,ZF_tab+f1*16);
- showZF(0,25,ZF_tab);
-
- showZF(2,1,ZF_tab+32);
- showZF(2,17,ZF_tab+f2*16);
- showZF(2,25,ZF_tab);
-
- showZF(4,1,ZF_tab+48);
- showZF(4,17,ZF_tab+f3*16);
- showZF(4,25,ZF_tab);
-
- showZF(6,1,ZF_tab+64);
- showZF(6,17,ZF_tab+f4*16);
- showZF(6,25,ZF_tab);
- setPM(1);
- showZF(0,1,ZF_tab+80);
- showZF(0,17,ZF_tab+f5*16);
- showZF(0,25,ZF_tab);
-
- showZF(2,1,ZF_tab+96);
- showZF(2,17,ZF_tab+f6*16);
- showZF(2,25,ZF_tab);
-
- showZF(4,1,ZF_tab+112);
- showZF(4,17,ZF_tab+f7*16);
- showZF(4,25,ZF_tab);
-
- showZF(6,1,ZF_tab+128);
- showZF(6,17,ZF_tab+f8*16);
- showZF(6,25,ZF_tab);
- setPM(2);
- }
- void main() //主函数
- {
- ds1=60;//抢答时间和答题时间初始化
- dtds1=60;
- ye=0;
- InitLcd();
-
- LOOP0:fen=0;//分数初始化
- fen1=0;
- fen2=0;
- fen3=0;
- fen4=0;
- fen5=0;
- fen6=0;
- fen7=0;
- fen8=0;
- f1=fen1/10;
- f2=fen2/10;
- f3=fen3/10;
- f4=fen4/10;
- f5=fen5/10;
- f6=fen6/10;
- f7=fen7/10;
- f8=fen8/10;
-
- LOOP1:init();//初始化子函数
- while(kaif==0)//抢答未开始
- {
- liushui();//流水灯
- chushi();//数码管初始状态
- shezhi();//抢答时间和答题时间的设置
- display();
- if(keyqc==0)
- {
- delay(5);
- if(keyqc==0)
- {
- while(!keyqc);
- goto LOOP0;
- }
- }
- if(kaif==0&&P1!=0xff)//判断是否有违规抢答
- {
- delay(5);
- if(kaif==0&&P1!=0xff)
- {
- q=P1;
- while(P1!=0xff);//松手判断
- while(1)
- {
- xuanze();//8人按键选择
- baojing(num);//违规报警
- if(keyfw==0)goto LOOP1;//回到初始化子程序
- }
- }
- }
- if(keyks==0&&setf==0)//判断抢答是否开始
- {
- delay(5);//延时消抖
- if(keyks==0)
- {
- while(!keyks);//松手判断
- beep=0;
- delay(100);
- beep=1;
- P0=0xff;//关灯
- deng=1;
- deng=0;
- TR0=1;//开定时器0,关定时器1
- TR1=0;
- num=0;//显示0
- kaif=1;//抢答开始标记
- }
- }
- }
- while(kaif==1)//抢答开始
- {
- if(daf==0)//未开始答题
- {
- scan();//键盘扫描
- shuzi(ds,num);//数码管显示
- }
- else
- {
- if(daf==1)
- shuzi(s3,num);//答题之前3秒倒计时
- else
- shuzi(dtds,num);//开始答题,答题倒计时
- if(!keyjia||!keyjian)
- {
- TR0=0;
- while(keyfw&&keyqc)
- {
- shuzi(dtds,num);
- jifen();
- display();
- }
- }
- }
- if(keyfw==0)//复位
- {
- delay(5);
- if(keyfw==0)
- {
- while(!keyfw);
- goto LOOP1;//回到初始化子程序
- }
- }
- if(keyqc==0)
- {
- delay(5);
- if(keyqc==0)
- {
- while(!keyqc);
- goto LOOP0;
- }
- }
- }
- }
复制代码
|
|