国产chinesehdxxxx老太婆,办公室玩弄爆乳女秘hd,扒开腿狂躁女人爽出白浆 ,丁香婷婷激情俺也去俺来也,ww国产内射精品后入国产

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

狀態(tài)機(jī)編程實(shí)例-狀態(tài)表法

碼農(nóng)愛學(xué)習(xí) ? 來源:碼農(nóng)愛學(xué)習(xí) ? 作者:碼農(nóng)愛學(xué)習(xí) ? 2023-06-20 09:05 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

上篇文章,使用嵌套switch-case法的狀態(tài)機(jī)編程,實(shí)現(xiàn)了一個(gè)炸彈拆除小游戲。

本篇,繼續(xù)介紹狀態(tài)機(jī)編程的第二種方法:狀態(tài)表法,來實(shí)現(xiàn)炸彈拆除小游戲的狀態(tài)機(jī)編程。

1 狀態(tài)表法

狀態(tài)表法,顧名思義,就是通過一個(gè)狀態(tài)表,來實(shí)現(xiàn)狀態(tài)機(jī)中的狀態(tài)轉(zhuǎn)換,下面就先介紹下狀態(tài)表的基礎(chǔ)知識(shí)。

1.1 狀態(tài)表

狀態(tài)表 ,最常用的是使用一個(gè)2維狀態(tài)表:

  • 水平方向是各個(gè)事件
  • 豎直方向是各個(gè)狀態(tài)
  • 單元的內(nèi)容是通過(執(zhí)行動(dòng)作,下一狀態(tài))來表示各種轉(zhuǎn)換關(guān)系

結(jié)合上一篇設(shè)計(jì)炸彈拆除小游戲的狀態(tài)圖(2個(gè)狀態(tài)和4個(gè)事件):

可以設(shè)計(jì)出對(duì)應(yīng)的狀態(tài)表,如下圖:

  • 水平方向的4種事件:UP、DOWN和ARM按鍵事件,TICK事件
  • 豎直方向的2種狀態(tài):設(shè)置狀態(tài)和倒計(jì)時(shí)狀態(tài)
  • 單元的內(nèi)容表示執(zhí)行指定動(dòng)作后,下一狀態(tài)是什么。比如設(shè)置狀態(tài)時(shí)按下UP鍵,執(zhí)行setting_UP函數(shù)中的動(dòng)作后,下一狀態(tài)還是留在設(shè)置狀態(tài)

注意:

  • (*):僅當(dāng)(me->code == me->defuse),即密碼輸入正確時(shí),才進(jìn)行狀態(tài)轉(zhuǎn)換至“設(shè)置狀態(tài)”
  • ):僅當(dāng)(me->fine_time == 0)和(me->timeout != 0),即每過一秒且倒計(jì)時(shí)未減到0時(shí),才進(jìn)行狀態(tài)轉(zhuǎn)換至“倒計(jì)時(shí)狀態(tài)”**

1.2 事件處理器

由于狀態(tài)表法可以使用一個(gè)非常有規(guī)律的數(shù)據(jù)結(jié)構(gòu)(狀態(tài)表)來表現(xiàn)一個(gè)狀態(tài)機(jī),因此編程時(shí)可以編寫一個(gè)通用的“事件處理器”來實(shí)現(xiàn)狀態(tài)機(jī)功能。

如下圖,通用的狀態(tài)表事件處理器,包含兩個(gè)主要結(jié)構(gòu):

  • 一個(gè)外部轉(zhuǎn)換的StateTable結(jié)構(gòu)
  • 一個(gè)帶有事件參數(shù)和沒有事件參數(shù)的Event結(jié)構(gòu)

此外,StateTable結(jié)構(gòu)有兩個(gè)相關(guān)的函數(shù):

  • init()函數(shù)用于觸發(fā)狀態(tài)機(jī)的初始轉(zhuǎn)換
  • dispatch()函數(shù)用于派送一個(gè)事件給狀態(tài)機(jī)處理

需體會(huì)的是,StateTable結(jié)構(gòu)是一個(gè)抽象的結(jié)構(gòu),按照UML類圖的畫法,這是一個(gè)抽象類(使用《abstract》或斜體類名表示),需要通過派生出一個(gè)實(shí)例類,如圖中的Bomb2,來實(shí)現(xiàn)具體的業(yè)務(wù)功能。

