我不知道你是學生還是已經在工作了, 如果是學生的話還可以理解.如果是出來工作了不應該一個按鍵的長短按還弄不清楚啊. 我給你一個程序,上面的注釋很清楚 ,如果你還不理解的話就不要做單片機了.這個是我所有項目都那樣寫的. 有三個點要注意:1 你要用到的那個IO口,也就是按鍵IO口必須是輸入設置,并且打開上拉,2 我的程序是4MS 一個定時. 3 不要用延時程序, 你用了延時程序以后這個就程序讀取的電平就不準了, 時間也不準了.
void KEY_SCAN(void) //掃描按鍵
{
if(!f_key_press) //判斷是按下還是彈起狀態 1 按下狀態 0 彈起狀態
{
if(P_KEY){key_cnt=0;} // 讀取IO口的電平 因為開了上拉,沒有按按鍵的時候讀取到的為高 所以只要是高就清零計數
key_cnt++; // ++
if(key_cnt>=10) // 連續讀取IO口電平10次證明按下按鍵了, 并且穩定了這也可以理解為消抖
{
key_cnt=0; // 清零按鍵計數 記得你一定要清零
f_key_press=1; //置按下按鍵標志位 并且置長按按鍵標志位
f_key_ctrl=1; // 長按標志位置起來后面要用到
}
}
else //判斷按鍵是按下還是彈起狀態 按下狀態 0 彈起狀態
{
if(!P_KEY){key_cnt=0;} //讀取IO口電平 ,開上拉的緣故 置要讀取到為低就證明還在按下狀態中 所以要清零按鍵計數
key_cnt++; //++
if(key_cnt>=10) // 連續讀取到10次高電平就證明已經彈起按鍵了.
{
key_cnt=0; // 清零彈起計數
f_key_press=0; //清按下標志位
// 敲重點 這里仔細看
if(f_key_ctrl) //去讀取這個標志位還在不在, 如果這個標志位不在就說明已經按下有3S了.直接跳過這里.執行下一條命令;
//如果這標志位還在就說明按下不到3S ,只能是短按,或者按下1S-3s之間.所以我們要來判斷ctrl_cnt的個數
{
if(ctrl_cnt>=250) //判斷之前的計數是多少 如果大于250*4MS =1000MS 就是長按1S的動作,那么執行長按1s的程序就可以了
{
ctrl_cnt=0; // 記得判斷后要立即清零
f_key_1s=1; //和f_key_3s一樣, 后面去讀取這個標志位 有就執行相應動作,沒有就不執行
}
else //不大于1S就短按 我們執行短按的程序
{
ctrl_cnt=0;
f_key_short=1;
}
}
//敲重點因為前面判斷了f_key_ctrl標志位還在不在,所以判斷完以后一定要清零 ,并且清理的位置不能錯
f_key_ctrl=0; // 清零長按標志位
}
}
//
if(f_key_ctrl) // 這個長按只管3S的長按 1 S 的在彈起里面處理
{
ctrl_cnt++; // 只要一讀取到f_key_ctrl為1 就開始++計數
if(ctrl_cnt>=750) //計數到750*4ms=3000ms 就清零 說明長按3S時間到了
{
ctrl_cnt=0; // 清零計數
f_key_ctrl=0; // 清零標志位
f_key_3s=1; // 這個標志位是長按3s的標志位,你自己另外寫一個函數,然后來讀取這個標志位 為1就執行長按3S的動作
//否則就不執行
}
}
else
{
ctrl_cnt=0;
}
}
void WORK_APP(void)
{
if(f_key_3s) //讀取上面按鍵的標志位 3S
{
// 自己添加相應的功能
}
else if(f_key_1s) // 讀取上面按鍵的標志位1s
{
// 自己添加功能
}
else if(f_key_short) // 讀取上面短按標志位
{
// 自己添加功能
}
} |