嚴(yán)一涵
當(dāng)今,數(shù)字電路的使用越來越廣泛,眾多的智能設(shè)備都依靠數(shù)字電路處理邏輯運(yùn)算,其重要性不言而喻。但作為初學(xué)者,學(xué)習(xí)數(shù)字電路的基本原理要面臨諸多難題。傳統(tǒng)學(xué)習(xí)方式需購買元器件進(jìn)行組裝,對動手能力有極高的要求,而且實(shí)際元件有一定的精度誤差,影響電路的運(yùn)行結(jié)果,使初學(xué)者難以理解。另一種學(xué)習(xí)方式為通過仿真軟件進(jìn)行學(xué)習(xí)研究,但許多仿真軟件需要付費(fèi),而且對計算機(jī)的配置也有一定的要求,也需要用戶擁有足夠的專業(yè)知識,同樣對初學(xué)者有一定的困難[1]。
基于上述背景,本文設(shè)計并實(shí)現(xiàn)一種數(shù)字電路在線仿真平臺,可以直接在瀏覽器中使用。該平臺具有硬盤空間占用少、兼容不同設(shè)備及可視化交互的特點(diǎn),用戶無需了解較多的專業(yè)知識便可以利用仿真平臺直觀地理解電路,大大降低了學(xué)習(xí)成本,為數(shù)字電路初學(xué)者提供了諸多便利[2-3]。
1)添加/刪除/拖動/連接節(jié)點(diǎn)。為了讓用戶自由設(shè)計電路,平臺應(yīng)允許用戶通過鼠標(biāo)點(diǎn)擊,在任意空白位置添加任意數(shù)量的節(jié)點(diǎn)。如果用戶添加的節(jié)點(diǎn)有誤,或是需要修改或移動部分電路,平臺應(yīng)允許選中若干節(jié)點(diǎn)并進(jìn)行刪除或者拖動,并在用戶拖動節(jié)點(diǎn)時不會破壞原有的電路信息。如果用戶希望建立節(jié)點(diǎn)之間的關(guān)系,可以用導(dǎo)線或者非門連接任意兩個節(jié)點(diǎn)。最后,如果用戶想要重復(fù)使用部分電路,或者從示例中拷貝出部分元件,平臺應(yīng)允許用戶進(jìn)行復(fù)制、剪切、粘貼等操作。
2)電路展示及運(yùn)行。添加的電路節(jié)點(diǎn)應(yīng)以不用顏色標(biāo)識不同的狀態(tài)。本文設(shè)計節(jié)點(diǎn)不通電時呈灰色,在通電時,變?yōu)樗{(lán)色進(jìn)行標(biāo)識,如果節(jié)點(diǎn)被作為電源,將會變成醒目的紅色。導(dǎo)線在通電時同樣變成藍(lán)色。而非門由粗細(xì)不同的兩段組成,用于標(biāo)識輸入端與輸出端的位置。當(dāng)用戶想要觀察細(xì)節(jié),或者縱觀全局時,可以自由縮放。當(dāng)用戶改變元件,或者元件被其他元件所影響時,應(yīng)該實(shí)時反映這一變化及其連鎖影響,并展示于屏幕上。對于示例電路,同樣允許用戶對其進(jìn)行調(diào)試和運(yùn)行[4]。
3)導(dǎo)入導(dǎo)出電路。為保存已設(shè)計電路信息,應(yīng)允許用戶將電路信息進(jìn)行導(dǎo)入導(dǎo)出。
1)云服務(wù)平臺構(gòu)建。用戶往往不希望下載體積巨大的軟件,因此,本文以云平臺的模式進(jìn)行仿真平臺的設(shè)計,以網(wǎng)頁的形式將平臺呈現(xiàn)給用戶。同時,示例電路等數(shù)據(jù)應(yīng)存儲于云端,當(dāng)用戶需要時再進(jìn)行加載,這樣就可以占用用戶更少的內(nèi)存空間,提升仿真平臺的流暢性。
2)多元交互方式。不同用戶的個人操作習(xí)慣可能存在很大的差別,有些偏好純鼠標(biāo)操作,有些更喜歡使用鍵盤快捷鍵。所以,仿真平臺需要同時支持鼠標(biāo)和鍵盤快捷鍵操作,以適應(yīng)不同用戶的習(xí)慣。
3)兼容性。不同的用戶可能會使用不同的瀏覽器,為了讓更多的用戶都能夠正常使用,平臺應(yīng)兼容IE/Chrome/FireFox/Safari 等不同內(nèi)核的瀏覽器。
4)移動端。部分用戶希望使用手機(jī)等移動智能終端對電路進(jìn)行編輯及運(yùn)行仿真,因此平臺應(yīng)支持與移動端對應(yīng)的一系列觸屏事件[5]。
首先定義“集合”類保存節(jié)點(diǎn)和連接信息,并使用JQuery 響應(yīng)各類鼠標(biāo)及鍵盤事件。當(dāng)用戶單擊節(jié)點(diǎn)、連接線,或者框出一部分節(jié)點(diǎn)時,枚舉得到焦點(diǎn)的物件,加入焦點(diǎn)集合,并在這些物件周圍渲染明顯的黑影提醒用戶。
當(dāng)用戶單擊按鈕或使用快捷鍵時,響應(yīng)事件進(jìn)入添加模式,并讓按鈕高亮提醒用戶。之后,響應(yīng)用戶單擊的事件,如果單擊的區(qū)域?qū)儆诋嫴嫉目瞻讌^(qū)域,也即添加操作合法時,將節(jié)點(diǎn)添加入集合并選中,否則僅僅選中所單擊的既有節(jié)點(diǎn)。如果進(jìn)入添加模式前,已經(jīng)選取若干節(jié)點(diǎn),則讓這些節(jié)點(diǎn)分別與現(xiàn)在的節(jié)點(diǎn)連接,以實(shí)現(xiàn)連接節(jié)點(diǎn)的功能。接下來響應(yīng)用戶按下Delete 或者在菜單欄中點(diǎn)擊刪除的事件,刪除焦點(diǎn)集合中的物件。如果被刪除的節(jié)點(diǎn)上還有連接線,則一并刪除這些連接線。響應(yīng)拖動事件,對焦點(diǎn)集合中的物件修改其坐標(biāo),并顯示在屏幕上。當(dāng)用戶點(diǎn)擊“切換狀態(tài)”時,枚舉焦點(diǎn)集合中的所有元素,逐一修改其信息,普通節(jié)點(diǎn)與電源互相轉(zhuǎn)換,導(dǎo)線與非門互相轉(zhuǎn)換。
本文使用HTML5Canvas 渲染電路的圖形化界面,使用Javascript 對所有的元件狀態(tài)進(jìn)行模擬。具體的模擬方式如下:
為每一個節(jié)點(diǎn)設(shè)定一個自然數(shù)“電勢”。作為電源的節(jié)點(diǎn)擁有最高的電勢,未通電的節(jié)點(diǎn)電勢為零。當(dāng)一個節(jié)點(diǎn)的電勢被改變時,或者用戶操作了一個節(jié)點(diǎn)時,先刪去節(jié)點(diǎn)原有向外的信號,若它的電勢不為零,則向?qū)Ь€連接的所有親屬節(jié)點(diǎn)釋放一個數(shù)值為電勢減一的信號;若電勢為零,則向此點(diǎn)出發(fā)的非門另一端釋放一個數(shù)值為“最高電勢”的信號。收到信號的節(jié)點(diǎn),會取周圍存在的信號的最大值設(shè)定自己的電勢,若數(shù)值與先前不同,則重復(fù)上述的過程。如此一來,就可以讓電流進(jìn)行傳遞,并讓失去電源供應(yīng)的電路迅速失去其電勢。對于沒有變化的部分,不會消耗無意義的計算資源。在此基礎(chǔ)上,枚舉所有物件及其狀態(tài),將其繪制到Canvas 中,就可以實(shí)現(xiàn)完整的仿真了。
當(dāng)用戶點(diǎn)擊導(dǎo)出時,將電路轉(zhuǎn)化為JSON 文檔。給節(jié)點(diǎn)集合中的點(diǎn)標(biāo)號,將其坐標(biāo)及其是否是電源分別記入x,y,power 字段,列為points 數(shù)組。將連接線集合中每個連接線的兩段標(biāo)號,以及連接線是否作為非門記錄入pointFrom,pointTo,notGate字段,列為lines 數(shù)組。最終導(dǎo)出的JSON 文檔中就含有points,lines 兩個字段,分別表示上述兩個數(shù)組,并將此內(nèi)容顯示在瀏覽器中,以供復(fù)制。當(dāng)用戶點(diǎn)擊導(dǎo)入時,顯示一個輸入框,將JSON 文檔復(fù)原為電路。枚舉points 數(shù)組,將每個元素加入節(jié)點(diǎn)集合;枚舉lines 數(shù)組,通過標(biāo)號找到相應(yīng)節(jié)點(diǎn)并建立連接。在節(jié)點(diǎn)被創(chuàng)建或者連接線被創(chuàng)建時,自動向相關(guān)節(jié)點(diǎn)釋放一個信號,更新其狀態(tài),那么電路就被復(fù)原了。代碼詳見https∶//github.com/yyhhenry/redstone。
單擊“添加元素”按鈕或單擊空白處,可以自由添加節(jié)點(diǎn)。選中若干節(jié)點(diǎn)并單擊“刪除元素”,可以自由刪去節(jié)點(diǎn)。按下鼠標(biāo)后可以拖動節(jié)點(diǎn),也可以通過先選中節(jié)點(diǎn),再單擊“添加元素”,最后單擊另一節(jié)點(diǎn)這樣的操作方式,進(jìn)行連接線的添加。選中節(jié)點(diǎn)或連接線,單擊切換狀態(tài),可以讓普通節(jié)點(diǎn)變成電源或讓連接線變成非門。Ctrl+A,Ctrl+X,Ctrl+C,Ctrl+V 等快捷鍵均可以在平臺中正常使用。同時打開兩個電路時,剪切板可以跨越文件公用。除此之外,本平臺在移動端上同樣可以編輯和運(yùn)行數(shù)字電路。效果示例如下圖所示:

圖1 添加電路示例

圖2 跨頁復(fù)制簡單邏輯門示例
通過菜單欄打開示例電路,根據(jù)示例電路附帶的文字說明,觸發(fā)該示例中的復(fù)位節(jié)點(diǎn),觀察到電路的一系列變化,最終完成復(fù)位操作,也就是兩側(cè)指示燈在第一位,且輸出端全為零的初始狀態(tài)。在整個電路仿真的運(yùn)行過程中,節(jié)點(diǎn)的變化狀態(tài)均有所展示。

圖3 電路仿真運(yùn)行示例

圖4 導(dǎo)出電路示例

圖5 導(dǎo)入電路示例
當(dāng)電路編輯完成后,單擊菜單欄中的導(dǎo)出電路,電路數(shù)據(jù)信息被轉(zhuǎn)化為一個JSON 文檔,直接Ctrl+A 選中便可進(jìn)行復(fù)制或保存。單擊導(dǎo)入并在輸入框里粘貼所要打開的電路,就可以復(fù)原電路。
本文實(shí)現(xiàn)了一種數(shù)字電路仿真平臺,初步實(shí)現(xiàn)了模擬簡單數(shù)字電路的功能,具有簡單易懂的操作模式和運(yùn)行界面,降低了學(xué)習(xí)數(shù)字電路的難度和成本,適合數(shù)字電路初學(xué)者使用,也可用于課堂教學(xué)。
在未來,數(shù)字電路仿真平臺還將從以下方面進(jìn)行改進(jìn):1)在菜單欄中直接提供封裝好的與門、或門、異或門、觸發(fā)器等常用元件。2)將電路導(dǎo)入導(dǎo)出的方式改為二進(jìn)制文件的形式,并以拖拽方式打開。3)允許用戶注冊登錄賬號,提供將設(shè)計電路上傳保存至云端的功能。