《蓝桥杯CT107D单片机竞赛板》:独立按键模块

实验简介

CT107D单片机开发板上的独立按键控制, 指示灯亮灭,数码管显示按键值

实验原理图

在这里插入图片描述

实验原理

  • 器件介绍:按键是一种电子开关,使用时轻轻按开关按钮就可使开关接通,当松开手时, 开关断开。CT107D上的为机械弹性开关,由于机械点的弹性作用,按键开关在闭合时不会马上稳定的接通,在断开时也不会一下子断开,因而在闭合和断开的瞬间均伴随着一连串的抖动。所以我们在实验程序总要注意按键消除抖动(简称“消抖”)的操作。
  • 消除抖动:消抖有软件消抖硬件消抖,为了方便,我们使用软件消抖,具体操作为,先设置按键IO口输入为高电平,读取IO口是否有按键被按下(即有低电平出现),使用软件延时函数10ms,再次检测IO口是否仍为低电平,若是,则有按键被按下,进而继续下面的按键程序。
  • 实现须知:由于本实验独立按键需要控制LED,故锁存端LE得为高电平,即得控制Y4C为高电平,下图知Y4C,受Y4控制,WR输入固定为低电平(0),了解数字电路中或非门知识,我们得使得Y4输出低电平,才能使的Y4C输出高电平,而Y4为74HC138芯片(38译码器)的一个管脚,查阅对应芯片手册可知,其真值表满足C = 1,B = 0,A = 0,(对应管脚P27,P26,P25),才能使得Y4输出低电平,同时代码实现时要保证管脚P2的其他的管脚(0~4)保持原来的状态 。同理控制数码管的Y6C和Y7C,以及控制蜂鸣器的Y5C也一样
  • 注意:按键功能选择BTN(J5上的跳线2与3相连,此时切换至S7,S6,S5,S4独立按键模块)

在这里插入图片描述
在这里插入图片描述

实验程序

按下独立键盘上每一个键,对应LED状态取反

//config.h--用于声明头文件,声明函数,声明一些经常使用的变量或难书写的语句
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>//对应芯片函数头文件,定义了一些特殊功能寄存器
//typedef unsigned char uchar;
#define uchar unsigned char

void Delay10ms();		//@12.000MHz

#endif
//独立按键部分,记得接线帽切换为BTN
//main.c文件--按下按键S7,LED灯1亮,按下按键S6,LED灯2亮,按下按键S5,LED灯3亮,按下按键S4,LED灯4亮
#include "config.h"


//定义特殊位功能寄名称
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;

sbit led1 = P0^0;
sbit led2 = P0^1;
sbit led3 = P0^2;
sbit led4 = P0^3;

void led_init()//LED初始化为全部不亮
{
	P2 = (P2 & 0x1f) | 0x80;
	P0 = 0xff;
}

void closeBeep()
{
	P2 = (P2 & 0x1f) | 0xa0;  //开启译码器的Y6端口,同时不改变其他管脚状态
	P0 &= 0xaf;//1010 1111//关闭蜂鸣器和继电器,P06和P04端口分贝输入,输出低电平
	P2 &= 0x1f;//P27 ~ 25清零
}

void keyPros()
{ 
	if (S7 == 0)
	{
		Delay10ms();//消抖
		if (S7 == 0)
		{
			  led1 = ~led1;//led灯1的状态取反
		}
		while(!S7);//判断按键是否松开
	}
	else if (S6 == 0)
	{
		Delay10ms();//消抖
		if (S6 == 0)
		{
			  led2 = ~led2;//led灯1的状态取反
		}
		while(!S6);//判断按键是否松开
	}
	else if (S5 == 0)
	{
		Delay10ms();//消抖
		if (S5 == 0)
		{
			  led3 = ~led3;//led灯1的状态取反
		}
		while(!S5);//判断按键是否松开
	}
	else if (S4 == 0)
	{
		Delay10ms();//消抖
		if (S4 == 0)
		{
			  led4 = ~led4;//led灯1的状态取反
		}
		while(!S4);//判断按键是否松开
	}

}

void main()
{	
	closeBeep();
	led_init();

	while(1)
	{
		keyPros();
	}
}

void Delay10ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 117;
	j = 184;
	do
	{
		while (--j);
	} while (--i);
}

按键值在数码管上显示

//config.h--用于声明头文件,声明函数,声明一些经常使用的变量或难书写的语句
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>//对应芯片函数头文件,定义了一些特殊功能寄存器
//typedef unsigned char uchar;
#define uchar unsigned char

void Delay10ms();		//@12.000MHz
void Delay1000us();		//@12.000MHz

#endif
//独立按键部分,记得接线帽切换为BTN
//main.c文件--按键值在数码管上显示
#include "config.h"

//共阳数码管位选表
uchar smgwei[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

//共阴数码管码值表
uchar smgduan[] = {                       //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

	
uchar key_num = 20;
uchar tab[8];

//定义特殊位功能寄名称
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;

void led_init()//LED初始化为全部不亮
{
	P2 = (P2 & 0x1f) | 0x80;
	P0 = 0xff;
}

void closeBeep()
{
	P2 = (P2 & 0x1f) | 0xa0;  //开启译码器的Y6端口,同时不改变其他管脚状态
	P0 &= 0xaf;//1010 1111//关闭蜂鸣器和继电器,P06和P04端口分贝输入,输出低电平
	P2 &= 0x1f;//P27 ~ 25清零
}

void keyPros()
{ 
	static bit key_flag = 1;//注意注意static修饰的静态变量使用
	if ((!S7 || !S6 || !S5 || !S4) && key_flag)
	{
		Delay10ms();//消抖
		
		if(S7 == 0) { key_flag = 0; key_num = 7;}
		if(S6 == 0) { key_flag = 0; key_num = 6;}
		if(S5 == 0) { key_flag = 0; key_num = 5;}
		if(S4 == 0) { key_flag = 0; key_num = 4;}
	}
	else if (S7 && S6 && S5 && S4)
	{
		key_flag = 1;
	}

}

void selectHC573LE(uchar num)
{
	switch(num)
	{
		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;
		default: P2 &= 0x1f;break;
	}
}

void digDisplay(uchar pos, letter)
{
	//位选
	selectHC573LE(6);
	P0 = smgwei[pos - 1];

	//段选
	selectHC573LE(7);
	P0 = ~smgduan[letter];
	
	Delay1000us();
	selectHC573LE(0);
	P0 = 0xff;
}

void display()
{
	uchar i;
	for (i = 0; i < 8; i++)
		digDisplay(i + 1, tab[i]);
}

void display_ds(uchar p1, p2, p3, p4, p5, p6, p7, p8)
{
	tab[0] = p1;
	tab[1] = p2;
	tab[2] = p3;
	tab[3] = p4;
	tab[4] = p5;
	tab[5] = p6;
	tab[6] = p7;
	tab[7] = p8;
}
void main()
{	
	uchar a = 0;
	closeBeep();
	led_init();
	
	while(1)
	{
		keyPros();
		display();
		if (key_num == 7)
		{
			a = 7;
			key_num = 20;
		}
		if (key_num == 6)
		{
			a = 6;
			key_num = 20;
		}
		if (5 == key_num)
		{
			a = 5;
			key_num = 20;
		}
		if (4 == key_num)
		{
			a = 4;
			key_num = 20;
		}
		
		display_ds(16, 16, 16, 16, 16, 16, 16, a);//16为黑屏的对应码值
	}
}

void Delay10ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 117;
	j = 184;
	do
	{
		while (--j);
	} while (--i);
}


void Delay1000us()		//@12.000MHz
{
	unsigned char i, j;

	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
}

S4长按显示4,短按显示0,其他显示原来的键值

//config.h--用于声明头文件,声明函数,声明一些经常使用的变量或难书写的语句
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>//对应芯片函数头文件,定义了一些特殊功能寄存器
//typedef unsigned char uchar;
#define uchar unsigned char

void Delay10ms();		//@12.000MHz
void Delay1000us();		//@12.000MHz

#endif
//独立按键部分,记得接线帽切换为BTN
//main.c文件--对于S4按键,长按显示4,短按显示0,其他按键显示原来的键值
#include "config.h"

//共阳数码管位选表
uchar smgwei[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

//共阴数码管码值表
uchar smgduan[] = {                       //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

	
uchar key_num = 20, key_num2 = 100;

uchar tab[8];

//定义特殊位功能寄名称
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;

sbit led1 = P0^0;
sbit led2 = P0^1;
sbit led3 = P0^2;
sbit led4 = P0^3;

void led_init()//LED初始化为全部不亮
{
	P2 = (P2 & 0x1f) | 0x80;
	P0 = 0xff;
}

void closeBeep()
{
	P2 = (P2 & 0x1f) | 0xa0;  //开启译码器的Y6端口,同时不改变其他管脚状态
	P0 &= 0xaf;//1010 1111//关闭蜂鸣器和继电器,P06和P04端口分贝输入,输出低电平
	P2 &= 0x1f;//P27 ~ 25清零
}

void keyPros()
{ 
	static bit key_flag = 1;//注意注意static修饰的静态变量使用
	if ((!S7 || !S6 || !S5 || !S4) && key_flag)
	{
		Delay10ms();//消抖
		
		if(S7 == 0) { key_flag = 0; key_num = 7;}
		if(S6 == 0) { key_flag = 0; key_num = 6;}
		if(S5 == 0) { key_flag = 0; key_num = 5;}
		if(S4 == 0) { key_flag = 0; key_num = 4; key_num2 = 4;}
	}
	else if (S7 && S6 && S5 && S4)
	{
		key_num2 = 0;
		key_flag = 1;
	}

}

void selectHC573LE(uchar num)
{
	switch(num)
	{
		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;
		default: P2 &= 0x1f;break;
	}
}

void digDisplay(uchar pos, letter)
{
	//位选
	selectHC573LE(6);
	P0 = smgwei[pos - 1];

	//段选
	selectHC573LE(7);
	P0 = ~smgduan[letter];
	
	Delay1000us();
	selectHC573LE(0);
	P0 = 0xff;
}

void display()
{
	uchar i;
	for (i = 0; i < 8; i++)
		digDisplay(i + 1, tab[i]);
}

void display_ds(uchar p1, p2, p3, p4, p5, p6, p7, p8)
{
	tab[0] = p1;
	tab[1] = p2;
	tab[2] = p3;
	tab[3] = p4;
	tab[4] = p5;
	tab[5] = p6;
	tab[6] = p7;
	tab[7] = p8;
}
void main()
{	
	uchar a = 0, b = 20;
	closeBeep();
	led_init();
	
	while(1)
	{
		keyPros();
		display();
		if (key_num == 7)
		{
			a = 7;
			key_num = 20;
		}
		if (key_num == 6)
		{
			a = 6;
			key_num = 20;
		}
		if (5 == key_num)
		{
			a = 5;
			key_num = 20;
		}
		if (4 == key_num)
		{
			a = 0;
			key_num = 20;
		}
		
		if (4 == key_num2)//对于S4按键,长按显示4,短按显示0,其他按键显示原来的键值
		{
			b = 4;
			display_ds(16, 16, 16, 16, 16, 16, 16, b);//16为黑屏的对应码值
		}
		else if (0 == key_num2)
		{
			display_ds(16, 16, 16, 16, 16, 16, 16, a);//16为黑屏的对应码值
		}
	}
}

void Delay10ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 117;
	j = 184;
	do
	{
		while (--j);
	} while (--i);
}


void Delay1000us()		//@12.000MHz
{
	unsigned char i, j;

	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
}


  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值