日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 嵌入式 > 嵌入式大雜燴
[導讀]星標「嵌入式大雜燴」,一起進步!來源:https://blog.csdn.net/qq_36969440/article/details/110387716狀態(tài)機基本術語現態(tài):是指當前所處的狀態(tài)。條件:又稱為“事件”,當一個條件被滿足,將會觸發(fā)一個動作,或者執(zhí)行一次狀態(tài)的遷移。動...

星標嵌入式大雜燴」,一起進步!

編程學習筆記,同時,公眾號內包含大量的學習資源。歡迎關注,一同交流學習,共同進步!" data-from="0">來源:https://blog.csdn.net/qq_36969440/article/details/110387716

狀態(tài)機基本術語

現態(tài):是指當前所處的狀態(tài)。條件:又稱為“事件”,當一個條件被滿足,將會觸發(fā)一個動作,或者執(zhí)行一次狀態(tài)的遷移。動作:條件滿足后執(zhí)行的動作。動作執(zhí)行完畢后,可以遷移到新的狀態(tài),也可以仍舊保持原狀態(tài)。

動作不是必需的,當條件滿足后,也可以不執(zhí)行任何動作,直接遷移到新狀態(tài)。次態(tài):條件滿足后要遷往的新狀態(tài)?!按螒B(tài)”是相對于“現態(tài)”而言的,“次態(tài)”一旦被激活,就轉變成新的“現態(tài)”了。

傳統(tǒng)有限狀態(tài)機Fsm實現方法

如圖,是一個定時計數器,計數器存在兩種狀態(tài),一種為設置狀態(tài),一種為計時狀態(tài)

設置狀態(tài)

“ ” “-” 按鍵對初始倒計時進行設置 當計數值設置完成,點擊確認鍵啟動計時 ,即切換到計時狀態(tài)

計時狀態(tài)

按下“ ” “-” 會進行密碼的輸入?!?”表示1 ,“-”表示輸入0 ,密碼共有4位?

確認鍵:只有輸入的密碼等于默認密碼,按確認鍵才能停止計時,否則計時直接到零,并執(zhí)行相關操作

嵌套switch

??????/***************************************
??????1.列出所有的狀態(tài)
??????***************************************/

??????typedef?enum{
??????????SETTING,
??????????TIMING
??????}STATE_TYPE;
??????/***************************************
??????2.列出所有的事件
??????***************************************/

??????typedef?enum{
?????????UP_EVT,
??????????DOWN_EVT,
??????????ARM_EVT,
??????????TICK_EVT
??????}EVENT_TYPE;
??????/***************************************
??????3.定義和狀態(tài)機相關結構
??????***************************************/

??????struct??bomb
??????{

??????????uint8_t?state;
??????????uint8_t?timeout;
??????????uint8_t?code;
??????????uint8_t?defuse_code;
??????}bomb1;
??????/***************************************
??????4.初始化狀態(tài)機
??????***************************************/

??????void?bomb1_init(void)
??????
{
??????????bomb1.state?=?SETTING;
??????????bomb1.defuse_code?=?6;????//0110?
??????}
??????/***************************************
??????5.?狀態(tài)機事件派發(fā)
??????***************************************/

??????void?bomb1_fsm_dispatch(EVENT_TYPE?evt?,void*?param)
??????
{
??????????switch(bomb1.state)
??????????{
??????????????case?SETTING:
??????????????{
??????????????????switch(evt)
??????????????????{
??????????????????????case?UP_EVT:????//?" "???按鍵按下事件
????????????????????????if(bomb1.timeout60)?? bomb1.timeout;
??????????????????????????bsp_display(bomb1.timeout);
??????????????????????break;
??????????????????????case?DOWN_EVT:??//?"-"???按鍵按下事件
??????????????????????????if(bomb1.timeout?>?0)??--bomb1.timeout;
??????????????????????????bsp_display(bomb1.timeout);
??????????????????????break;
??????????????????????case?ARM_EVT:???//?"確認"?按鍵按下事件
??????????????????????????bomb1.state?=?TIMING;
??????????????????????????bomb1.code??=?0;
??????????????????????break;
??????????????????}
??????????????}?break;?
??????????????case?TIMING:
??????????????{
??????????????????switch(evt)
??????????????????{
??????????????????????case?UP_EVT:????//?" "???按鍵按下事件
?????????????????????????bomb1.code?=?(bomb1.code?<<1)?|0x01;
??????????????????????break;
??????????????????????case?DOWN_EVT:??//?"-"???按鍵按下事件
??????????????????????????bomb1.code?=?(bomb1.code?<<1);?
??????????????????????break;
??????????????????????case?ARM_EVT:???//?"確認"?按鍵按下事件
??????????????????????????if(bomb1.code?==?bomb1.defuse_code){
??????????????????????????????bomb1.state?=?SETTING;
??????????????????????????}
??????????????????????????else{
???????????????????????????bsp_display("bomb!")
??????????????????????????}
??????????????????????break;
??????????????????????case?TICK_EVT:
??????????????????????????if(bomb1.timeout)
??????????????????????????{
??????????????????????????????--bomb1.timeout;
??????????????????????????????bsp_display(bomb1.timeout);
??????????????????????????}
??????????????????????????if(bomb1.timeout?==?0)
??????????????????????????{
??????????????????????????????bsp_display("bomb!")
??????????????????????????}
??????????????????????break;
??????????????????}???
??????????????}break;
??????????}
??????}

優(yōu)點:

  • 簡單,代碼閱讀連貫,容易理解

缺點

  • 當狀態(tài)或事件增多時,代碼狀態(tài)函數需要經常改動,狀態(tài)事件處理函數會代碼量會不斷增加

  • 狀態(tài)機沒有進行封裝,移植性差。

  • 沒有實現狀態(tài)的進入和退出的操作。進入和退出在狀態(tài)機中尤為重要

  • 進入事件:只會在剛進入時觸發(fā)一次,主要作用是對狀態(tài)進行必要的初始化

  • 退出事件:只會在狀態(tài)切換時觸發(fā)一次 ,主要的作用是清除狀態(tài)產生的中間參數,為下次進入提供干凈環(huán)境

狀態(tài)表

二維狀態(tài)轉換表

狀態(tài)機可以分為狀態(tài)和事件 ,狀態(tài)的躍遷都是受事件驅動的,因此可以通過一個二維表格來表示狀態(tài)的躍遷。

(*) 僅當( code == defuse_code) 時才發(fā)生到setting 的轉換。

??????/*1.列出所有的狀態(tài)*/
??????enum
??????{
??????????SETTING,
??????????TIMING,
??????????MAX_STATE
??????};
??????/*2.列出所有的事件*/
??????enum
??????{
??????????UP_EVT,
??????????DOWN_EVT,
??????????ARM_EVT,
??????????TICK_EVT,
??????????MAX_EVT
??????};
??????
??????/*3.定義狀態(tài)表*/
??????typedef?void?(*fp_state)(EVT_TYPE?evt?,?void*?param);
??????static??const?fp_state??bomb2_table[MAX_STATE][MAX_EVENT]?=
??????{
??????????{setting_UP?,?setting_DOWN?,?setting_ARM?,?null},
??????????{setting_UP?,?setting_DOWN?,?setting_ARM?,?timing_TICK}
??????};
??????
??????struct?bomb_t
??????{

??????????const?fp_state?const?*state_table;?/*?the?State-Table?*/
??????????uint8_t?state;?/*?the?current?active?state?*/
??????????
??????????uint8_t?timeout;
??????????uint8_t?code;
??????????uint8_t?defuse_code;
??????};
??????struct?bomb?bomb2=
??????{

??????????.state_table?=?bomb2_table;
??????}
??????void?bomb2_init(void)
??????
{
??????????bomb2.defuse_code?=?6;?//?0110
??????????bomb2.state?=?SETTING;
??????}
??????
??????void?bomb2_dispatch(EVT_TYPE?evt?,?void*?param)
??????
{
??????????fp_state??s?=?NULL;
??????????if(evt?>?MAX_EVT)
??????????{
??????????????LOG("EVT?type?error!");
??????????????return;
??????????}
??????????s?=?bomb2.state_table[bomb2.state?*?MAX_EVT? ?evt];
??????????if(s?!=?NULL)
??????????{
??????????????s(evt?,?param);
??????????}
??????}
??????/*列出所有的狀態(tài)對應的事件處理函數*/
??????void?setting_UP(EVT_TYPE?evt,?void*?param)
??????
{
??????????if(bomb1.timeout60)?? bomb1.timeout;
??????????bsp_display(bomb1.timeout);
??????}

優(yōu)點

  • 各個狀態(tài)面向用戶相對獨立,增加事件和狀態(tài)不需要去修改先前已存在的狀態(tài)事件函數。

  • 可將狀態(tài)機進行封裝,有較好的移植性 函數指針的安全轉換 , 利用下面的特性,用戶可以擴展帶有私有屬性的狀態(tài)機和事件而使用統(tǒng)一的基礎狀態(tài)機接口

    typedef?void?(*Tran)(struct?StateTableTag?*me,?Event?const?*e);
    void?Bomb2_setting_ARM?(Bomb2?*me,?Event?const?*e);
    typedef?struct?Bomb
    {

    ???struct?StateTableTag?*me;??//必須為第一個成員
    ????uint8_t?private;
    }

缺點

  • 函數粒度太小是最明顯的一個缺點,一個狀態(tài)和一個事件就會產生一個函數,當狀態(tài)和事件較多時,處理函數將增加很快,在閱讀代碼時,邏輯分散。

  • 沒有實現進入退出動作。

一維狀態(tài)轉換表

實現原理:

?typedef?void?(*fp_action)(EVT_TYPE?evt,void*?param);
????
????/*轉換表基礎結構*/
????struct?tran_evt_t
????{

???????EVT_TYPE?evt;
????????uint8_t?next_state;
????};
????/*狀態(tài)的描述*/
????struct??fsm_state_t
????{

????????fp_action??enter_action;??????//進入動作
????????fp_action??exit_action;???//退出動作
????????fp_action??action;???????????
????????
????????tran_evt_t*?tran;????//轉換表
????????uint8_t?????tran_nb;?//轉換表的大小
????????const?char*?name;
????}
????/*狀態(tài)表本體*/
????#define??ARRAY(x)???x,sizeof(x)/sizeof(x[0])
????const?struct??fsm_state_t??state_table[]=
????{

????????{setting_enter?,?setting_exit?,?setting_action?,?ARRAY(set_tran_evt),"setting"?},
????????{timing_enter?,?timing_exit?,?timing_action?,?ARRAY(time_tran_evt),"timing"?}
????};
????
????/*構建一個狀態(tài)機*/
????struct?fsm
????{

????????const?struct?state_t?*?state_table;?/*?the?State-Table?*/
????????uint8_t?cur_state;??????????????????????/*?the?current?active?state?*/
????????
????????uint8_t?timeout;
????????uint8_t?code;
????????uint8_t?defuse_code;
????}bomb3;
????
????/*初始化狀態(tài)機*/
????void??bomb3_init(void)
????
{
????????bomb3.state_table?=?state_table;??//指向狀態(tài)表
????????bomb3.cur_state?=?setting;
????????bomb3.defuse_code?=?8;?//1000
????}
????/*狀態(tài)機事件派發(fā)*/
????void??fsm_dispatch(EVT_TYPE?evt?,?void*?param)
????
{
????????tran_evt_t*?p_tran?=?NULL;
????????
????????/*獲取當前狀態(tài)的轉換表*/
????????p_tran?=?bomb3.state_table[bomb3.cur_state]->tran;
????????
????????/*判斷所有可能的轉換是否與當前觸發(fā)的事件匹配*/
????????for(uint8_t?i=0;i????????{
????????????if(p_tran[i]->evt?==?evt)//事件會觸發(fā)轉換
????????????{
????????????????if(NULL?!=?bomb3.state_table[bomb3.cur_state].exit_action){
??????????????bomb3.state_table[bomb3.cur_state].exit_action(NULL);??//執(zhí)行退出動作
?????????????}
????????????????if(bomb3.state_table[_tran[i]->next_state].enter_action){
???????????????????bomb3.state_table[_tran[i]->next_state].enter_action(NULL);//執(zhí)行進入動作
????????????????}
????????????????/*更新當前狀態(tài)*/
????????????????bomb3.cur_state?=?p_tran[i]->next_state;
????????????}
????????????else
????????????{
?????????????????bomb3.state_table[bomb3.cur_state].action(evt,param);
????????????}
????????}
????}
????/*************************************************************************
????setting狀態(tài)相關
????************************************************************************/

????void?setting_enter(EVT_TYPE?evt?,?void*?param)
????
{
????????
????}
????void?setting_exit(EVT_TYPE?evt?,?void*?param)
????
{
????????
????}
????void?setting_action(EVT_TYPE?evt?,?void*?param)
????
{
????????
????}
????tran_evt_t?set_tran_evt[]=
????{
????????{ARM?,?timing},
????}
????/*timing?狀態(tài)相關*/

優(yōu)點

  • 各個狀態(tài)面向用戶相對獨立,增加事件和狀態(tài)不需要去修改先前已存在的狀態(tài)事件函數。

  • 實現了狀態(tài)的進入和退出

  • 容易根據狀態(tài)躍遷圖來設計 (狀態(tài)躍遷圖列出了每個狀態(tài)的躍遷可能,也就是這里的轉換表)

  • 實現靈活,可實現復雜邏輯,如上一次狀態(tài),增加監(jiān)護條件來減少事件的數量。可實現非完全事件驅動

缺點

  • 函數粒度較?。ū榷S小且增長慢),可以看到,每一個狀態(tài)需要至少3個函數,還需要列出所有的轉換關系。