在狀態(tài)機(jī)的應(yīng)用程序中,狀態(tài)表僅包含執(zhí)行轉(zhuǎn)換函數(shù)的指針,即函數(shù)指針,而不是(執(zhí)行動(dòng)作,下一狀態(tài))的形式,使用這種方式,實(shí)際就是把狀態(tài)改變的邏輯,放到了轉(zhuǎn)換函數(shù)中,這樣做,使得編程更加靈活,因?yàn)闋顟B(tài)函數(shù)能方便地判斷某些監(jiān)護(hù)條件并隨之改變。

2 狀態(tài)表法的實(shí)現(xiàn)

上面介紹了狀態(tài)表法的基礎(chǔ)知識(shí),下面就來通過代碼來介紹狀態(tài)表法的具體實(shí)現(xiàn)。

2.1 通用狀態(tài)表事件處理器

上面說到,狀態(tài)表法可以使用一個(gè)非常有規(guī)律的狀態(tài)表數(shù)據(jù)結(jié)構(gòu)來表現(xiàn)一個(gè)狀態(tài)機(jī),因而在程序設(shè)計(jì)時(shí),可以編寫一個(gè)通用的狀態(tài)表事件處理器。

2.1.1 接口定義

通用的狀態(tài)表事件處理器,先來通過接口定義,看下它的功能。

注意上面提到的它包含兩個(gè)主要結(jié)構(gòu):

  • 一個(gè)外部轉(zhuǎn)換的StateTable結(jié)構(gòu)
  • 一個(gè)帶有事件參數(shù)和沒有事件參數(shù)的Event結(jié)構(gòu)

以及StateTable結(jié)構(gòu)的兩個(gè)相關(guān)的函數(shù):

  • init()函數(shù):用于觸發(fā)狀態(tài)機(jī)的初始轉(zhuǎn)換
  • dispatch()函數(shù):用于派送一個(gè)事件給狀態(tài)機(jī)處理
// 用于進(jìn)行狀態(tài)轉(zhuǎn)換的宏
#define TRAN(target) (((StateTable *)me)- >state = (uint8_t)(target))
?
typedef struct EventTag
{
  uint16_t sig; // 事件的信號(hào)
} Event;
?
struct StateTableTag; //提前聲明此變量
?
// 函數(shù)指針
typedef void (*Tran)(struct StateTableTag *me, Event const *e);
?
// 狀態(tài)表數(shù)據(jù)結(jié)構(gòu)
typedef struct StateTableTag
{
  uint8_t state;           //當(dāng)前狀態(tài)
  Tran const *state_table; //狀態(tài)表
  uint8_t n_states;        //狀態(tài)的個(gè)數(shù)
  uint8_t n_signals;       //事件(信號(hào))的個(gè)數(shù)
  Tran initial;            //初始轉(zhuǎn)換
} StateTable;
?
void StateTable_ctor(StateTable *me, Tran const *table, uint8_t n_states, uint8_t n_signals, Tran initial);
void StateTable_init(StateTable *me);
void StateTable_dispatch(StateTable *me, Event const *e);
void StateTable_empty(StateTable *me, Event const *e);

StateTable_ctor是狀態(tài)表的“構(gòu)造函數(shù)”,僅指向一個(gè)基本的初始化動(dòng)作,不會(huì)觸發(fā)初始轉(zhuǎn)換。

StateTable_empty是一個(gè)默認(rèn)的空動(dòng)作,用于狀態(tài)表初始化時(shí),某些需要空單元的地方使用。

另外,這里還要體會(huì)函數(shù)指針的用法。什么是函數(shù)指針,下面再來復(fù)習(xí)一下。

2.1.2 體會(huì)函數(shù)指針的用法

函數(shù)指針,本質(zhì)是一個(gè)指針,其指向的一個(gè)函數(shù),其類型定義為:

返回值類型 (* 函數(shù)名) ([形參列表]);

注意和指針函數(shù)的區(qū)別:

何為指針函數(shù)?

