標(biāo)題:
單片機(jī)狀態(tài)機(jī)按鍵程序 支持短按和長(zhǎng)按,可移植性好
[打印本頁(yè)]
作者:
2006sunmoon
時(shí)間:
2022-9-29 11:55
標(biāo)題:
單片機(jī)狀態(tài)機(jī)按鍵程序 支持短按和長(zhǎng)按,可移植性好
狀態(tài)機(jī)按鍵程序,可移植性好,支持短按和長(zhǎng)按。親測(cè)可用。
單片機(jī)源程序如下:
#include <iom16.h>
#include <intrinsics.h>
#include <stdbool.h>//位變量頭文件
#include <iomacro.h>
#include "keyboard.h"
#define key_state_init 0 //按鍵的初始狀態(tài)
#define key_state_ok 1 //按鍵被按下的狀態(tài)
#define key_state_long 2 //按鍵被長(zhǎng)按狀態(tài)
//#define key_state_continue 3 //按鍵被連續(xù)按下?tīng)顟B(tài)
#define key_state_release 4 //按鍵釋放的狀態(tài)
unsigned char KeyRead()
{
static unsigned int key_timenum=0;//按鍵長(zhǎng)按時(shí)間變量
static unsigned char key_state=0; //按鍵的狀態(tài)
static unsigned char key_num=0;//保存按鍵按鍵釋放時(shí)的值
static bool key_LONG=0;//記錄長(zhǎng)按釋放
unsigned char key_return=0; //按鍵返回值
unsigned char key_press; //保存按鍵按下的端口值
key_press =(port^0xFF)&0XFF; // 讀按鍵I/O電平
switch (key_state)
{
case key_state_init://按鍵的初始狀態(tài)
if(key_press)//如果按鍵被按下
{
key_state=key_state_ok;//則把key_state按鍵狀態(tài)置為按鍵確認(rèn)狀態(tài)
}
break;
case key_state_ok://按鍵確認(rèn)狀態(tài)
if(key_press)//如果按鍵被按下
{
key_num=key_press;// 按鍵I/O電平保存
key_state=key_state_long;//則把key_state按鍵狀態(tài)置為按鍵被長(zhǎng)按狀態(tài)
}
else
key_state=key_state_init; //如果按鍵是抖動(dòng)則返回按鍵的初始狀態(tài)
break;
case key_state_long://按鍵被長(zhǎng)按狀態(tài)
if(key_press)//如果按鍵被按下
{
if(!key_LONG)//如果上次有長(zhǎng)按事件發(fā)生,長(zhǎng)按時(shí)間就不再計(jì)時(shí)。
{
if (++key_timenum>=KEY_LONG_PERIOD)//達(dá)到長(zhǎng)按設(shè)置值時(shí)
{
key_timenum=0;
key_return=(key_press+KEY_LONGSIGN);//返回按鍵值加個(gè)數(shù)來(lái)區(qū)別單按和長(zhǎng)按
key_LONG=1;//標(biāo)記長(zhǎng)按事件發(fā)生
}
}
else
key_return=(key_press+KEY_LONGSIGN);//返回按鍵值加個(gè)數(shù)來(lái)區(qū)別單按和長(zhǎng)按
}
else
key_state=key_state_release; //則把key_state按鍵狀態(tài)置為按鍵被釋放狀態(tài)
break;
case key_state_release://按鍵釋放狀態(tài)
if (key_LONG)//如果有長(zhǎng)按事件發(fā)生
{
if(!key_press)//如果按鍵全部釋放
{
key_return=0;//返回值清0
key_state=key_state_init;//則把key_state按鍵狀態(tài)置為按鍵初始狀態(tài)
key_timenum=0;//計(jì)數(shù)清0
key_LONG=0;//長(zhǎng)按標(biāo)記清0
}
else//如果按鍵沒(méi)有釋放
{
key_state=key_state_release;//則繼續(xù)把key_state按鍵狀態(tài)置為按鍵被釋放狀態(tài)
}
}
else//如果沒(méi)有長(zhǎng)按事件發(fā)生
{
if(!key_press)//如果按鍵全部釋放
{
key_return=key_num;
key_state=key_state_init;//則把key_state按鍵狀態(tài)置為按鍵初始狀態(tài)
key_timenum=0;//計(jì)數(shù)清0
}
else
{
key_state=key_state_release;//則繼續(xù)把key_state按鍵狀態(tài)置為按鍵被釋放狀態(tài)
}
}
break;
}
return key_return;
}
復(fù)制代碼
#ifndef __KEYBOARD_H__
#define __KEYBOARD_H__
#define K1 0X01//設(shè)定按鍵位置
#define K2 0X02//設(shè)定按鍵位置
#define K3 0X04//設(shè)定按鍵位置
#define K4 0X08//設(shè)定按鍵位置
#define K5 0X10//設(shè)定按鍵位置
#define K6 0X20//設(shè)定按鍵位置
#define K7 0X40//設(shè)定按鍵位置
#define K8 0X80//設(shè)定按鍵位置
#define L_K1 0X01+KEY_LONGSIGN//設(shè)定按鍵位置
#define L_K2 0X02+KEY_LONGSIGN//設(shè)定按鍵位置
#define L_K3 0X04+KEY_LONGSIGN//設(shè)定按鍵位置
#define L_K4 0X08+KEY_LONGSIGN//設(shè)定按鍵位置
#define L_K5 0X10+KEY_LONGSIGN//設(shè)定按鍵位置
#define L_K6 0X20+KEY_LONGSIGN//設(shè)定按鍵位置
#define L_K7 0X40+KEY_LONGSIGN//設(shè)定按鍵位置
#define L_K8 0X80+KEY_LONGSIGN//設(shè)定按鍵位置
#define port PINA//設(shè)定按鍵端口
#define KEY_LONGSIGN 5//設(shè)定長(zhǎng)按按鍵與普通按鍵差值
#define KEY_LONG_PERIOD 150//定義長(zhǎng)按鍵時(shí)間,消抖時(shí)間*時(shí)間數(shù)
unsigned char KeyRead();
#endif
復(fù)制代碼
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1