一直以來,單片機(jī)松手檢測用的都是while(key==0); 這樣,不但浪費(fèi)CPU 資源,還。。。所以,用松手檢測 是非常好的,很時(shí)髦的。
下面是我晚上做了個(gè)小車總結(jié)出來的,可以單獨(dú)的按鍵,不影響其他按鍵,幾通道都可以。 貼上程序,最后分析整個(gè)程序意思。。
/*----------------------------------------------------------------
* 文 件 名:KEY.C
* 芯 片:STC12C5A60S2
* 晶 振:11.0592MHz
* 創(chuàng) 建 者:小強(qiáng)
* 創(chuàng)建日期:2012.3.23
* 修 改 者:
* 修改日期:
* 聯(lián)系作者:lyg407@126.com QQ:5163-806-35
* 功能描述:按鍵掃描
-------------------------------------------------------------*/
//按鍵掃描
uchar key_scan()
{
//前進(jìn)后退左轉(zhuǎn)右轉(zhuǎn) 按鍵
if(key_up&&(key1==0||key2==0||key3==0||key4==0)) //第一次 key_up=1 那么如果其它按鍵有按下,則為真 執(zhí)行下面程序
{
delay_10ms(); //延時(shí)去抖
if(key_up&&(key1==0||key2==0||key3==0||key4==0)) //再次判斷
{
key_up=0; //松手標(biāo)志為0 那么下次在檢測, if 結(jié)果就為0 則不會則行這里語句
key_down=1; //按鍵被按下標(biāo)志。 最后如果 按鍵松手 那么還應(yīng)該發(fā)送一個(gè)數(shù)據(jù)過去,執(zhí)行關(guān)閉
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; //必須所有按鍵 沒有按下 松手標(biāo)志 初始化
if(key_down==1) //這里判斷 是否按鍵 按下過, 按下過 就發(fā)送一個(gè)數(shù)據(jù)過去, 關(guān)閉之前輸出的。
{
key_down=0; //初始化
return 99; //返回值 隨意更改
}
}
//第二個(gè) 獨(dú)立按鍵
if(flag2_up&&(key5==0)) //意思同上
{
delay_10ms(); //延時(shí)去抖
if(flag2_up&&(key5==0)) //在判斷
{
flag2_up=0;
flag2_down=1; //意思同上
if(key5==0)
{
return 5;
}
}
}
else
if(key5==1)
{
flag2_up=1; //必須所有按鍵為1 沒有按下 松手標(biāo)志為1
if(flag2_down==1)
{
flag2_down=0;
return 95;
}
}
//第3個(gè)獨(dú)立 按鍵
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 沒有按下 松手標(biāo)志為1
if(flag3_down==1)
{
flag3_down=0; //意思同上
return 96;
}
}
return 0;
}
// 返回的按鍵 做的處理,執(zhí)行什么功能。。串口輸出數(shù)據(jù)
key_num=key_scan(); //讀取 按鍵掃描返回值
switch(key_num) //判斷
{
case 1:
UART1_Send_Byte(0x11); //前進(jìn)
break;
case 2:
UART1_Send_Byte(0x22); //后退
break;
case 3:
UART1_Send_Byte(0x33); //左轉(zhuǎn)
break;
case 4:
UART1_Send_Byte(0x44); //右轉(zhuǎn)
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 松手后 發(fā)送一個(gè)數(shù)據(jù)過去
break;
case 96:
UART1_Send_Byte(0x96); //按鍵6 松手后 發(fā)送一個(gè)數(shù)據(jù)過去
break;
case 99:
UART1_Send_Byte(0x99); // 小車 前進(jìn)后退 左轉(zhuǎn) 右轉(zhuǎn) 按鍵松手后 發(fā)送一個(gè)停止信號 。。。
break;
}
//上面是整個(gè)發(fā)送部分,有按鍵掃描 判斷 發(fā)送數(shù)據(jù)
//下面是接收解碼部分
value=SBUF; //value等于串口接收的字節(jié);
switch(value) //判斷接收到的數(shù)據(jù)
{
case 0x11: //執(zhí)行前進(jìn)
go();
break;
case 0x22: //執(zhí)行后退
back();
break;
case 0x33: //執(zhí)行左轉(zhuǎn)函數(shù)
left();
break;
case 0x44: //執(zhí)行右轉(zhuǎn)函數(shù)
right();
break;
case 0x99: //執(zhí)行 停止 函數(shù)
stop();
break;
case 0x55: //輸出 控制1 打開
out1=0;
break;
case 0x95: // 控制1 關(guān)閉
out1=1;
break;
case 0x66: //輸出控制2 打開
out2=0;
break;
case 0x96: //控制2 關(guān)閉
out2=1;
break;
}
OK, 下面整個(gè)程序意思分析: 遙控檢測按鍵 是否有按鍵 按下,如果有按鍵按下,發(fā)送一個(gè)前進(jìn) 0x11過去,接收機(jī) 接收到了11 執(zhí)行前進(jìn)函數(shù)。 那么此時(shí) 前進(jìn)按鍵 一直按著 則后 左 右 按鍵 按不起作用,因?yàn)檫@幾個(gè)共用一個(gè)按鍵按下標(biāo)志, 但是 按鍵5 按鍵 6 是在單獨(dú)一個(gè)松手檢測程序里,所以,此時(shí) 按鍵5 按鍵6 隨意觸發(fā)的。 當(dāng)前進(jìn) 按鍵松手后, 松手down=1 則執(zhí)行一次 返回99, 這個(gè)時(shí)候串口又發(fā)送一個(gè) 99 停止函數(shù)過去,小車停止。 。 不知道這樣是不是有點(diǎn)繁瑣,但是目前沒有其它的好思路,解決這樣的幾個(gè)獨(dú)立按鍵,按下,松手檢測。 這樣好處是,每次只發(fā)送一次數(shù)據(jù)過去,通訊不是那么頻繁,響應(yīng)能快一些。 這個(gè)就是整個(gè)思路,如果有什么問題可以提問哦~ ^_^ 又忘記要早點(diǎn)睡覺了。。