蓝桥杯静态数码管、独立键盘、矩阵键盘

一、静态数码管

image-20210620105131698

#include <stc15f2k60s2.h>
sbit relay=P0^4;	//sbit是定义特殊功能寄存器的位变量
sbit buzzer=P0^6;
void SysInit()
{
	P2=(P2&0x1f)|0x80;P0=0xff;P2&=0x1f;
	P2=(P2&0x1f)|0xa0;relay=0;buzzer=0;P2&=0x1f;
	P2=(P2&0x1f)|0xe0;P0=0xff;P2&=0x1f;
	P2=(P2&0x1f)|0xc0;P0=0x00;P2&=0x1f;
}

void main()
{
	SysInit();
	P2=(P2&0x1f)|0xe0;P0=0xc0;P2&=0x1f;
	P2=(P2&0x1f)|0xc0;P0=0xff;P2&=0x1f;P0=0xff;
}

二、独立按键与矩阵按键

image-20210622232501118

1.独立按键

独立按键学习点:
(1)注意J5跳线调到btn,四个独立按键是左边s7,s6,s5,s4
(2)每个键设置了三种工作状态,利用定时中断没10ms去读取一次按键值,
由于static char btn_state是个静态变量,上次读的结果是记住了的,这样就可以用来记下按下、抖动、松开几个状态,
没10ms读一次按键,还取到了消抖的作用,所以独立按键这个程序是比较全面的。
(3)使用这段代码的方法是,每隔10ms,btnkey=scanbtn(); btnkey为1就是s7,2为s6,3为s5,4为s4,0为没有按键

参考网址:
https://blog.csdn.net/lin5103151/article/details/103544509

1.状态机

//状态机消抖,可以用10ms延时查询,也可以用10ms中断查询,建议用中断
#define key_input P3
#define key_state_0 0	//判断按键是否按下
#define key_state_1 1	//判断按键是否抖动
#define key_state_2 2	//判断按键是否弹起
#define key_mask 0x0f	//屏蔽不需要的IO
char read_key()
{
	static key_state = 0;
	char key_press,key_return = 0;
	key_press = key_input & key_mask;
	switch(key_state)
	{
		case key_state_0:
			if(key_press != key_mask)
				key_state = key_state_1;
			break;
		
		case key_state_1:
			if(key_press != key_mask)
			{
				if(key_press == 0x0e) key_return = 1;	//S7
				if(key_press == 0x0d) key_return = 2;	//S6
				if(key_press == 0x0b) key_return = 3;	//S5
				if(key_press == 0x07) key_return = 4;	//S4
				key_state = key_state_2;
			}
			else
				key_state = key_state_0;
			break;
			
		case key_state_2:
			if(key_press == 0x0f) key_state = key_state_0;
			break;
	}
	return key_return;
}

//test
#include <STC15F2K60S2.H> 
void main()
{
	u8 i=0;
	sys_init();
	while(1)
	{
		i = read_key();
		delay_ms(10);
		if(i == 1)
		{
			//做你想做的事
		}
		if(i == 2)
		{
			//同上
		}
	}
		
}

2.状态机(坐标系)

#define state_0 0 //消抖
#define state_1 1 //是否按下 
#define state_2 2 //判断按键是否上

u8 key_num=0;
void key_scanf(void)
{
	static u8 key_state = 0;
	switch(key_state)
	{
		case state_0:
			P3 = 0x0f;  //消抖
			if(P3!=0x0f)
				key_state = state_1;//消抖完后进入到按键中
			break;
		case state_1:
			if(!P30|!P31|!P32|!P33)
			{
				if(!P30) key_num = 4;
				if(!P31) key_num = 3;
				if(!P32) key_num = 2;
				if(!P33) key_num = 1;
				key_state = state_2;
			}
			else
				key_state = state_0;
			break;
		case state_2:
			//P3 = 0x0f;  //消抖
			if(P3 == 0x0f)
				key_state = state_0;//消抖完后进入到按键中
			break;
	}
}

3.三行代码

/*******************************************************
Name : key_read
Function :	(1) No Key :ReadDate=0;Trg=0;Cont=0
			(2) S7 is 0 : KEYPORT=0xfe;ReadDate=0x01;Trg = 0x01 & (0x01 ^ 0x00) = 0x01;Cont=0x01
			(3) when S7 is always 0 : Trg = 0x01 & (0x01 ^ 0x01) = 0x00;Cont=0x01
			(4) when S7 is 1 : Trg = 0x01 & (0x00 ^ 0x01) = 0;Cont=0
Example:
	if(Trg & 0x08)	//one key
	
	if(Cont & 0x08)	//long key
	{
		time_count++;
		if(time_count == 100)
		{
			time_count = 0;
			SendString(*long !\r\n);
		}
	}
*******************************************************/
u8 Trg;	//触发
u8 Cont;	//持续
void key_read()
{
	unsigned char ReadDate = KEYPORT ^ 0xff;	//ReadDate:读取的键值	^:异或	  
	Trg = ReadDate & (ReadDate ^ Cont);	
	Cont = ReadDate;	
}

