女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

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

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

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

什么是狀態(tài)機(jī)?狀態(tài)機(jī)5要素

FPGA那點(diǎn)事兒 ? 來源:Alicedodo ? 作者:Alicedodo ? 2021-07-27 11:23 ? 次閱讀

單片機(jī)還可以,各個外設(shè)也都會驅(qū)動,但是如果讓你完整的寫一套代碼時(shí),卻無邏輯與框架可言。這說明編程還處于比較低的水平,你需要學(xué)會一種好的編程框架或者一種編程思想!比如模塊化編程、狀態(tài)機(jī)編程、分層思想等。

本文來說一下狀態(tài)機(jī)編程。

什么是狀態(tài)機(jī)?

狀態(tài)機(jī)(state machine)有5個要素:

狀態(tài)(state)

遷移(transition)

事件(event)

動作(action)

條件(guard) 狀態(tài):一個系統(tǒng)在某一時(shí)刻所存在的穩(wěn)定的工作情況,系統(tǒng)在整個工作周期中可能有多個狀態(tài)。例如一部電動機(jī)共有正轉(zhuǎn)、反轉(zhuǎn)、停轉(zhuǎn)這 3 種狀態(tài)。

一個狀態(tài)機(jī)需要在狀態(tài)集合中選取一個狀態(tài)作為初始狀態(tài)。

遷移:系統(tǒng)從一個狀態(tài)轉(zhuǎn)移到另一個狀態(tài)的過程稱作遷移,遷移不是自動發(fā)生的,需要外界對系統(tǒng)施加影響。停轉(zhuǎn)的電動機(jī)自己不會轉(zhuǎn)起來,讓它轉(zhuǎn)起來必須上電。

事件:某一時(shí)刻發(fā)生的對系統(tǒng)有意義的事情,狀態(tài)機(jī)之所以發(fā)生狀態(tài)遷移,就是因?yàn)槌霈F(xiàn)了事件。對電動機(jī)來講,加正電壓、加負(fù)電壓、斷電就是事件。

動作:在狀態(tài)機(jī)的遷移過程中,狀態(tài)機(jī)會做出一些其它的行為,這些行為就是動作,動作是狀態(tài)機(jī)對事件的響應(yīng)。給停轉(zhuǎn)的電動機(jī)加正電壓,電動機(jī)由停轉(zhuǎn)狀態(tài)遷移到正轉(zhuǎn)狀態(tài),同時(shí)會啟動電機(jī),這個啟動過程可以看做是動作,也就是對上電事件的響應(yīng)。

條件:狀態(tài)機(jī)對事件并不是有求必應(yīng)的,有了事件,狀態(tài)機(jī)還要滿足一定的條件才能發(fā)生狀態(tài)遷移。還是以停轉(zhuǎn)狀態(tài)的電動機(jī)為例,雖然合閘上電了,但是如果供電線路有問題的話,電動機(jī)還是不能轉(zhuǎn)起來。

舉個例子

要解決的問題

電路如下圖:

器件包括單片機(jī)MCU、一按鍵K0、LED燈L1和L2。

實(shí)現(xiàn)功能描述:

L1L2狀態(tài)轉(zhuǎn)換順序OFF/OFF---》ON/OFF---》ON/ON---》OFF/ON---》OFF/OFF

通過按鍵控制L1L2的狀態(tài),每次狀態(tài)轉(zhuǎn)換需連續(xù)按鍵5次

L1L2的初始狀態(tài)OFF/OFF

e9a65d1a-e426-11eb-a97a-12bb97331649.png

狀態(tài)轉(zhuǎn)換圖

在狀態(tài)機(jī)編程中,正確的順序應(yīng)該是先有狀態(tài)轉(zhuǎn)換圖,后有程序,程序應(yīng)該是根據(jù)設(shè)計(jì)好的狀態(tài)圖寫出來的。

下面這張按鍵控制流水燈狀態(tài)轉(zhuǎn)換圖,是用UML(統(tǒng)一建模語言)的語法元素畫出來的,語法不是很標(biāo)準(zhǔn),但拿來解釋問題足夠了。

e9db62d0-e426-11eb-a97a-12bb97331649.png

上圖中,圓角矩形代表狀態(tài)機(jī)的各個狀態(tài),里面標(biāo)注著狀態(tài)的名稱。

帶箭頭的直線或弧線代表狀態(tài)遷移,起于初態(tài),止于次態(tài)。