*指針函數(shù),本質(zhì)是一個(gè)函數(shù),例如 int pfun(int, int); 其返回值是指針類型,即返回一個(gè)指針(或稱地址),這個(gè)指針指向的數(shù)據(jù)是什么類型都可以。

一個(gè)記憶小技巧:指針函數(shù),可以類比int函數(shù),它們都是函數(shù),只是返回值不一樣,一個(gè)是返回指針,一個(gè)返回int。

首先來看函數(shù)指針的定義,以及基礎(chǔ)用法:

//定義一個(gè)函數(shù)指針pFUN,它指向一個(gè)返回類型為void,有一個(gè)參數(shù)類型為int的函數(shù)
void (*pFun)(int);
?
//定義一個(gè)返回類型為void,參數(shù)為int的函數(shù)。從指針層面上理解該函數(shù),其函數(shù)名實(shí)際上是一個(gè)指針,該指針指向函數(shù)在內(nèi)存中的首地址
void glFun(int a)
{
    printf("%d
", a);
}
?
int main()
{
    pFun = glFun; //將函數(shù)glFun的地址賦值給變量pFun
    (*pFun)(2);//“*pFun”是取pFun所指向地址的內(nèi)容,即取出了函數(shù)glFun()的內(nèi)容,然后給定參數(shù)為2
    
    return 0;
}

實(shí)際使用時(shí),常常通過typedef的方式讓函數(shù)指針更直觀方便的進(jìn)行使用:

//定義新的類型PTRFUN, 此類型的實(shí)際含義為函數(shù)指針,指向的函數(shù)的返回值是void,參數(shù)是int
typedef void (*PTRFUN)(int); 
?
//定義一個(gè)返回類型為void,參數(shù)為int的函數(shù)
void glFun(int a)
{ 
    printf("%d
", a);
} 
?
int main() 
{ 
    PTRFUN pFun; //使用定義的(函數(shù)指針)類型,實(shí)例化一個(gè)函數(shù)指針
    
    pFun = glFun; //把定義的glFun函數(shù),以函數(shù)名(本質(zhì)即指針)的形式為其賦值
    (*pFun)(2); //執(zhí)行該函數(shù)指針指向的內(nèi)容,即指向指向的函數(shù),并指定參數(shù)2
    
    return 0;
}

關(guān)于函數(shù)指針的實(shí)際應(yīng)用,也可參考我之前的這篇文章: STM32簡(jiǎn)易多級(jí)菜單(數(shù)組查表法)

2.1.3 具體實(shí)現(xiàn)

看完了通用的狀態(tài)表事件處理器的接口定義,下面再來看下具體實(shí)現(xiàn)。

//狀態(tài)表的構(gòu)造
void StateTable_ctor(StateTable *me,
                     Tran const *table, uint8_t n_states, uint8_t n_signals,
                     Tran initial)
{
    //第一個(gè)參數(shù)me為StateTable結(jié)構(gòu),由具體業(yè)務(wù)的派生狀態(tài)表的tateTable結(jié)構(gòu)傳入
    me- >state_table = table;   //狀態(tài)表, 由具體業(yè)務(wù)的二維狀態(tài)表傳入
    me- >n_states = n_states;   //二維狀態(tài)表的狀態(tài)數(shù)量
    me- >n_signals = n_signals; //二維狀態(tài)表的信號(hào)(事件)數(shù)量
    me- >initial = initial;     //狀態(tài)表的初始準(zhǔn)換函數(shù)
}
?
//狀態(tài)表的初始化
void StateTable_init(StateTable *me)
{
    me- >state = me- >n_states;
    (*me- >initial)(me, (Event *)0); //初始轉(zhuǎn)換
?
    assert(me- >state < me- >n_states); //確保事件范圍的合理
}
?
//狀態(tài)表的調(diào)度(派送一個(gè)事件給狀態(tài)機(jī)處理)
void StateTable_dispatch(StateTable *me, Event const *e)
{
    Tran t;
?
    assert(e- >sig < me- >n_signals); //確保信號(hào)范圍的合理
?
    //通過當(dāng)前狀態(tài)與當(dāng)前的信號(hào),以及信號(hào)的總數(shù),計(jì)算得到狀態(tài)表中要執(zhí)行的轉(zhuǎn)換函數(shù)在狀態(tài)表(二維的函數(shù)指針數(shù)組)中的位置
    t = me- >state_table[me- >state * me- >n_signals + e- >sig];
    (*t)(me, e); //然后執(zhí)行轉(zhuǎn)換函數(shù)
?
    assert(me- >state < me- >n_states); //確保狀態(tài)范圍的合理
}
?
//狀態(tài)表的空元素
void StateTable_empty(StateTable *me, Event const *e)
{
    (void)me; //用于消除參數(shù)未使用的警告
    (void)e;  
}

這里要體會(huì)一下狀態(tài)表的調(diào)度,即派送一個(gè)事件給狀態(tài)機(jī)處理的代碼邏輯,StateTable_dispatch的兩個(gè)參數(shù),一個(gè)是StateTable結(jié)構(gòu)的二維表,一個(gè)是Event結(jié)構(gòu)的信號(hào)(事件),注意這個(gè)二維狀態(tài)表,存儲(chǔ)的函數(shù)指針(各種轉(zhuǎn)換函數(shù)),所以是一個(gè)二維的函數(shù)指針數(shù)組,根據(jù)信號(hào),如何知道要執(zhí)行二維數(shù)組中的哪個(gè)函數(shù)呢?還要借助當(dāng)前狀態(tài)機(jī)所處的狀態(tài),即可通過簡(jiǎn)單的數(shù)學(xué)運(yùn)算得出,示意如下圖:

2.2 應(yīng)用邏輯(具體業(yè)務(wù)代碼)

看完了通用的狀態(tài)表事件處理器,就可以在此基礎(chǔ)上,編寫具體的狀態(tài)機(jī)業(yè)務(wù)代碼,實(shí)現(xiàn)上一篇介紹的炸彈拆除小游戲。

2.2.1 接口定義

還是先看下炸彈拆除小游戲這個(gè)具體業(yè)務(wù)邏輯用到的數(shù)據(jù)結(jié)構(gòu)與接口定義,主要包括:

  • 炸彈狀態(tài)機(jī)的狀態(tài)與信號(hào)(事件)
  • 從狀態(tài)表事件處理器的Event結(jié)構(gòu)派生的帶有事件參數(shù)的TickEvt結(jié)構(gòu)
  • 從狀態(tài)表事件處理器的StateTable結(jié)構(gòu)派生的具體的炸彈狀態(tài)機(jī)數(shù)據(jù)結(jié)構(gòu)
  • 狀態(tài)表中用到的所有的轉(zhuǎn)換函數(shù)
// 炸彈狀態(tài)機(jī)的所有狀態(tài)
enum BombStates
{
  SETTING_STATE, // 設(shè)置狀態(tài)
  TIMING_STATE,   // 倒計(jì)時(shí)狀態(tài)
  STATE_MAX
};
?
// 炸彈狀態(tài)機(jī)的所有信號(hào)(事件)
enum BombSignals
{
  UP_SIG,   // UP鍵信號(hào)
  DOWN_SIG, // DOWN鍵信號(hào)
  ARM_SIG,  // ARM鍵信號(hào)
  TICK_SIG,  // Tick節(jié)拍信號(hào)
  SIG_MAX
};
?
typedef struct TickEvtTag
{
  Event super;       // 派生自Event結(jié)構(gòu)
  uint8_t fine_time; // 精細(xì)的1/10秒計(jì)數(shù)器
} TickEvt;
?
// 炸彈狀態(tài)機(jī)數(shù)據(jù)結(jié)構(gòu)
typedef struct Bomb2Tag
{
  StateTable super; // 派生自StateTable結(jié)構(gòu)
  uint8_t timeout; // 爆炸前的秒數(shù)
  uint8_t code;    // 當(dāng)前輸入的解除炸彈的密碼
  uint8_t defuse;  // 解除炸彈的拆除密碼
  uint8_t errcnt;  // 當(dāng)前拆除失敗的次數(shù)
} Bomb2;
?
//炸彈構(gòu)造
void Bomb2_ctor(Bomb2 *me, uint8_t defuse);
//狀態(tài)表中需要用到的轉(zhuǎn)換函數(shù)(函數(shù)指針)
void Bomb2_initial(Bomb2 *me, Event const *e);      //初始轉(zhuǎn)換
void Bomb2_setting_UP(Bomb2 *me, Event const *e);   //轉(zhuǎn)換函數(shù), 設(shè)置狀態(tài)時(shí), 處理UP事件
void Bomb2_setting_DOWN(Bomb2 *me, Event const *e); //轉(zhuǎn)換函數(shù), 設(shè)置狀態(tài)時(shí), 處理DOWN事件
void Bomb2_setting_ARM(Bomb2 *me, Event const *e);  //轉(zhuǎn)換函數(shù), 設(shè)置狀態(tài)時(shí), 處理ARM事件
void Bomb2_timing_UP(Bomb2 *me, Event const *e);    //轉(zhuǎn)換函數(shù), 倒計(jì)時(shí)狀態(tài)時(shí), 處理UP事件
void Bomb2_timing_DOWN(Bomb2 *me, Event const *e);  //轉(zhuǎn)換函數(shù), 倒計(jì)時(shí)狀態(tài)時(shí), 處理DOWN事件
void Bomb2_timing_ARM(Bomb2 *me, Event const *e);   //轉(zhuǎn)換函數(shù), 倒計(jì)時(shí)狀態(tài)時(shí), 處理ARM事件
void Bomb2_timing_TICK(Bomb2 *me, Event const *e);  //轉(zhuǎn)換函數(shù), 倒計(jì)時(shí)狀態(tài)時(shí), 處理Tick事件

2.2.2 具體實(shí)現(xiàn)

1)炸彈構(gòu)造與初始化

炸彈構(gòu)造與初始化的實(shí)現(xiàn)如下

//炸彈構(gòu)造
void Bomb2_ctor(Bomb2 *me, uint8_t defuse)
{
  //定義炸彈狀態(tài)機(jī)的狀態(tài)表(函數(shù)指針構(gòu)成的二維數(shù)組)
  static const Tran bomb2_state_table[STATE_MAX][SIG_MAX] = {
    {(Tran)&Bomb2_setting_UP, (Tran)&Bomb2_setting_DOWN, (Tran)&Bomb2_setting_ARM, &StateTable_empty},
    {(Tran)&Bomb2_timing_UP, (Tran)&Bomb2_timing_DOWN, (Tran)&Bomb2_timing_ARM, (Tran)&Bomb2_timing_TICK}
  };
?
  //使用通用的通用狀態(tài)表事件處理器構(gòu)造狀態(tài)表
  StateTable_ctor(&me- >super, &bomb2_state_table[0][0], STATE_MAX, SIG_MAX, (Tran)&Bomb2_initial); 
  me- >defuse = defuse; //設(shè)置默認(rèn)的拆除密碼
}
?
//炸彈初始化
void Bomb2_initial(Bomb2 *me, Event const *e)
{
  (void)e; //用于消除參數(shù)未使用的警告
  me- >timeout = INIT_TIMEOUT;
  me- >errcnt = 0;
  TRAN(SETTING_STATE); //默認(rèn)進(jìn)行設(shè)置狀態(tài)
}

2)各個(gè)轉(zhuǎn)換函數(shù)

