STM32狀態(tài)機(jī)編程實(shí)例——全自動洗衣機(jī)(上)
本篇,繼續(xù)使用狀態(tài)機(jī)編程,來實(shí)現(xiàn)一個(gè)更有趣的功能——全自動洗衣機(jī)。
下面是一個(gè)全自動洗衣機(jī)的控制面板:

面板上有4個(gè)按鍵:
電源:控制洗衣機(jī)通電與斷電
水位:選擇洗衣時(shí)需要的水位,有1~8個(gè)水位
程序:選擇不同的洗衣模式,有1~10個(gè)模式
01:標(biāo)準(zhǔn)
02:輕柔
03:快速
...
10:桶風(fēng)干
啟動/暫停:用于啟動或暫停洗衣任務(wù)
面板上還有一個(gè)數(shù)碼管,用于顯示當(dāng)前的工作狀態(tài)與剩余時(shí)間,可顯示的工作模式有:
AA:浸泡
BB:洗滌
CC:漂洗
DD:脫水
本篇,就按照這款洗衣機(jī)的操作方式實(shí)現(xiàn)對應(yīng)的洗衣機(jī)控制邏輯。需注意的是:
實(shí)際的洗衣機(jī)有水位檢測傳感器,本篇中,暫用時(shí)間延時(shí)模擬水位的增加,且默認(rèn)開機(jī)時(shí)水位為0
實(shí)際的洗衣機(jī)中的洗衣模式,會根據(jù)不同的模式自動設(shè)置清洗次數(shù)與每次清洗的時(shí)間以及清洗力度,本篇為了簡化起見,清洗模式的設(shè)置僅用于區(qū)分不同的清洗次數(shù)
某些特殊的清洗模式,如單獨(dú)的脫水,桶風(fēng)干等,本篇暫不實(shí)現(xiàn)
對于狀態(tài)的顯示 ,本篇先以串口打印的實(shí)現(xiàn)展示,下篇使用OLED小屏幕來顯示不同清洗狀態(tài)的圖標(biāo)等信息
2 畫狀態(tài)圖
根據(jù)上面分析的全自動洗衣機(jī)的功能,以及我們自己使用洗衣機(jī)時(shí)的經(jīng)驗(yàn),可以畫出如下的全自動洗衣機(jī)的狀態(tài)圖:

首先是上電開機(jī),洗衣機(jī)可能會開機(jī)自檢,檢測洗衣機(jī)的各個(gè)部件是否正常,次過程很短。
然后就處于空閑狀態(tài),此時(shí)用戶可以設(shè)置水位與清洗模式,若不設(shè)置,則為默認(rèn)的水位與洗衣模式。
接著觸發(fā)開始按鍵后,就開始清洗了,一般流程就是:加水、清洗、排水、甩干、結(jié)束。
根據(jù)不同的清洗模式,加水、清洗和排水這3個(gè)過程會循環(huán)執(zhí)行一定的次數(shù)。
另外,在不同的工作階段,按下暫停鍵可以讓洗衣任務(wù)暫停,再按繼續(xù)可讓洗衣任務(wù)繼續(xù)。
3 編程實(shí)現(xiàn)
3.1 多按鍵檢測功能
本篇介紹的洗衣機(jī)的按鍵,僅需要檢測按鍵單擊即可,不需要雙擊與長按功能,因此,可使用之前文章介紹的最基礎(chǔ)的按鍵狀態(tài)機(jī)來為洗衣機(jī)狀態(tài)機(jī)提供按鍵事件。
之前介紹的按鍵狀態(tài)機(jī),只有一個(gè)按鍵,本篇需要用到4個(gè)按鍵(除去電源鍵,3個(gè)也可以),因此,需要對按鍵狀態(tài)機(jī)稍加修改,實(shí)現(xiàn)按鍵狀態(tài)機(jī)的復(fù)用。
之前介紹的按鍵狀態(tài)機(jī),使用了幾個(gè)全局變量來表示狀態(tài),更合理的做法是將其封裝起來:
注意,額外增加了一個(gè)按鍵索引值,用來告訴狀態(tài)機(jī)要檢測哪個(gè)按鍵。
再將原來的按鍵狀態(tài)機(jī)程序,通過入?yún)?/strong>的形式將上述定義的結(jié)構(gòu)體傳入,并通過函數(shù)返回的形式返回按鍵是否被按下。
這樣修改后的按鍵狀態(tài)機(jī),就是一個(gè)獨(dú)立的模塊了,可以通過傳入不同的參數(shù),實(shí)現(xiàn)不同按鍵的檢測。
對于本篇需要的4個(gè)按鍵的檢測,就可以定義4個(gè)數(shù)據(jù)結(jié)構(gòu)體,分別調(diào)用4次狀態(tài)機(jī)函數(shù)即可,實(shí)現(xiàn)代碼的復(fù)用。
其中,multi_key_check函數(shù),放到50ms周期的定時(shí)器中斷服務(wù)函數(shù)中,使按鍵狀態(tài)機(jī)程序運(yùn)行起來。
get_press_key_idx函數(shù),用于洗衣機(jī)程序來獲取不同按鍵的按下事件,每次獲取后,將按鍵事件清除(g_keyPressIdx設(shè)為無效值-1)
3.2 洗衣功能
按照上面繪制的洗衣機(jī)狀態(tài)圖,使用switch-case法編寫對應(yīng)的程序即可:
這里將洗衣機(jī)不同狀態(tài)時(shí)的處理邏輯,都分別使用函數(shù)來實(shí)現(xiàn),并將其返回值作為下一個(gè)要跳轉(zhuǎn)的狀態(tài)。
各個(gè)狀態(tài)的處理函數(shù)如下:
對于按鍵的獲取,這里定義了幾個(gè)對應(yīng)的功能按鍵,并從按鍵狀態(tài)機(jī)函數(shù)中獲取按鍵索引,再轉(zhuǎn)為洗衣機(jī)程序所需的對應(yīng)功能按鍵:
洗衣機(jī)狀態(tài)機(jī)主程序,可以放到main函數(shù)中,每隔100ms調(diào)用一次,使其運(yùn)行起來:
3.3 測試
將代碼燒寫到STM32板子中,通過3個(gè)按鍵(電源鍵暫不使用)操作,并通過串口打印,查看全自動洗衣機(jī)的運(yùn)行情況:

4 總結(jié)
本篇實(shí)現(xiàn)了一款全自動洗衣機(jī)的基礎(chǔ)洗衣控制流程,可實(shí)現(xiàn)不同水位與清洗次數(shù)的設(shè)置,以及任務(wù)的暫停與繼續(xù)。此外,通過對之前按鍵狀態(tài)機(jī)的進(jìn)一步優(yōu)化修改,實(shí)現(xiàn)了按鍵狀態(tài)機(jī)的復(fù)用,實(shí)現(xiàn)多個(gè)按鍵的檢測。下篇文章將進(jìn)一步進(jìn)行功能優(yōu)化,添加OLED小屏幕實(shí)現(xiàn)不同狀態(tài)的可視化展示。