2.矩阵按键

1.状态机

//---------------------------4x4矩阵按键--------------------------------
#define kbd_io P3
#define state_0 0	  //是否按下
#define state_1 1 	  //是否是抖动
#define state_2 2	  //判断是否弹起
#define kbd_maskrow 0x0f	  //屏蔽不需要的IO
  
u8 key_num=16;
//col co2 co3 co4 rowl row2 row3 row4
//P44 P42 P35 P34 P33  P32  P31  P30
void scankbd()
{
	static char kbd_state = 0;
	unsigned char kbd_press;
	char row;
	switch(kbd_state)
	{
		case state_0:
			kbd_io=0x0f; P42=0; P44=0;
			kbd_press =kbd_io;
            
			if(kbd_press != kbd_maskrow)
				kbd_state = state_1;
			break;
		case state_1:
			kbd_press =kbd_io;
			if(kbd_press != kbd_maskrow){
				if((kbd_io&0x08)==0)  row=0;
				if((kbd_io&0x04)==0)  row=1;
				if((kbd_io&0x02)==0)  row=2;
				if((kbd_io&0x01)==0)  row=3;
				
				kbd_io=0xf0; P42=1;P44=1; 
				if(P44==0) key_num=row;
				if(P42==0) key_num=row+4;
				if((kbd_io&0x20)==0) key_num=row+8;
				if((kbd_io&0x10)==0) key_num=row+12;		
				kbd_state = state_2;
			}
			else
				kbd_state = state_0;
			break;
		case state_2:
			kbd_io=0x0f; P42=0; P44=0;
			kbd_press =kbd_io;
			if(kbd_press == 0x0f)	kbd_state = state_0;
			break;
		default:
			break;
	}
}

2.状态机(坐标系)

#define state_0 0 // 消抖
#define state_1 1 //按键是否按下
#define state_2 2 //按键弹起
uchar key_num = 0xff;
void key_scanf(void)
{
	static uchar stats = 0;
	uchar key_x,key_y=0;
	switch(stats)
	{
		case state_0:
			P3 = 0x0f;P42=0;P44=0;
			if(P3!=0x0f)
				stats = state_1;
			break;
		case state_1:
			if(!P30|!P31|!P32|!P33)
			{
				if(!P30) key_y = 4;
				if(!P31) key_y = 3;
				if(!P32) key_y = 2;
				if(!P33) key_y = 1;
			}
			P3 = 0xf0;P42=1;P44=1;
			if(!P34|!P35|!P42|!P44)
			{
				if(!P34) key_x = 4;
				if(!P35) key_x = 3;
				if(!P42) key_x = 2;
				if(!P44) key_x = 1;
				key_num = key_x*4 +key_y -5;
				stats = state_2;
			}
			else
				state = state_0;
			break;
		case state_2:
			P3 = 0x0f;P42=0;P44=0;
			if(P3==0x0f)
				state = state_0;
			break;
	}
}

3.三行代码(了解)

//#define SetKeyBoard(x) P4= (P4&0xEB) | ((x>>7)<<4) | (((x>>6)&0x01)<<2);P3= (P3&0xC0) | (x&0x3F)// 0xEB - 0x1110 1011  P4.2 P4.4
#define SetKeyBoard(x) P4 = (x>>3) | (x>>4);P3 = x 
#define GetKeyBoard() ((P4&0x10)<<3) | ((P4&0x04)<<4) | (P3&0x3F)
unsigned char Trg; 
unsigned char Cont; 

/**
  * @brief  三行按键-矩阵键盘,提供简化版本,大家自行消化理解
  * @param  None
  * @retval None
  * @author dianshe.taobao.com
  */
void KeyRead( void ) 
{ 
    unsigned char ReadData; 
    SetKeyBoard(0x0f);
    ReadData=GetKeyBoard(); 
	SetKeyBoard(0xf0);
    ReadData=(ReadData | GetKeyBoard())^0xff; 
    Trg  = ReadData & (ReadData ^ Cont); 
    Cont = ReadData; 
} 

/**
  * @brief  按键处理函数
  * @param  None
  * @retval None
  * @author dianshe.taobao.com
  */
void KeyProc(void) 
{ 
    if (Trg)  // 如果有按下 
    {
		P2=0x80;P0=Trg^0xff;;P2=0x00;	
    } 
	
    if (Cont)  // 如果按键被按着不放 
    { 
           
    }
	
    if (Trg ==0 & Cont==0)  //按键放开  
    { 
       
    } 
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dumbking

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值