各個(gè)轉(zhuǎn)換函數(shù)(函數(shù)指針)的具體實(shí)現(xiàn)如下,其特征為短函數(shù)

/*.................設(shè)置狀態(tài)下的事件處理函數(shù)......................*/
void Bomb2_setting_UP(Bomb2 *me, Event const *e)
{
  (void)e; /* avoid compiler warning about unused parameter */
  if (me- >timeout < 60)
  {
    ++me- >timeout; //設(shè)置超時(shí)時(shí)間+1
    bsp_display_set_time(me- >timeout); //顯示設(shè)置的超時(shí)時(shí)間
  }
}
?
void Bomb2_setting_DOWN(Bomb2 *me, Event const *e)
{
  (void)e; /* avoid compiler warning about unused parameter */
  if (me- >timeout > 1)
  {
    --me- >timeout; //設(shè)置超時(shí)時(shí)間-1
    bsp_display_set_time(me- >timeout); //顯示設(shè)置的超時(shí)時(shí)間
  }
}
?
void Bomb2_setting_ARM(Bomb2 *me, Event const *e)
{
  (void)e; /* avoid compiler warning about unused parameter */
  me- >code = 0;
  TRAN(TIMING_STATE); /* transition to "timing" */
}
?
/*...................倒計(jì)時(shí)狀態(tài)下的事件處理函數(shù)................*/
void Bomb2_timing_UP(Bomb2 *me, Event const *e)
{
  (void)e; /* avoid compiler warning about unused parameter */
  me- >code < <= 1;
  me- >code |= 1; //添加一個(gè)1
  bsp_display_user_code(me- >code);
}
?
void Bomb2_timing_DOWN(Bomb2 *me, Event const *e)
{
  (void)e; /* avoid compiler warning about unused parameter */
  me- >code < <= 1; //添加一個(gè)0
  bsp_display_user_code(me- >code);
}
?
void Bomb2_timing_ARM(Bomb2 *me, Event const *e)
{
  (void)e; /* avoid compiler warning about unused parameter */
  if (me- >code == me- >defuse)
  {
    TRAN(SETTING_STATE); //轉(zhuǎn)換到設(shè)置狀態(tài)
    bsp_display_user_success(); //炸彈拆除成功
    Event *e = NULL;
    Bomb2_initial(me, e);
  }
  else
  {
    me- >code = 0;
    bsp_display_user_code(me- >code);
    bsp_display_user_err(++me- >errcnt);
  }
}
?
void Bomb2_timing_TICK(Bomb2 *me, Event const *e)
{
  if (((TickEvt const *)e)- >fine_time == 0)
  {
    --me- >timeout;
    bsp_display_remain_time(me- >timeout);
    if (me- >timeout == 0)
    {
      bsp_display_bomb(); //顯示爆炸效果
      Event *e = NULL;
      Bomb2_initial(me, e);
    }
  }
}

