51单片机——计分器
前言
设计目标
1、完成一些比赛时的双方计分任务
2、通过四个按键完成对双方分数的加减,在数码管显示
3、设置按键,P31,P30完成甲方的计分加减;P32,P33完成乙方的计分加减
4、P31,P33为加,P32,P30为减
硬件设计:
甲方加分:P31
甲方减分:P30
乙方加分:P33
乙方减分:P32
显示模块:74HC138完成多位数码管的位选,P2口完成数码管的段选
原理图&仿真
这是当前我们需要用到的模块部分的原理图以及我们的仿真,这部分的原理图已经以仿真的形式画出来了,需要的可以私信博主或者从跳跳鼠的博客中获取,我们使用了四个独立按键,以及两组数码管控制显示了我们的比分
设计思路
在上面我们说到了,用了独立按键以及数码管进行操作显示,我们将四个独立按键分成了两组,分别做两组分数的加减,所以我们需要先把四个按键的部分写出来,代码如下
void key_proc()
{if(P3_2 == 0){delay(20);if(P3_2 == 0){num2++;}while(!P3_2);}if(P3_3 == 0){delay(20);if(P3_3 == 0){num2--;}while(!P3_3);}if(P3_1 == 0){delay(20);if(P3_1 == 0){num1++;}while(!P3_1);}if(P3_0 == 0){delay(20);if(P3_0 == 0){num1--;}while(!P3_0);}
}
很长一坨,看起来很屎山是吧,上面有两个没有定义的变量,这两个变量定义成了全局变量,分别用来表示双方分数,四个按键的处理部分分别对不同的变量进行了加减控制,对这部分代码有疑问,可以看51单片机基础部分——独立按键检测
这里的关于按键的讲解
部分实现代码
下面,我们就要考虑数码管的显示,数码管在这里应该怎么显示呢?结合51单片机基础部分——数码管显示
这里的代码我们写,这里我们的代码和之前的可能会有出入,但是原理都是一样的,这里的代码写法无数,看自己更偏向喜欢哪种代码
void display(int addr)
{switch(addr){case 1:P2_4=1;P2_3=1;P2_2=1;break;case 2:P2_4=1;P2_3=1;P2_2=0;break;case 3:P2_4=1;P2_3=0;P2_2=1;break;case 4:P2_4=1;P2_3=0;P2_2=0;break;case 5:P2_4=0;P2_3=1;P2_2=1;break;case 6:P2_4=0;P2_3=1;P2_2=0;break;case 7:P2_4=0;P2_3=0;P2_2=1;break;case 8:P2_4=0;P2_3=0;P2_2=0;break;}
}void smg_proc(unsigned char yi,er,qi,ba)
{display(7);P0 = show_num[yi];delay(5);display(8);P0 = show_num[er];delay(5);display(1);P0 = show_num[qi];delay(5);display(2);P0 = show_num[ba];delay(5);
}
这里我定义了一坨屎山变量,大家不要和我学,在代码里面定义拼音一类的东西,这样虽说可读性也还可以,但是读起来怪怪的(我的学长经常因为这个骂我),但是我还挺喜欢定义屎山的
这里数码管的和之前的有点出入,在这些说一下这个数码管的写法,大家可以和上面连接处的代码对比,选取自己喜欢的进行操作
void display(int addr)//这一部分是数码管的位选,和之前的差不多
{switch(addr){case 1:P2_4=1;P2_3=1;P2_2=1;break;case 2:P2_4=1;P2_3=1;P2_2=0;break;case 3:P2_4=1;P2_3=0;P2_2=1;break;case 4:P2_4=1;P2_3=0;P2_2=0;break;case 5:P2_4=0;P2_3=1;P2_2=1;break;case 6:P2_4=0;P2_3=1;P2_2=0;break;case 7:P2_4=0;P2_3=0;P2_2=1;break;case 8:P2_4=0;P2_3=0;P2_2=0;break;}
}void smg_proc(unsigned char yi,er,qi,ba)//这部分是数码管真正显示的部分,和之前不一样的地方在这里
{display(7);//对数码管位选(选择要哪个数码管进行显示)P0 = show_num[yi];//选择数码管后,对这个数码管的断码进行赋值,使该数码管显示相应的内容delay(5);//延时消影//下面以此类推都是同样的套路display(8);P0 = show_num[er];delay(5);display(1);P0 = show_num[qi];delay(5);display(2);P0 = show_num[ba];delay(5);
}
整体实现代码
#include <REGX52.H>
#include "intrins.h"
unsigned char show_num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char yi,er,qi,ba;
int num1,num2;
void delay(unsigned char t)
{unsigned char data i, j;while(t--){_nop_();i = 2;j = 199;do{while (--j);} while (--i); }}void display(int addr)
{switch(addr){case 1:P2_4=1;P2_3=1;P2_2=1;break;case 2:P2_4=1;P2_3=1;P2_2=0;break;case 3:P2_4=1;P2_3=0;P2_2=1;break;case 4:P2_4=1;P2_3=0;P2_2=0;break;case 5:P2_4=0;P2_3=1;P2_2=1;break;case 6:P2_4=0;P2_3=1;P2_2=0;break;case 7:P2_4=0;P2_3=0;P2_2=1;break;case 8:P2_4=0;P2_3=0;P2_2=0;break;}
}void smg_proc(unsigned char yi,er,qi,ba)
{display(7);P0 = show_num[yi];delay(5);display(8);P0 = show_num[er];delay(5);display(1);P0 = show_num[qi];delay(5);display(2);P0 = show_num[ba];delay(5);
}void key_proc()
{if(P3_2 == 0){delay(20);if(P3_2 == 0){num2++;}while(!P3_2);}if(P3_3 == 0){delay(20);if(P3_3 == 0){num2--;}while(!P3_3);}if(P3_1 == 0){delay(20);if(P3_1 == 0){num1++;}while(!P3_1);}if(P3_0 == 0){delay(20);if(P3_0 == 0){num1--;}while(!P3_0);}if(num1 < 0)num1 = 0;if(num1 > 99)num1 = 99;if(num2 < 0)num2 = 0;if(num2 > 99)num2 = 99;
}void main()
{while(1){key_proc();yi = num2/10;er = num2%10;qi = num1/10;ba = num1%10;smg_proc(yi,er,qi,ba);}
}
代码目前在硬件上面没有问题,由于社区上传视频较为麻烦,Proteus仿真已上传(也可以私信获取),大家可以将代码烧入仿真里面进行相关实验,也可以自己搭建硬件电路进行测试,后面会给大家更新相关的硬件电路以及其他小项目
ps:绑定资源好像只能绑定一个,另一个大家可以去主页找一下