自写单片机按键松手检测思路(转)

一直以来,单片机松手检测用的都是while(key==0); 这样,不但浪费CPU 资源,还。。。所以,用松手检测 是非常好的,很时髦的。
下面是我晚上做了个小车总结出来的,可以单独的按键,不影响其他按键,几通道都可以。 贴上程序,最后分析整个程序意思。。

#include <reg51.h>
/*----------------------------------------------------------------
* 文 件 名:KEY.C
* 芯 片:STC12C5A60S2
* 晶 振:11.0592MHz
* 创 建 者:小强
* 创建日期:2012.3.23
* 修 改 者:
* 修改日期:
* 联系作者:[email protected] QQ:5163-806-35
* 功能描述:按键扫描
-------------------------------------------------------------*/
//按键扫描
uchar key_scan()
{

	if(key_up&&(key1==0||key2==0||key3==0||key4==0))//前进后退左转右转 按键

		//第一次 key_up=1 那么如果其它按键有按下,则为真 执行下面程序
	{
		delay_10ms(); //延时去抖
		if(key_up&&(key1==0||key2==0||key3==0||key4==0)) //再次判断
		{
			key_up=0; //松手标志为0 那么下次在检测, if 结果就为0 则不会则行这里语句

			key_down=1; //按键被按下标志。 最后如果 按键松手 那么还应该发送一个数据过去,执行关闭

			if(key1==0) //如果按键1 按下
			return 1;
			if(key2==0)
			return 2;
			if(key3==0)
			return 3;
			if(key4==0)
			return 4;
		} 
	}
	else if(key1==1&&key2==1&&key3==1&&key4==1) //如果所有按键都没有按下。。注意 所有按键都没按下
	{
			key_up=1; //必须所有按键 没有按下 松手标志 初始化
			if(key_down==1) //这里判断 是否按键 按下过, 按下过 就发送一个数据过去, 关闭之前输出的。
		{
			key_down=0; //初始化
			return 99; //返回值 随意更改
		}
	}
		/**************************************
		*************第二个 独立按键**********/
	if(flag2_up&&(key5==0)) //意思同上 
		{
			delay_10ms(); //延时去抖
			if(flag2_up&&(key5==0)) //在判断
			{
				flag2_up=0;
				flag2_down=1; //意思同上
				if(key5==0)
				{
					return 5; 
				}
			}
		}
	else if(key5==1)
	{
		flag2_up=1; //必须所有按键为1 没有按下 松手标志为1
		if(flag2_down==1)
			{
				flag2_down=0;
				return 95; 
			} 
	}
	/**************************************
	*************第三个 独立按键**********/
	if(flag3_up&&(key6==0)) //意思同上
		{
			delay_10ms();
			if(flag3_up&&(key6==0))
			{
				flag3_up=0;
				flag3_down=1; //意思同上
				if(key6==0)
				{
					return 6; 
				}
			}
		}
	else if(key6==1)
		{
			flag3_up=1; //必须所有按键为1 没有按下 松手标志为1
			if(flag3_down==1)
			{
				flag3_down=0; //意思同上
				return 96; 
			} 
		}
			return 0;
}
		// 返回的按键 做的处理,执行什么功能。。串口输出数据
		key_num=key_scan(); //读取 按键扫描返回值
		switch(key_num) //判断
		{
		case 1:
		UART1_Send_Byte(0x11); //前进
		break;
		case 2:
		UART1_Send_Byte(0x22); //后退
		break;
		case 3:
		UART1_Send_Byte(0x33); //左转
		break;
		case 4:
		UART1_Send_Byte(0x44); //右转
		break;
		case 5:
		UART1_Send_Byte(0x55); //按键5 控制输出1
		break;
		case 6:
		UART1_Send_Byte(0x66); //按键6 控制输出2
		break;
		case 95:
		UART1_Send_Byte(0x95); //按键5 松手后 发送一个数据过去
		break;
		case 96:
		UART1_Send_Byte(0x96); //按键6 松手后 发送一个数据过去
		break;
		case 99:
		UART1_Send_Byte(0x99); // 小车 前进后退 左转 右转 按键松手后 发送一个停止信号 。。。
		break;
		}
		//上面是整个发送部分,有按键扫描 判断 发送数据

		//下面是接收解码部分

		value=SBUF; //value等于串口接收的字节;

switch(value) //判断接收到的数据
{
		case 0x11: //执行前进
		go(); 
		break;
		case 0x22: //执行后退
		back();
		break;
		case 0x33: //执行左转函数
		left();
		break;
		case 0x44: //执行右转函数
		right();
		break;
		case 0x99: //执行 停止 函数
		stop();
		break;
		case 0x55: //输出 控制1 打开
		out1=0; 
		break;
		case 0x95: // 控制1 关闭
		out1=1;
		break;
		case 0x66: //输出控制2 打开
		out2=0;
		break;
		case 0x96: //控制2 关闭
		out2=1;
		break;
}

void main()
{
    
}


OK, 下面整个程序意思分析: 遥控检测按键 是否有按键 按下,如果有按键按下,发送一个前进 0x11过去,接收机 接收到了11 执行前进函数。 那么此时 前进按键 一直按着 则后 左 右 按键 按不起作用,因为这几个共用一个按键按下标志, 但是 按键5 按键 6 是在单独一个松手检测程序里,所以,此时 按键5 按键6 随意触发的。 当前进 按键松手后, 松手down=1 则执行一次 返回99, 这个时候串口又发送一个 99 停止函数过去,小车停止。 。 不知道这样是不是有点繁琐,但是目前没有其它的好思路,解决这样的几个独立按键,按下,松手检测。 这样好处是,每次只发送一次数据过去,通讯不是那么频繁,响应能快一些。 这个就是整个思路,如果有什么问题可以提问哦~ ^_^ 又忘记要早点睡觉了。。
————————————————
版权声明:本文为CSDN博主「小王的修行路」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011872336/article/details/44917355

发布了4 篇原创文章 · 获赞 1 · 访问量 577

猜你喜欢

转载自blog.csdn.net/linsenaa/article/details/100883838
今日推荐