2.3 主函數(shù)

本篇同樣使用Arduino控制器進(jìn)行測(cè)試,對(duì)應(yīng)的主函數(shù)代碼如下:

static Bomb2 l_bomb;
?
void setup(void)
{
  Serial.begin(115200);
  bsp_display_init();
  bsp_display_hello();
  bsp_key_init();
?
  Bomb2_ctor(&l_bomb, 0x0D); // 構(gòu)造, 密碼1101
  StateTable_init((StateTable *)&l_bomb); // 初始轉(zhuǎn)化
}
?
void loop(void)
{
  static TickEvt tick_evt = {TICK_SIG, 0};
  delay(100);
?
  if (++tick_evt.fine_time == 10)
  {
    tick_evt.fine_time = 0;
  }
?
  char tmp_buffer[256];
  sprintf(tmp_buffer, "T(%1d)%c", tick_evt.fine_time, (tick_evt.fine_time == 0) ? '
' : ' ');
  Serial.print(tmp_buffer);
?
  StateTable_dispatch((StateTable *)&l_bomb, (Event *)&tick_evt);
?
  BombSignals userSignal = bsp_key_check_signal();
  if (userSignal != SIG_MAX)
  {
    static Event const up_evt = {UP_SIG};
    static Event const down_evt = {DOWN_SIG};
    static Event const arm_evt = {ARM_SIG};
    Event const *e = (Event *)0;
?
    switch (userSignal)
    {
      case UP_SIG: //UP鍵事件
      {
        Serial.print("
UP  : ");
        e = &up_evt;
        break;
      }
      case DOWN_SIG: //DOWN鍵事件
      {
        Serial.print("
DOWN: ");
        e = &down_evt;
        break;
      }
      case ARM_SIG: //ARM鍵事件
      {
        Serial.print("
ARM : ");
        e = &arm_evt;
        break;
      }
      default:break;
    }
?
    /* keyboard event available? */
    if (e != (Event *)0)
    {
       StateTable_dispatch((StateTable *)&l_bomb, e); /* dispatch the event */
    }
  }
}

3 總結(jié)

本編介紹了狀態(tài)機(jī)編程的第2種方法——狀態(tài)表法,通過一個(gè)非常有規(guī)律的二維表數(shù)據(jù)結(jié)構(gòu),以及函數(shù)指針,實(shí)現(xiàn)炸彈拆除小游戲中的狀態(tài)機(jī)功能。

本篇,需要重點(diǎn)體會(huì)的點(diǎn)包括:

  • 通用的“事件處理器”的結(jié)構(gòu)與功能
  • 函數(shù)指針的妙用,一般與數(shù)組查表法結(jié)合
  • 根據(jù)實(shí)際的狀態(tài)轉(zhuǎn)換與處理的業(yè)務(wù)需求,利用狀態(tài)表法,實(shí)現(xiàn)狀態(tài)機(jī)編程

    審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5149

    文章

    19655

    瀏覽量

    317306
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3689

    瀏覽量

    95211
  • 狀態(tài)機(jī)
    +關(guān)注

    關(guān)注

    2

    文章

    493

    瀏覽量

    28228
  • 函數(shù)指針
    +關(guān)注

    關(guān)注

    2

    文章

    57

    瀏覽量

    3970
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    NVMe高速傳輸之?dāng)[脫XDMA設(shè)計(jì)之十:NVMe初始化狀態(tài)機(jī)設(shè)計(jì)

    1為NVMe配置初始化狀態(tài)機(jī)狀態(tài)轉(zhuǎn)移圖。各狀態(tài)的說明如下: 圖1NVMe初始化狀態(tài)轉(zhuǎn)移圖 IDLE:空閑狀態(tài),復(fù)位后的初始
    發(fā)表于 07-05 22:03

    NVMe高速傳輸之?dāng)[脫XDMA設(shè)計(jì)之八:PCIe初始化狀態(tài)機(jī)設(shè)計(jì)

    PCIe配置初始化狀態(tài)機(jī)實(shí)現(xiàn)PCIe設(shè)備枚舉和配置空間初始化過程,在完成鏈路訓(xùn)練后,使用DFS(深度優(yōu)先搜索)算法枚舉PCIe總線上的設(shè)備,完成PCIe總線域的地址分配和設(shè)備的初始化。PCIe配置
    發(fā)表于 07-05 22:00

    有可能在 FX3 GPIF2 中創(chuàng)建兩個(gè)獨(dú)立的狀態(tài)機(jī)嗎?

    我想,如果我想通過 FX3 GPIF2 創(chuàng)建兩個(gè)獨(dú)立的傳輸流接口,我需要在 GPIF2 設(shè)計(jì)器中創(chuàng)建兩個(gè)獨(dú)立的狀態(tài)機(jī),我是否有可能在 GPIF2 設(shè)計(jì)器中創(chuàng)建兩個(gè)獨(dú)立的狀態(tài)機(jī)?
    發(fā)表于 05-20 06:14

    cypress3014視頻格式改變的話,GPIF狀態(tài)機(jī)需不需要重新配置?

    你好,請(qǐng)問視頻格式改變的話,GPIF狀態(tài)機(jī)需不需要重新配置
    發(fā)表于 05-14 07:28

    求助,關(guān)于srammaster.cydsn中狀態(tài)機(jī)的問題求解

    晚上好。 我目前正在學(xué)習(xí) GPIF II。 查看..EZ-USB FX3 SDK1.3firmwaregpif_examplescyfxsrammastersrammaster.cydsn中的狀態(tài)機(jī),有狀態(tài)START和START1。 這意味著什么?
    發(fā)表于 05-12 06:20

    單片機(jī)c語言編程實(shí)例大全

    單片機(jī)c語言編程實(shí)例大全_18
    發(fā)表于 04-30 16:11 ?3次下載

    基于FPGA的DS18B20數(shù)字溫度傳感器測(cè)溫實(shí)例

    本文將使用三段式狀態(tài)機(jī)(Moore型)的寫法來對(duì)DS18B20進(jìn)行測(cè)溫操作,以便了解DS18B20和熟悉三段式狀態(tài)機(jī)的寫法。
    的頭像 發(fā)表于 03-17 11:06 ?1485次閱讀
    基于FPGA的DS18B20數(shù)字溫度傳感器測(cè)溫<b class='flag-5'>實(shí)例</b>

    Simulink中的狀態(tài)機(jī)建模方法 Simulink數(shù)據(jù)可視化與分析功能

    1. Simulink中的狀態(tài)機(jī)建模方法 1.1 理解狀態(tài)機(jī)的基本概念 在開始建模之前,了解狀態(tài)機(jī)的基本概念是必要的。狀態(tài)機(jī)由以下幾個(gè)部分組成:
    的頭像 發(fā)表于 12-12 09:27 ?2976次閱讀

    基于狀態(tài)機(jī)和面向?qū)ο蟮乃枷朐O(shè)計(jì)按鍵檢測(cè)模塊

    嵌入式入門學(xué)習(xí)的教程里面,按鍵原理普遍被認(rèn)為是“很簡(jiǎn)單”的知識(shí)點(diǎn)之一,按鍵輸入檢測(cè)的原理,無非就是通過CPU不斷掃描按鍵引腳的電平狀態(tài),或者采用單片機(jī)引腳外部中斷方式,然后在死循環(huán)或者中斷服務(wù)程序里面處理按鍵被按下
    的頭像 發(fā)表于 11-14 11:44 ?950次閱讀
    基于<b class='flag-5'>狀態(tài)機(jī)</b>和面向?qū)ο蟮乃枷朐O(shè)計(jì)按鍵檢測(cè)模塊

    FPGA中有狀態(tài)表項(xiàng)的存儲(chǔ)與管理

    一篇2014年的論文:《CACHE FOR FLOW CONTENT: SOLUTION TODEPENDENT PACKET PROCESSING IN FPGA》,主要講述在FPGA中有狀態(tài)表項(xiàng)的存儲(chǔ)與管理。感興趣的可以閱讀原文。
    的頭像 發(fā)表于 10-27 16:06 ?663次閱讀
    FPGA中有<b class='flag-5'>狀態(tài)表</b>項(xiàng)的存儲(chǔ)與管理

    單片機(jī)io一般包含哪幾種狀態(tài)

    單片機(jī)的IO口(Input/Output,即輸入輸出端口)通常包含以下幾種狀態(tài),這些狀態(tài)使得單片機(jī)能夠靈活地與外部設(shè)備進(jìn)行數(shù)據(jù)交互和控制。以下是對(duì)這些狀態(tài)的說明: 輸入
    的頭像 發(fā)表于 09-14 14:35 ?1936次閱讀

    單片機(jī)io口的四種工作狀態(tài)

    單片機(jī)的I/O口工作狀態(tài)是單片機(jī)編程和硬件操作中非常重要的一部分,它決定了單片機(jī)如何與外部設(shè)備進(jìn)行通信。 1. 單片
    的頭像 發(fā)表于 09-14 14:24 ?3783次閱讀

    時(shí)序邏輯電路中如何判斷有效狀態(tài)和無效狀態(tài)

    在時(shí)序邏輯電路中,有效狀態(tài)和無效狀態(tài)的判斷是電路分析和設(shè)計(jì)的重要環(huán)節(jié)。有效狀態(tài)是指電路在實(shí)際工作過程中被利用到的狀態(tài),它們構(gòu)成了電路的有效循環(huán);而無效
    的頭像 發(fā)表于 08-12 15:51 ?5161次閱讀

    觸發(fā)器和狀態(tài)機(jī)的關(guān)系是什么

    觸發(fā)器和狀態(tài)機(jī)在數(shù)字電路設(shè)計(jì)中有著緊密的關(guān)系,它們共同構(gòu)成了時(shí)序邏輯電路的基礎(chǔ),用于實(shí)現(xiàn)數(shù)據(jù)的存儲(chǔ)、處理和傳輸。
    的頭像 發(fā)表于 08-12 11:24 ?940次閱讀

    如何在FPGA中實(shí)現(xiàn)狀態(tài)機(jī)

    在FPGA(現(xiàn)場(chǎng)可編程門陣列)中實(shí)現(xiàn)狀態(tài)機(jī)是一種常見的做法,用于控制復(fù)雜的數(shù)字系統(tǒng)行為。狀態(tài)機(jī)能夠根據(jù)當(dāng)前的輸入和系統(tǒng)狀態(tài),決定下一步的動(dòng)作和新的
    的頭像 發(fā)表于 07-18 15:57 ?1220次閱讀