圖中的文字內(nèi)容是對遷移的說明,格式是:事件[條件]/動作列表(后兩項(xiàng)可選)。

“事件[條件]/動作列表”要說明的意思是:如果在某個狀態(tài)下發(fā)生了“事件”,并且狀態(tài)機(jī)

滿足“[條件]”,那么就要執(zhí)行此次狀態(tài)轉(zhuǎn)移,同時(shí)要產(chǎn)生一系列“動作”,以響應(yīng)事件。在這個例子里,我用“KEY”表示擊鍵事件。

圖中有一個黑色實(shí)心圓點(diǎn),表示狀態(tài)機(jī)在工作之前所處的一種不可知的狀態(tài),在運(yùn)行之前狀態(tài)機(jī)必須強(qiáng)制地由這個狀態(tài)遷移到初始狀態(tài),這個遷移可以有動作列表(如圖1所示),但不需要事件觸發(fā)。

圖中還有一個包含黑色實(shí)心圓點(diǎn)的圓圈,表示狀態(tài)機(jī)生命周期的結(jié)束,這個例子中的狀態(tài)機(jī)生生不息,所以沒有狀態(tài)指向該圓圈。

程序代碼

下面是根據(jù)上述狀態(tài)轉(zhuǎn)換圖寫成的代碼:

void main(void){ sys_init(); led_off(LED1); led_off(LED2); g_stFSM.u8LedStat = LS_OFFOFF; g_stFSM.u8KeyCnt = 0; while(1) { if(test_key()==TRUE) { fsm_active(); } else { ; /*idle code*/ } }}void fsm_active(void){ if(g_stFSM.u8KeyCnt 》 3) /*擊鍵是否滿 5 次*/ { switch(g_stFSM.u8LedStat) { case LS_OFFOFF: led_on(LED1); /*輸出動作*/ g_stFSM.u8KeyCnt = 0; g_stFSM.u8LedStat = LS_ONOFF; /*狀態(tài)遷移*/ break; case LS_ONOFF: led_on(LED2); /*輸出動作*/ g_stFSM.u8KeyCnt = 0; g_stFSM.u8LedStat = LS_ONON; /*狀態(tài)遷移*/ break; case LS_ONON: led_off(LED1); /*輸出動作*/ g_stFSM.u8KeyCnt = 0; g_stFSM.u8LedStat = LS_OFFON; /*狀態(tài)遷移*/ break; case LS_OFFON: led_off(LED2); /*輸出動作*/ g_stFSM.u8KeyCnt = 0; g_stFSM.u8LedStat = LS_OFFOFF; /*狀態(tài)遷移*/ break; default: /*非法狀態(tài)*/ led_off(LED1); led_off(LED2); g_stFSM.u8KeyCnt = 0; g_stFSM.u8LedStat = LS_OFFOFF; /*恢復(fù)初始狀態(tài)*/ break; } } else { g_stFSM.u8KeyCnt++; /*狀態(tài)不遷移,僅記錄擊鍵次數(shù)*/ }}

先看一下fsm_active()這個函數(shù),g_stFSM.u8KeyCnt = 0;這個語句在switch—case里共出現(xiàn)了 5 次,前 4 次是作為各個狀態(tài)遷移的動作出現(xiàn)的。從代碼簡化提高效率的角度來看,我們完全可以把這 5 次合并為 1 次放在 switch—case 語句之前,兩者的效果是完全一樣的,代碼里之所以這樣啰嗦,是為了清晰地表明每次狀態(tài)遷移中所有的動作細(xì)節(jié),這種方式和上面狀態(tài)轉(zhuǎn)換圖所要表達(dá)的意圖是完全一致的。

再看一下g_stFSM這個狀態(tài)機(jī)結(jié)構(gòu)體變量,它有兩個成員:u8LedStat和 u8KeyCnt。用這個結(jié)構(gòu)體來做狀態(tài)機(jī)好像有點(diǎn)兒啰嗦,我們能不能只用一個像 u8LedStat 這樣的整型變量來做狀態(tài)機(jī)呢?

當(dāng)然可以!我們把上圖中的這 4 個狀態(tài)各自拆分成 5 個小狀態(tài),這樣用 20 個狀態(tài)同樣能實(shí)現(xiàn)這個狀態(tài)機(jī),而且只需要一個 unsigned char 型的變量就足夠了,每次擊鍵都會引發(fā)狀態(tài)遷移, 每遷移 5 次就能改變一次 LED 燈的狀態(tài),從外面看兩種方法的效果完全一樣。

