卖逼视频免费看片|狼人就干网中文字慕|成人av影院导航|人妻少妇精品无码专区二区妖婧|亚洲丝袜视频玖玖|一区二区免费中文|日本高清无码一区|国产91无码小说|国产黄片子视频91sese日韩|免费高清无码成人网站入口

什么是狀態(tài)機:按鍵消抖實例

在編程中,狀態(tài)機是一種非常常用的設計模式,尤其在處理按鍵消抖的問題時非常有效。本文將介紹一個使用狀態(tài)機實現(xiàn)按鍵消抖的實例,并詳細講解其概念和編程思路。 狀態(tài)機的定義 狀態(tài)機是一個包含多個狀態(tài)的系統(tǒng)

在編程中,狀態(tài)機是一種非常常用的設計模式,尤其在處理按鍵消抖的問題時非常有效。本文將介紹一個使用狀態(tài)機實現(xiàn)按鍵消抖的實例,并詳細講解其概念和編程思路。

狀態(tài)機的定義

狀態(tài)機是一個包含多個狀態(tài)的系統(tǒng),根據(jù)輸入和當前狀態(tài)來決定狀態(tài)的轉(zhuǎn)移和輸出。在本例中,我們設置了4種狀態(tài),分別為A0、A1、A2、A3。初始時,狀態(tài)機處于A0狀態(tài)。

狀態(tài)機的工作原理

當掃描發(fā)現(xiàn)有鍵按下時,狀態(tài)機會根據(jù)當前狀態(tài)和鍵值進行狀態(tài)轉(zhuǎn)移。具體的轉(zhuǎn)移規(guī)則如下:

  • 如果當前狀態(tài)為A0,并且檢測到有鍵按下,則轉(zhuǎn)移到A1狀態(tài)。
  • 如果當前狀態(tài)為A1,并且檢測到有鍵按下,并且鍵值等于A1狀態(tài)下的鍵值,則轉(zhuǎn)移到A2狀態(tài),否則轉(zhuǎn)移到A0狀態(tài)。
  • 如果當前狀態(tài)為A2,并且檢測到有鍵按下,并且鍵值等于A2狀態(tài)下的鍵值,則轉(zhuǎn)移到A3狀態(tài),并同時發(fā)出鍵按下消息或?qū)聪骆I的鍵值入隊,否則轉(zhuǎn)移到A0狀態(tài)。
  • 如果當前狀態(tài)為A3,并且檢測到無鍵按下,則轉(zhuǎn)移到A0狀態(tài),并同時發(fā)出鍵彈起消息或彈起鍵的鍵值入隊。

函數(shù)介紹

在實現(xiàn)按鍵消抖的過程中,我們需要兩個函數(shù):

  • JianSaoMiao():用于鍵掃描獲取即時鍵值。
  • JianChuLi(JZ):用于按鍵處理,可以放在時鐘中斷中調(diào)用。

代碼實現(xiàn)

#define Kong 0x00 //定義無鍵按下時,鍵掃描返回的值
#define A0 0
#define A1 1
#define A2 2
#define A3 3
struct {
  unsigned char JianZhi; //當前鍵值
  unsigned char DangQianZhuangTai; //當前狀態(tài)
} ZTJ;
void ZTJ_ChuShiHua(void) //狀態(tài)機初始化
{
  ZTJ.DangQianZhuangTai  A0; //初始狀態(tài)A0
  ZTJ.JianZhi  Kong; //鍵值為Kong
}
uchar JianSaoMiao(void) //鍵值掃描
{
  uchar JianZhi;
  //在此根據(jù)實際電路插入鍵值掃描程序段,鍵值存放到JianZhi
  ...
  return (JianZhi);
}
void JianChuLi(uchar JZ)
{
  switch(ZTJ.DangQianZhuangTai)
  {
    case A0:
    {
      if(JZ ! Kong)
      {
        ZTJ.DangQianZhuangTai  A1; //有鍵按下,狀態(tài)轉(zhuǎn)移
        ZTJ.JianZhi  JZ; //保存當前鍵值
      }
    }
    break;
    case A1:
    {
      if(JZ  ZTJ.JianZhi)
        ZTJ.DangQianZhuangTai  A2; //有鍵按下,且鍵值穩(wěn)定,狀態(tài)轉(zhuǎn)移
      else
        ZTJ_ChuShiHua(); //鍵值不穩(wěn),回到初始狀態(tài)A0
    }
    break;
    case A2:
    {
      if(JZ  ZTJ.JianZhi)
      {
        ZTJ.DangQianZhuangTai  A3; //有鍵按下,且鍵值穩(wěn)定,狀態(tài)轉(zhuǎn)移
        //在此發(fā)出鍵按下消息,或?qū)㈡I按下鍵值入鍵值隊列供后續(xù)處理
        ...
      }
      else
        ZTJ_ChuShiHua(); //鍵值不穩(wěn),回到初始狀態(tài)A0
    }
    break;
    case A3:
    {
      if(JZ  Kong)
      {
        ZTJ_ChuShiHua(); //鍵已彈起,回到初始狀態(tài)A0
        //在此發(fā)出鍵彈起消息,或?qū)㈡I彈起鍵值入鍵值隊列供后續(xù)處理
        ...
      }
    }
    break;
    default:
    {
      ZTJ_ChuShiHua(); //初始狀態(tài)A0
    }
  }
}

使用方法

在10ms的中斷中掃描并處理按鍵,只需調(diào)用:JianChuLi(JianSaoMiao()),這樣就可以完成發(fā)出鍵按下或鍵彈起的消息,或?qū)㈡I值送入鍵值隊列供后續(xù)處理。

標簽: