蓝桥杯单片机组矩阵按键扫描与数码管刷新

初始化

(把led和蜂鸣器啥的先关了)
通过操作P25 P26 P27 选择P0控制的设备

void init_system()	//初始化
{
	select_HC138(5);
	P0 = 0x00;
	select_HC138(4);
	P0 = 0xFF;				//关闭LED
}
void select_HC138(uchar n)
{
	switch(n)
	{
		case 4:
			P2 = (P2 & 0x1f) | 0x80;
			break;
		case 5:
			P2 = (P2 & 0x1f) | 0xA0;
			break;
		case 6:
			P2 = (P2 & 0x1f) | 0xC0;
			break;
		case 7:
			P2 = (P2 & 0x1f) | 0xE0;
			break;
	}
}

配置定时器,打开中断

(总中断在main里面开)
这里直接复制烧录软件里生成的代码(1毫秒)

void Timer0Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;
}

中断用来刷新数码管

void interruptT0() interrupt 1
{
	TL0 = 0x18;		
	TH0 = 0xFC;		
	
	smg_scan();
}

数码管刷新

uchar code led_code[11] = 
{
	0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,  //0-9
	0xbf //小横杆——led_code[10]
	// 若要加小数点则 led_buff -= 128;
};
uchar led_buff[8] = {0};//用来存放数码管要显示的数据
void smg_show(uchar dat, uchar pos)  //dat个位数,pos数码管位置
{
	P0 = 0xff;		//消隐
	select_HC138(6);
	P0 = 0x01 << (pos);
	select_HC138(7);
	P0 = led_code[dat];
}
void smg_scan()
{
	static uchar i = 0;
	smg_show(show_buff[i], i);
	i++;
	if(i==8) i=0;
}

矩阵按键扫描

在这里插入图片描述

这里如果用头文件 reg52.h
是没有P4的
所以用 STC15F2K60S2.h

sbit y1 = P3^0;
sbit y2 = P3^1;
sbit y3 = P3^2;
sbit y4 = P3^3;

sbit x1 = P4^4;
sbit x2 = P4^2;
sbit x3 = P3^5;
sbit x4 = P3^4;

思路是

x置1,y置0, 判断 x 状态,
若x有0,则有按键按下
短暂延时后(消抖),
再次判断 x 状态,确认按键被按下
依次判断x1-4状态,获取按键的列号
x置0,y置1, 判断 y 状态,
获取按键行号
松手检测

uchar key_scan()
{
	uchar key_code;
	P3 &= 0xF0; x1=1;x2=1;x3=1;x4=1;	//y置0,判断x
	if(!(x1&&x2&&x3&&x4))	//检测到有按键按下时
	{
		delay(100);
		if(!(x1&&x2&&x3&&x4))
		{
			if(x1==0) key_code=1;
			else if(x2==0) key_code=2;
			else if(x3==0) key_code=3;
			else if(x4==0) key_code=4;		//判断列

			x1=0;x2=0;x3=0;x4=0; P3 |= 0x0F;  //x置0,判断y
			if(y1==0) key_code += (1*10);
			else if(y2==0) key_code += (2*10);
			else if(y3==0) key_code += (3*10);
			else if(y4==0) key_code += (4*10);
			
			while(y1==0||y2==0||y3==0||y4==0);	//松手检测
			count_key++;
			return key_code;
		}
	}
	return 0;
}

主函数

void main()
{
	uchar n=0;
	init_system();
	Timer0Init();
	EA = 1;
	while(1)
	{
		n = key_scan();
		if(n)  //n不是0,则有按键按下,刷新数码管显示
		{
			led_buff[0] = n/10;
			led_buff[1] = n%10;
		}
	}
}
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值