假設(shè)我把功能要求改一下,把連續(xù)擊鍵5次改變L1L2的狀態(tài)改為連續(xù)擊鍵100次才能改變L1L2的狀態(tài)。這樣的話第二種方法需要4X100=400個狀態(tài)!而且函數(shù)fsm_active()中的switch—case語句里要有400個case,這樣的程序還有法兒寫么?!

同樣的功能改動,如果用g_stFSM這個結(jié)構(gòu)體來實(shí)現(xiàn)狀態(tài)機(jī)的話,函數(shù)fsm_active()只需要將if(g_stFSM.u8KeyCnt》3)改為if(g_stFSM.u8KeyCnt 》 98)就可以了!

g_stFSM結(jié)構(gòu)體的兩個成員中,u8LedStat可以看作是質(zhì)變因子,相當(dāng)于主變量;u8KeyCnt可以看作是量變因子,相當(dāng)于輔助變量。量變因子的逐步積累會引發(fā)質(zhì)變因子的變化。

像g_stFSM這樣的狀態(tài)機(jī)被稱作Extended State Machine。

編輯:jq

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

    關(guān)注

    2

    文章

    493

    瀏覽量

    28079

原文標(biāo)題:談?wù)剢纹瑱C(jī)編程思想——狀態(tài)機(jī)

文章出處:【微信號:gh_94c30763133f,微信公眾號:FPGA那點(diǎn)事兒】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

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

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

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

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

    你好,請問視頻格式改變的話,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

    NVME控制器設(shè)計(jì)之指令控制

    指令控制模塊由一個指令信息緩存, 一個指令組裝狀態(tài)機(jī)和一個 ID 池組成。 指令信息緩存中存放著由系統(tǒng)控制模塊寫入的待處理指令信息; 指令組裝狀態(tài)機(jī)獲取緩存的指令信息, 將其組裝成提交隊(duì)列條目寫入提交隊(duì)列中; ID 池則用于存放可使用的指令 ID。
    的頭像 發(fā)表于 04-24 10:22 ?170次閱讀
    NVME控制器設(shè)計(jì)之指令控制

    高速ssd存儲系統(tǒng)中數(shù)據(jù)緩存控制器流程控制設(shè)計(jì)

    高速SSD系統(tǒng)中流程控制模塊設(shè)計(jì)。該模塊主要由寄存器、讀狀態(tài)機(jī)、寫狀態(tài)機(jī)和命令生成模塊組成,系統(tǒng)介紹各模塊功能。
    的頭像 發(fā)表于 04-14 10:43 ?197次閱讀
    高速ssd存儲系統(tǒng)中數(shù)據(jù)緩存控制器流程控制設(shè)計(jì)

    樹莓派Pico不帶CAN接口怎么辦?難道要換方案?

    PicoPIO狀態(tài)機(jī)實(shí)現(xiàn)外設(shè):CAN-示例1Pico擁有一組PIO協(xié)處理器。它們是實(shí)時(shí)控制器,能夠以確定的時(shí)序執(zhí)行邏輯。非常適合運(yùn)行嚴(yán)格定時(shí)的序列和狀態(tài)機(jī),以及實(shí)現(xiàn)額外的外設(shè)(如這里的CAN)。序列
    的頭像 發(fā)表于 03-25 09:32 ?374次閱讀
    樹莓派Pico不帶CAN接口怎么辦?難道要換方案?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    玩轉(zhuǎn)Spring狀態(tài)機(jī)

    說起Spring狀態(tài)機(jī),大家很容易聯(lián)想到這個狀態(tài)機(jī)和設(shè)計(jì)模式中狀態(tài)模式的區(qū)別是啥呢?沒錯,Spring狀態(tài)機(jī)就是狀態(tài)模式的一種實(shí)現(xiàn),在介紹S
    的頭像 發(fā)表于 06-25 14:21 ?1274次閱讀
    玩轉(zhuǎn)Spring<b class='flag-5'>狀態(tài)機(jī)</b>

    esp32 wroom 32d是半雙工還是全雙工的?

    我的疑問有幾個: 1. esp32 wroom 32d是半雙工還是全雙工的? 2. 鏈路層在狀態(tài)機(jī)切換的時(shí)候,比如在廣播態(tài)發(fā)廣播包的時(shí)候,一個廣播事件還沒結(jié)束,狀態(tài)機(jī)能切換到掃描態(tài)嗎? 3. 一個
    發(fā)表于 06-18 06:15