各位同学们大家好~!又到了学习时间了。上一帖中有小可耐回帖,说希望在蓝桥板的代码里多看到一些注释,今天所发的数码管训练题目的帖子,在蓝桥板的代码中必要的地方都重新添加上了注释。让大家能够看得更明白。
今天的题目,主要针对按键进行讲解。有同学觉得按键很简单,但实际上,要想写出一个响应灵敏,并能够灵活触发的各种按键其实并不容易,尤其是当题目中要求我们实现双击、长按等这种不同动作种类的按键时,就更需要大家动一动自己的水灵的小脑袋了。
而且,从历年真题来看,按键和数码管是一样的,也是必考题。题目中通过按键结合数码管,设计的各种逻辑,做起来真的还是蛮有一定的挑战性的。下面咱们就来先针对按键和数码管进行综合练习。本次的练习题目和代码发出来,供大家参考学习。
题1、按下按键S4-S7,数码管分别显示键值1-4
题2、数码管初始显示0,单击S4,显示值加1,单击S5数值减1,长按S6数值连续加1,长按S7数值连续减1
下面依旧给出两个题目的代码,并在文末给出所有代码压缩包的下载链接,欢迎大家下载查看。如有任何问题,请大家在下方回帖告知~不胜感激的同时,还可能有U盘赠送的哦~
-----------------------蓝桥板代码---------------------
蓝桥板题1代码:
/*********************************************
1、按下按键S4-S7,数码管分别显示键值1-4
**********************************************/
#include<stc15f2k60s2.h>
#include"intrins.h"
#define uchar unsigned char
#define uint unsigned int
uchar code smgtab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF}; //共阳数码值
uchar yi,er,san,si,wu,liu,qi,ba;
void display1(uchar yi,uchar er); //第1第2两个数码管的显示函数
void display2(uchar san,uchar si); //第3第4两个数码管的显示函数
void display3(uchar wu,uchar liu ); //第5第6两个数码管的显示函数
void display4(uchar qi,uchar ba); //第7第8两个数码管的显示函数
void keyscan(); //按键扫描函数
void delayms(uint z); //毫秒级别延时函数
void init(); //单片机初始化函数
void main()
{
init();
yi=11;er=11;san=11;si=11;wu=11;liu=11;qi=11;ba=11;
while(1)
{
keyscan();
display1(yi,er);
display2(san,si);
display3(wu,liu );
display4(qi,ba);
}
}
void delayms(uint z) //延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=845;y>0;y--);
}
void init()
{
P2=0xa0;
P0=0x00; //关闭继电器蜂鸣器
P2=0x80;
P0=0xff; //关闭led灯
P2=0xc0;
P0=0xff; //选择所有数码管
P2=0xff;
P0=0xff; //关闭所有数码管
}
void keyscan() //独立按键
{
if(P30==0) //s7
{
delayms(5); //消抖
if(P30==0)
{
si=4; //键值4
}
while(!P30);
}
else if(P31==0) //s6
{
delayms(5);
if(P31==0)
{
san=3; //键值3
}
while(!P31);
}
else if(P32==0) //s5
{
delayms(5);
if(P32==0)
{
er=2; //键值2
}
while(!P32);
}
else if(P33==0) //s4
{
delayms(5);
if(P33==0)
{
yi=1; //键值1
}
while(!P33);
}
}
void display1(uchar yi,uchar er)
{
P2=0xc0;
P0=0x01; //选择第一个数码管
P2=0xff;
P0=smgtab[yi]; //段选
delayms(1);
P2=0xc0;
P0=0x02; //选择第二个数码管
P2=0xff;
P0=smgtab[er]; //段选
delayms(1);
}
void display2(uchar san,uchar si)
{
P2=0xc0;
P0=0x04; //选择第三个数码管
P2=0xff;
P0=smgtab[san]; //段选
delayms(1);
P2=0xc0;
P0=0x08; //选择第四个数码管
P2=0xff;
P0=smgtab[si]; //段选
delayms(1);
}
void display3(uchar wu,uchar liu )
{
P2=0xc0;
P0=0x10; //选择第五个数码管
P2=0xff;
P0=smgtab[wu]; //段选
delayms(1);
P2=0xc0;
P0=0x20; //选择第六个数码管
P2=0xff;
P0=smgtab[liu]; //段选
delayms(1);
}
void display4(uchar qi,uchar ba)
{
P2=0xc0;
P0=0x40; //选择第七个数码管
P2=0xff;
P0=smgtab[qi]; //段选
delayms(1);
P2=0xc0;
P0=0x80; //选择第八个数码管
P2=0xff;
P0=smgtab[ba]; //段选
delayms(1);
}蓝桥板题2代码:
/************************************************************************************
2、数码管初始显示0,单击S4,显示值加1,单击S5数值减1,长按S6数值连续加1,长按S7数值连续减1
(评论区有同学觉得长按的设计有点小BUG,已经在代码中重新更正,请大家验证)
*************************************************************************************/
#include<stc15f2k60s2.h>
#include"intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define TT 5
uchar code smgtab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar s4,s5,num;
uint count;
uchar One,Two,Three,Four,Five,Six,Seven,Eight;
void init();//蓝桥杯板初始化程序
void keyScan();//键盘扫描
void delayms(uint z);//ms级延时函数
void displayOne(uchar One,uchar Two);//第一二个数码管显示函数
void displayTwo(uchar Three,uchar Four);//第三四个数码管显示函数
void displayThree(uchar Five,uchar Six );//第五六个数码管显示函数
void displayFour(uchar Seven,uchar Eight);//第七八个数码管显示函数
/********************主函数****************************/
/*void main()
{
init();
while(1)
{
One=11;Two=11;Three=11;Four=11;Five=11;Six=num/100;Seven=num/10%10;Eight=num%10;
if(s4==1) //显示值加1
{
s4=0;
if((num>=0)&&(num<=255)) {num=num+1;} //uchar计数范围为0-255;
else if(num>255){num=255;}
}
else if(s5==1) //显示值减1
{
s5=0;
if((num>0)&&(num<=255)) {num=num-1;}
else if(num==0){num=0;}
}
else if(P31==0) //s6长按连续加1
{
delayms(5);
if(P31==0)
{
count=0;
while(P31==0)
{
delayms(40);
count++;
}
if(count>TT)
{
if((num>=0)&&(num<255))num=num+1;
else if(num==255)num=255;
}
}
}
else if(P30==0) //s7长按连续减1
{
delayms(5);
if(P30==0)
{
count=0;
while(P30==0)
{
delayms(40);
count++;
}
if(count>TT)
{
if((num>0)&&(num<=255))num=num-1;
else if(num==0)num=0;
}
}
}
keyScan();
displayOne(One,Two);
displayTwo(Three,Four);
displayThree(Five,Six);
displayFour(Seven,Eight);
}
}
void delayms(uint z) //延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=845;y>0;y--);
}
void init()
{
P2=0xa0;
P0=0x00; //关闭继电器蜂鸣器
P2=0x80;
P0=0xff; //关闭led灯
P2=0xc0;
P0=0xff; //选择所有数码管
P2=0xff;
P0=0xff; //关闭所有数码管
}
void keyscan()
{
if(P32==0) //s5
{
delayms(5);
if(P32==0)
{
s5=1; //按键s5的标志位
}
while(!P32);
}
else if(P33==0) //s4
{
delayms(5);
if(P33==0)
{
s4=1; //按键s4的标志位
}
while(!P33);
}
}
void displayOne(uchar One,uchar Two)
{
P2=0xc0;
P0=0x01; //选择第一个数码管
P2=0xff;
P0=smgtab[One]; //段选
delayms(1);
P2=0xc0;
P0=0x02; //选择第二个数码管
P2=0xff;
P0=smgtab[Two]; //段选
delayms(1);
}
void displayTwo(uchar Three,uchar Four)
{
P2=0xc0;
P0=0x04; //选择第三个数码管
P2=0xff;
P0=smgtab[Three]; //段选
delayms(1);
P2=0xc0;
P0=0x08; //选择第四个数码管
P2=0xff;
P0=smgtab[Four]; //段选
delayms(1);
}
void displayThree(uchar Five,uchar Six )
{
P2=0xc0;
P0=0x10; //选择第五个数码管
P2=0xff;
P0=smgtab[Five]; //段选
delayms(1);
P2=0xc0;
P0=0x20; //选择第六个数码管
P2=0xff;
P0=smgtab[Six]; //段选
delayms(1);
}
void displayFour(uchar Seven,uchar Eight)
{
P2=0xc0;
P0=0x40; //选择第七个数码管
P2=0xff;
P0=smgtab[Seven]; //段选
delayms(1);
P2=0xc0;
P0=0x80; //选择第八个数码管
P2=0xff;
P0=smgtab[Eight]; //段选
delayms(1);
}-----------------------小红板代码----------------------
小红板题1代码:
/*************************************************
1、按下独立按键s5,s10,s15,s20,数码管分别显示键值1-4
**************************************************/
#include"reg52.h"
#define uchar unsigned char
#define uint unsigned int
sbit P_HC595_SER = P2^7; //pin 14 SER data input
sbit P_HC595_RCLK = P2^5; //pin 12 RCLk store (latch) clock
sbit P_HC595_SRCLK = P2^6; //pin 11 SRCLK Shift data clock
sbit s5=P3^0;
sbit s10=P3^1;
sbit s15=P3^2;
sbit s20=P3^3;
uchar code smgtab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};
uchar yi,er,san,si,wu,liu,qi,ba;
void display1(uchar yi,uchar er);
void display2(uchar san,uchar si);
void display3(uchar wu,uchar liu);
void display4(uchar qi,uchar ba);
void keyscan();
void SMG_Init();
void Send_595(unsigned char dat);
void delayms(uint z);
void main()
{
SMG_Init();
yi=16;er=16;san=16;si=16;wu=16;liu=16;qi=16;ba=16;
while(1)
{
keyscan();
display1(yi,er);
display2(san,si);
display3(wu,liu);
display4(qi,ba);
}
}
void delayms(uint z) //ms级别延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void keyscan()
{
if(s5==0) //s5
{
delayms(5); //延时消抖5-10ms
if(s5==0)
{
yi=1;
}
while(!s5); // 松手检测
}
else if(s10==0) //s10
{
delayms(5);
if(s10==0)
{
er=2;
}
while(!s10);
}
else if(s15==0) //s15
{
delayms(5);
if(s15==0)
{
san=3;
}
while(!s15);
}
else if(s20==0) //s20
{
delayms(5);
if(s20==0)
{
si=4;
}
while(!s20);
}
}
void SMG_Init()
{
Send_595(0x00); //同时选择8个数码管
Send_595(0x00); //让8个数码管同时显示消隐字符
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
}
void Send_595(unsigned char dat) //发送一个字节
{
unsigned char i;
for(i=0; i<8; i++)
{
if(dat & 0x80) //判断dat的最高位是否为1
P_HC595_SER = 1; //最高位如果为1,则令P2.7 = 1
else
P_HC595_SER = 0; //最高位如果为0,则令P2.7 = 0
P_HC595_SRCLK = 0;
P_HC595_SRCLK = 1;
P_HC595_SRCLK = 0; //使用P2.6制造一个上升沿将这一位数据送到74HC595的QA输出端
dat = dat << 1; //将dat左移一位,取次高位
}
}
void display1(uchar yi,uchar er)
{
Send_595(0xfe); //选择最右边的一个数码管
Send_595(smgtab[yi]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
Send_595(0xfd); //选择最右边的一个数码管
Send_595(smgtab[er]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
}
void display2(uchar san,uchar si)
{
Send_595(0xfb); //选择最右边的一个数码管
Send_595(smgtab[san]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
Send_595(0xf7); //选择最右边的一个数码管
Send_595(smgtab[si]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
}
void display3(uchar wu,uchar liu)
{
Send_595(0xef); //选择最右边的一个数码管
Send_595(smgtab[wu]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
Send_595(0xdf); //选择最右边的一个数码管
Send_595(smgtab[liu]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
}
void display4(uchar qi,uchar ba)
{
Send_595(0xbf); //选择最右边的一个数码管
Send_595(smgtab[qi]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
Send_595(0x7f); //选择最右边的一个数码管
Send_595(smgtab[ba]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
}小红板题2代码:
/*****************************************************************************************
2、数码管初始显示0,单击S5,显示值加1,单击S10数值减1,长按S15数值连续加1,长按S20数值连续减1。
******************************************************************************************/
#include"reg52.h"
#define uchar unsigned char
#define uint unsigned int
#define TT 5
sbit P_HC595_SER = P2^7; //pin 14 SER data input
sbit P_HC595_RCLK = P2^5; //pin 12 RCLk store (latch) clock
sbit P_HC595_SRCLK = P2^6; //pin 11 SRCLK Shift data clock
sbit s5=P3^0;
sbit s10=P3^1;
sbit s15=P3^2;
sbit s20=P3^3;
uchar code smgtab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40,0x00};
uint count;
uchar ss5,ss10,num;
uchar One,Two,Three,Four,Five,Six,Seven,Eight;
void keyScan(); //键盘扫描
void SMG_Init();//数码管初始化函数
void delayms(uint z);//ms级延时函数
void Send_595(unsigned char dat);
void displayOne(uchar One,uchar Two);//第一二个数码管显示函数
void displayTwo(uchar Three,uchar Four);//第三四个数码管显示函数
void displayThree(uchar Five,uchar Six );//第五六个数码管显示函数
void displayFour(uchar Seven,uchar Eight);//第七八个数码管显示函数
/****************************主函数*******************************/
void main()
{
SMG_Init();
while(1)
{
One=11;Two=11;Three=11;Four=11;Five=11;Six=num/100;Seven=num/10%10;Eight=num%10;
if(ss5==1)
{
ss5=0;
if((num>0)&&(num<=255)){num=num-1;}
else if(num==0){num=0;}
}
else if(ss10==1)
{
ss10=0;
if((num>=0)&&(num<=255)){num=num+1;}
else if(num>255){num=255;}
}
else if(s15==0) //s15长按连续加1
{
delayms(5);
if(s15==0)
{
count=0;
while(s15==0)
{
delayms(40);
count++;
}
if(count>TT)
{
if((num>=0)&&(num<255))num=num+1;
else if(num==255)num=255;
}
}
}
else if(s20==0) //s20长按连续减1
{
delayms(5);
if(s20==0)
{
count=0;
while(s20==0)
{
delayms(40);
count++;
}
if(count>TT)
{
if((num>0)&&(num<=255))num=num-1;
else if(num==0)num=0;
}
}
}
keyScan();
displayOne(One,Two);
displayTwo(Three,Four);
displayThree(Five,Six);
displayFour(Seven,Eight);
}
}
void delayms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void keyscan()
{
if(s5==0) //s5
{
delayms(5);
if(s5==0)
{
ss5=1; //s5的标志位
}
while(!s5);
}
else if(s10==0) //s10
{
delayms(5);
if(s10==0)
{
ss10=1; //s10的标志位
}
while(!s10);
}
}
void SMG_Init()
{
Send_595(0x00); //同时选择8个数码管
Send_595(0x00); //让8个数码管同时显示消隐字符
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
}
void Send_595(unsigned char dat) //发送一个字节
{
unsigned char i;
for(i=0; i<8; i++)
{
if(dat & 0x80) //判断dat的最高位是否为1
P_HC595_SER = 1; //最高位如果为1,则令P2.7 = 1
else
P_HC595_SER = 0; //最高位如果为0,则令P2.7 = 0
P_HC595_SRCLK = 0;
P_HC595_SRCLK = 1;
P_HC595_SRCLK = 0; //使用P2.6制造一个上升沿将这一位数据送到74HC595的QA输出端
dat = dat << 1; //将dat左移一位,取次高位
}
}
void displayOne(uchar One,uchar Two)
{
Send_595(0xfe); //选择最右边的一个数码管
Send_595(smgtab[One]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
Send_595(0xfd); //选择最右边的一个数码管
Send_595(smgtab[Two]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
}
void displayTwo(uchar Three,uchar Four)
{
Send_595(0xfb); //选择最右边的一个数码管
Send_595(smgtab[Three]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
Send_595(0xf7); //选择最右边的一个数码管
Send_595(smgtab[Four]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
}
void displayThree(uchar Five,uchar Six )
{
Send_595(0xef); //选择最右边的一个数码管
Send_595(smgtab[Five]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
Send_595(0xdf); //选择最右边的一个数码管
Send_595(smgtab[Six]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
}
void displayFour(uchar Seven,uchar Eight)
{
Send_595(0xbf); //选择最右边的一个数码管
Send_595(smgtab[Seven]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
Send_595(0x7f); //选择最右边的一个数码管
Send_595(smgtab[Eight]);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
}----------------所有代码打包下载链接------------------
同学们,可以接着往下进行 06. 单片机 外部中断的使用 的题目练习~如对代码有任何问题,欢迎回帖指出来~
欢迎大家对本系列的支持,这是我们的动力!

我要赚赏金
