单片机-答题计数器+数码管滚动显示

实现效果:
实现效果视频

/*
 * @Author: Guoquan Wei 1940359148@qq.com 
 * @Date: 2018-01-23 11:03:32 
 * @Last Modified by: Guoquan Wei
 * @Last Modified time: 2018-01-23 11:12:22
 */
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar datable[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71}; //定义段选
uchar watable[] = {0x3f, 0x1f, 0x2f, 0x37, 0x3b, 0x3d, 0x3e};														//定义位选,位选六位,最高两位初始化定为零
uchar lovetable[] = {5, 2, 0, 1, 3, 1, 4};
uchar *start = lovetable; //只是记录lovetable首地址,它不会改变
uchar *p = lovetable;	 // 指针
uchar *q;
sbit dula = P2 ^ 6;
sbit wela = P2 ^ 7;
#define KEY P3

int truenum, totalnum;
uchar flag;

void delayms(int x)
{
	int i, j;
	for (i = 0; i < x; i++)
		for (j = 0; j < 110; j++)
			;
}

void display(uchar numdis) //numdis是要显示的数字
{
	uchar shi, ge;
	shi = numdis / 10;
	ge = numdis % 10;

	dula = 1;
	P0 = datable[shi];
	dula = 0;
	P0 = 0xff;
	wela = 1;
	P0 = watable[2];
	wela = 0;
	delayms(1);

	dula = 1;
	P0 = datable[ge];
	dula = 0;
	P0 = 0xff;
	wela = 1;
	P0 = watable[1];
	wela = 0;
	delayms(1);
}

void display1(uchar numdis) //numdis是要显示的数字
{
	uchar shi, ge;
	shi = numdis / 10;
	ge = numdis % 10;

	dula = 1;
	P0 = datable[shi];
	dula = 0;
	P0 = 0xff;
	wela = 1;
	P0 = watable[6];
	wela = 0;
	delayms(1);

	dula = 1;
	P0 = datable[ge];
	dula = 0;
	P0 = 0xff;
	wela = 1;
	P0 = watable[5];
	wela = 0;
	delayms(1);
}

//-------------------------------------------
unsigned char Keyboard(void)
{
	unsigned char x, y, z = 0, jz;
	KEY = 0xf0;		 //低四位置低,即行接低
	if (KEY != 0xf0) //是否有按键按下
	{
		delayms(100);	//去抖
		if (KEY != 0xf0) //确实有按键按下
		{
			x = KEY;	//读取按键所在的行
			KEY = 0x0f; //高四位置低,即列接低
			y = KEY;	//读取按键所在的列
			z = x | y;  //按键的坐标为行+列
			while (KEY != 0x0f)
				; //等待按键抬起
		}
	}
	switch (z)
	{
	case 0xee:
	{
		jz = 0;
		break;
	} //按键值显示为0
	case 0xde:
	{
		jz = 1;
		break;
	} //按键值显示为1
	case 0xbe:
	{
		jz = 2;
		break;
	}
	case 0x7e:
	{
		jz = 3;
		break;
	}

	case 0xed:
	{
		jz = 4;
		break;
	}
	case 0xdd:
	{
		jz = 5;
		break;
	}
	case 0xbd:
	{
		jz = 6;
		break;
	}
	case 0x7d:
	{
		jz = 7;
		break;
	}

	case 0xeb:
	{
		jz = 8;
		break;
	}
	case 0xdb:
	{
		jz = 9;
		break;
	}
	case 0xbb:
	{
		jz = 10;
		break;
	}
	case 0x7b:
	{
		jz = 11;
		break;
	}

	case 0xe7:
	{
		jz = 12;
		break;
	}
	case 0xd7:
	{
		jz = 13;
		break;
	}
	case 0xb7:
	{
		jz = 14;
		break;
	}
	case 0x77:
	{
		jz = 15;
		break;
	}
	default:
	{
		jz = 16;
		break;
	} // 没有按键按下,返回16
	}
	return jz;
}

/*if (key == 0) //答题正确
	{
		truenum++;
		totalnum++;
		flag = 1;
	}
	if (key == 1) //答题错误
	{
		totalnum++;
		flag = 2;
	}
	if (key == 2)
	{
		if (flag == 1)
		{
			if (totalnum > 0)
			{
				truenum--;
				totalnum--;
			}
		}
		if (flag == 2)
		{
			if (totalnum > 0)
			{
				totalnum--;
			}
		}
		flag = 0; //表明本次执行的是按键3
	}*/

int main()
{
	uchar key;
	int i, j, k;
	while (totalnum < 3)
	{
		display(truenum);
		display1(totalnum);
		key = Keyboard();
		if (key == 0) //答题正确
		{
			truenum++;
			totalnum++;
			flag = 1;
		}
		if (key == 1) //答题错误
		{
			totalnum++;
			flag = 2;
		}
		if (key == 2)
		{
			if (flag == 1)
			{
				if (totalnum > 0)
				{
					truenum--;
					totalnum--;
				}
			}
			if (flag == 2)
			{
				if (totalnum > 0)
				{
					totalnum--;
				}
			}
			flag = 0; //表明本次执行的是按键3
		}
	}

	/*while (1)
	{
		dula = 1;
		P0 = datable[5];
		dula = 0;
		P0 = 0xff;
		wela = 1;
		P0 = watable[3];
		wela = 0;
		delayms(1);

		dula = 1;
		P0 = datable[2];
		dula = 0;
		P0 = 0xff;
		wela = 1;
		P0 = watable[2];
		wela = 0;
		delayms(1);

		dula = 1;
		P0 = datable[0];
		dula = 0;
		P0 = 0xff;
		wela = 1;
		P0 = watable[1];
		wela = 0;
		delayms(1);
	}*/
	while (1)
	{
        //start存储lovetable的首地址,且一直都不变;q是一直存储着start+k的地址,在内层的for循环里是不变的,q其实表示最左边数码管在一段时间内要显示的数对应的lovetable的地址;只有p一直在变,它用来显示段选
		for (k = 0; k < 7; k++)
			for (i = 1, j = 0, q = p = start + k; j < 300; i++, j++)
			{
				if (i >= 7)
				{
					i = 1;
				}
				dula = 1;
				P0 = datable[*p++];
				if (p >= start + 7)//p指向lovetable末尾的下一位时,把p移到start
				{
					p = start;
				}
				if (p - q == 6 || q - p == 1)//因为数码管是6位,而要显示7位,所以只能选取其中的六位。当p在q的后面时,p-q==6时,就要归位了;当q在p的后面时,则q-p==1时归位。
				{
					p = q;
				}
				dula = 0;
				P0 = 0xff;
				P0 = 0xff;
				P0 = 0xff;
				P0 = 0xff;
				P0 = 0xff;
				wela = 1;
				P0 = watable[7 - i];
				wela = 0;
				P0 = 0xff;
				P0 = 0xff;
				delayms(5);
			}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值