QP嵌入式實時框架

特點

事件驅動型編程

好萊塢原則:和傳統(tǒng)的順序式編程方法例如“超級循環(huán)”,或傳統(tǒng)的RTOS 的任務不同。絕大多數的現代事件驅動型系統(tǒng)根據好萊塢原則被構造,(Don’t call me; I’ll call you.)

面向對象

類和單一繼承。

工具

QM ,一個通過UML類圖來描述狀態(tài)機的軟件,并且可以自動生成C代碼:

QS軟件追蹤工具:

QEP實現有限狀態(tài)機Fsm

????/*?qevent.h?----------------------------------------------------------------*/
??????typedef?struct?QEventTag?
??????{
??
????????QSignal?sig;?????
???????uint8_t?dynamic_;??
??????}?QEvent;
??????/*?qep.h?-------------------------------------------------------------------*/
??????typedef?uint8_t?QState;?/*?status?returned?from?a?state-handler?function?*/
??????typedef?QState?(*QStateHandler)?(void?*me,?QEvent?const?*e);?/*?argument?list?*/
??????typedef?struct?QFsmTag???/*?Finite?State?Machine?*/
??????{
?
????????QStateHandler?state;?????/*?current?active?state?*/
??????}QFsm;
??????
??????#define?QFsm_ctor(me_,?initial_)?((me_)->state?=?(initial_))
??????void?QFsm_init?(QFsm?*me,?QEvent?const?*e);
??????void?QFsm_dispatch(QFsm?*me,?QEvent?const?*e);
??????
??????#define?Q_RET_HANDLED?((QState)0)
??????#define?Q_RET_IGNORED?((QState)1)
??????#define?Q_RET_TRAN?((QState)2)
??????#define?Q_HANDLED()?(Q_RET_HANDLED)
??????#define?Q_IGNORED()?(Q_RET_IGNORED)
??????
???????#define?Q_TRAN(target_)?(((QFsm?*)me)->state?=?(QStateHandler)???(target_),Q_RET_TRAN)
??????
??????enum?QReservedSignals
??????{
??????????Q_ENTRY_SIG?=?1,?
????????Q_EXIT_SIG,?
????????Q_INIT_SIG,?
????????Q_USER_SIG?
??????};
??????
??????/*?file?qfsm_ini.c?---------------------------------------------------------*/
??????#include?"qep_port.h"?/*?the?port?of?the?QEP?event?processor?*/
??????#include?"qassert.h"?/*?embedded?systems-friendly?assertions?*/
??????void?QFsm_init(QFsm?*me,?QEvent?const?*e)?
??????
{
??????????(*me->state)(me,?e);?/*?execute?the?top-most?initial?transition?*/
???????/*?enter?the?target?*/
????????(void)(*me->state)(me?,?
本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯系該專欄作者,如若文章內容侵犯您的權益,請及時聯系本站刪除。
換一批
延伸閱讀

LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: 驅動電源

在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設備,其驅動電源的性能直接關系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅動電源設計中至關重要的兩個環(huán)節(jié),集成化方案的設計成為提升電機驅動性能的關鍵。

關鍵字: 工業(yè)電機 驅動電源

LED 驅動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設備的使用壽命。然而,在實際應用中,LED 驅動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設計、生...

關鍵字: 驅動電源 照明系統(tǒng) 散熱

根據LED驅動電源的公式,電感內電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關鍵字: LED 設計 驅動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產業(yè)的重要發(fā)展方向。電動汽車的核心技術之一是電機驅動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅動系統(tǒng)中的關鍵元件,其性能直接影響到電動汽車的動力性能和...

關鍵字: 電動汽車 新能源 驅動電源

在現代城市建設中,街道及停車場照明作為基礎設施的重要組成部分,其質量和效率直接關系到城市的公共安全、居民生活質量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關鍵字: 發(fā)光二極管 驅動電源 LED

LED通用照明設計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數校正(PFC)、空間受限和可靠性等。

關鍵字: LED 驅動電源 功率因數校正

在LED照明技術日益普及的今天,LED驅動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關鍵字: LED照明技術 電磁干擾 驅動電源

開關電源具有效率高的特性,而且開關電源的變壓器體積比串聯穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現在的LED驅動電源

關鍵字: LED 驅動電源 開關電源

LED驅動電源是把電源供應轉換為特定的電壓電流以驅動LED發(fā)光的電壓轉換器,通常情況下:LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: LED 隧道燈 驅動電源
關閉