至少有兩個(gè)因素表明轉(zhuǎn)向功能更強(qiáng)大的處理器并不一定意味著需要占用更多比特。隨著應(yīng)用程序的成熟,功能強(qiáng)大,功能特定的處理器或引擎可用于承擔(dān)大部分繁重的工作。例如,使用MP3播放器,您可以購買完整的數(shù)字音頻解碼引擎。您只需要一個(gè)用戶
接口和PC的I/O接口,可以充實(shí)您的數(shù)字播放器。 8位處理器可以有效地處理這些功能。而且,對(duì)于需要更多功能的任務(wù),您可能會(huì)驚訝于那些小型8位處理器已經(jīng)成為40-MHz時(shí)鐘,可擴(kuò)展程序存儲(chǔ)器,向量中斷表,浮點(diǎn)庫,C編譯器的強(qiáng)大工具,和外圍設(shè)備的范圍。您可能會(huì)發(fā)現(xiàn)選擇使用較少位的處理器可以更好地幫助您滿足成本和性能限制,同時(shí)節(jié)省空間。
我花了10多年的時(shí)間在工業(yè)控制應(yīng)用程序中使用16位和32位x86組裝。對(duì)于這個(gè)動(dòng)手實(shí)踐的項(xiàng)目,我想看看我所有的16/32位偏差會(huì)讓我們后退并使用8位處理器進(jìn)行設(shè)計(jì)。畢竟,因?yàn)樘幚砥鞑荒敲磸?fù)雜,設(shè)計(jì)過程應(yīng)該更簡單,不應(yīng)該嗎?
一個(gè)人的愚蠢錯(cuò)誤往往會(huì)產(chǎn)生最好的學(xué)習(xí)材料。因此,一些設(shè)計(jì)經(jīng)驗(yàn)可能有點(diǎn)令人尷尬。幸運(yùn)的是,總是存在這樣的安慰:在完成這個(gè)項(xiàng)目之后,我不再是那些犯了這些錯(cuò)誤的程序員。如果你正在考慮轉(zhuǎn)向8位處理器,那么閱讀這個(gè)項(xiàng)目可能會(huì)讓你免于我所遇到的一些痛苦和痛苦。
項(xiàng)目
對(duì)于我的項(xiàng)目,我決定制作一個(gè)音序器。我的一些工程師和我最近發(fā)現(xiàn)了“Cool-Neon”,也稱為電致發(fā)光線(參考文獻(xiàn)1)。您可以使用逆變器將9V電源轉(zhuǎn)換為300V交流電,從而驅(qū)動(dòng)電線以創(chuàng)建多色光雕塑。我們首先建造了一條二維魚,我們可以騎在自行車上,創(chuàng)造一個(gè)游泳魚群的幻覺。對(duì)于我們的下一代項(xiàng)目,我們需要一個(gè)可以循環(huán)通過光線模式的音序器,為移動(dòng)的雕塑或電子萬花筒創(chuàng)造一種運(yùn)動(dòng)的幻覺,其中不同時(shí)間點(diǎn)亮的不同光束代表短幀和循環(huán)動(dòng)畫中的幀序列
8位處理器似乎非常適合這個(gè)項(xiàng)目。我需要一個(gè)輸出引腳來驅(qū)動(dòng)每根導(dǎo)線;對(duì)于10股容量,我需要10個(gè)引腳。一個(gè)按鈕(使用另一個(gè)引腳)將允許某人循環(huán)通過模式選項(xiàng)。在功能列表中,我快速添加了傳感器的輸入。例如,放置在自行車車輪周圍的傳感器可以基于外部事件而不是內(nèi)部計(jì)時(shí)器來觸發(fā)模式。決定使用Microchip的PIC系列產(chǎn)品,我發(fā)現(xiàn)18引腳封裝處理器有13個(gè)I/O引腳,所以我有一個(gè)引腳備用,但不會(huì)長時(shí)間保留備用。
資源有限:記憶
您通??梢酝ㄟ^在更強(qiáng)大的處理器上投入資源(如內(nèi)存,處理和I/O)來解決問題。然而,由于配置的多樣性,8位世界中的家庭成員之間的差異可以直接節(jié)省成本。例如,具有2千字節(jié)板載內(nèi)存的處理器成本低于4千字節(jié)的處理器。我記得有64千克的銀行可用;你可以通過使用一個(gè)大表來加速一個(gè)關(guān)鍵的計(jì)算 - 一個(gè)可行的,有時(shí)是至關(guān)重要的選項(xiàng)來燃燒記憶。
早期,我做了什么才能成為我的音序器的關(guān)鍵設(shè)計(jì)決策。我沒有用1位(10個(gè)燈等于10位)表示活動(dòng)燈,而是創(chuàng)建了一個(gè)10字節(jié)長的表,其中包含適當(dāng)邏輯光的物理端口代碼;也就是說,I/O端口A上的指示燈1 =位3)。我制作這張桌子是因?yàn)?,?dāng)我測試是否填充了燈光時(shí),我必須計(jì)算物理端口。當(dāng)時(shí),存儲(chǔ)這個(gè)預(yù)先計(jì)算的值似乎更容易。鑒于我的心態(tài),這個(gè)選擇是明智的:在開始時(shí)(主處理循環(huán)之外)執(zhí)行一次計(jì)算,并在每次稍后使用計(jì)算時(shí)保存那么多循環(huán)。
不幸的是,這個(gè)選擇很糟糕。首先,定序器將大部分時(shí)間花在輪詢循環(huán)中,等待按鍵是否被按下或是否已觸發(fā)定時(shí)器。因此,在輪詢循環(huán)中,我節(jié)省了幾個(gè)周期(最多10個(gè)燈,10個(gè)指令= 100個(gè)周期)。其次,更重要的是,我使用了比我需要多8個(gè)字節(jié)的RAM。我習(xí)慣丟掉數(shù)百字節(jié)的填充緩沖區(qū)來覆蓋可能出現(xiàn)的最壞情況。但是,當(dāng)8個(gè)字節(jié)幾乎占總數(shù)據(jù)存儲(chǔ)器的八分之一時(shí),這是一個(gè)糟糕的決定。
在我用完數(shù)據(jù)存儲(chǔ)器之前,我沒有意識(shí)到這種選擇的重要性。我添加了一個(gè)變量,程序無法運(yùn)行,因?yàn)榱硪粋€(gè)變量被推入未定義的0xFF區(qū)域。我的項(xiàng)目似乎沒有足夠的復(fù)雜性來使用這么多的內(nèi)存,但是當(dāng)我添加更多功能時(shí),我忘了留意內(nèi)存。當(dāng)我努力恢復(fù)字節(jié)時(shí),擊中數(shù)據(jù)存儲(chǔ)器的頂部使我的開發(fā)暫時(shí)停止。然后我犯了一個(gè)愚蠢的錯(cuò)誤,即偶然試圖加倍臨時(shí)變量。例如,某些函數(shù)需要循環(huán)計(jì)數(shù)器。但是,您可以使用這些循環(huán)計(jì)數(shù)器來計(jì)算除這些函數(shù)之外的其他內(nèi)容。為了完成這項(xiàng)工作,我需要嚴(yán)格控制變量的范圍,以確保一個(gè)函數(shù)不使用相同的變量調(diào)用另一個(gè)函數(shù)。
我的第一個(gè)直覺指示我只給一個(gè)雙重任務(wù)變量一個(gè)名字。我可以想象調(diào)試的噩夢是沒有記住兩個(gè)不同的變量實(shí)際上是相同的變量并相互改變。至少如果他們有相同的名字,如果我不小心違反變量的范圍,我就有更好的機(jī)會(huì)抓住自己。
當(dāng)我嘗試按范圍對(duì)變量進(jìn)行分組時(shí),我了解到在整個(gè)程序中使用變量之前我可以更輕松地執(zhí)行此任務(wù)。例如,變量Temp具有直接范圍,這意味著如果函數(shù)調(diào)用另一個(gè)函數(shù),則第一個(gè)函數(shù)應(yīng)該假定Temp被銷毀。另一個(gè)極端是系統(tǒng)或全局變量,例如Flags,所有函數(shù)都可以使用。然后是灰色區(qū)域。例如,循環(huán)計(jì)算當(dāng)前正在處理燈光模式中的哪個(gè)步驟。因?yàn)橐淮沃荒軋?zhí)行一個(gè)模式,所以每個(gè)模式函數(shù)都可以使用Cycle。此外,當(dāng)用戶編輯用戶可編程模式時(shí),沒有預(yù)定義模式正在運(yùn)行,因此您也可以在此處使用Cycle。但是,當(dāng)我想在編輯時(shí)顯示用戶可編程模式時(shí),我確實(shí)存在潛在的范圍違規(guī)。我必須在顯示之前存儲(chǔ)Cycle并在編輯后恢復(fù)它,或者我可以讓用戶通過在他或她想要編輯的周期停止顯示來重置Cycle,這是我實(shí)現(xiàn)的選擇。
在這種情況下存儲(chǔ)Cycle會(huì)需要一個(gè)全局變量,因?yàn)轱@示一個(gè)模式使用了主程序循環(huán),但是為此目的專用變量會(huì)使變量首先加倍。我也可以選擇實(shí)現(xiàn)數(shù)據(jù)堆棧。在16位和32位的世界中,堆棧是一個(gè)方便的朋友。但是,我使用的微處理器只有一個(gè)內(nèi)部堆棧用于程序地址。 (我確信有一些方法可以欺騙處理器來存儲(chǔ)數(shù)據(jù),但只有8個(gè)級(jí)別,如果我想保存多于一個(gè)或兩個(gè)值,我會(huì)冒著堆棧的風(fēng)險(xiǎn)。)堆棧至少需要一個(gè)額外的字節(jié)用于尾部管理,你必須緩沖他們最壞情況下使用。我避免實(shí)現(xiàn)堆棧,因?yàn)槲艺J(rèn)為我的值太少而無法保存。
變量的范圍對(duì)于通過加倍使用變量來跟蹤和創(chuàng)建變量的依賴性至關(guān)重要。這項(xiàng)任務(wù)應(yīng)該是一個(gè)謹(jǐn)慎的決定。我試圖將變量劃分為功能塊,但是,即使仔細(xì)規(guī)劃,似乎總是可以同時(shí)使用兩個(gè)塊,因此也就是所有變量。然后我會(huì)發(fā)現(xiàn)自己正在追逐自己造成的錯(cuò)誤。
一旦您決定將處理器放在電路板上,您就有可能顯著降低處理器的成本。當(dāng)你發(fā)展時(shí),給自己一些重新編程的空間是有意義的;但是,您可能會(huì)發(fā)現(xiàn)自己只需幾個(gè)字節(jié)就可以將設(shè)計(jì)融入更便宜的處理器中。較便宜的選項(xiàng)并不總是等價(jià)的,并且會(huì)影響開發(fā),因?yàn)樗鼈兌x了內(nèi)存和性能閾值。通過在開始開發(fā)時(shí)而不是在完成開發(fā)時(shí)了解這些閾值,您可以確定限制可用資源的緊密程度。無論如何,你可能永遠(yuǎn)不會(huì)雇用一個(gè)字節(jié)作為一個(gè)角色。
資源有限:處理
由于“功能蠕變”-extra功能使設(shè)計(jì)復(fù)雜化并拋棄計(jì)劃 - 繼續(xù)為順控程序添加選項(xiàng)和增強(qiáng)功能,我意識(shí)到我可能也會(huì)在程序內(nèi)存中占據(jù)優(yōu)勢。在16位和32位的世界中,我經(jīng)常為一個(gè)問題投入內(nèi)存以減少總計(jì)算時(shí)間。我發(fā)現(xiàn)自己正在使用我的音序器進(jìn)行反向權(quán)衡。
當(dāng)我設(shè)計(jì)用戶可編程模式(存儲(chǔ)在EEPROM中)時(shí),我使用位來表示每個(gè)光。但是,10位是1字節(jié),剩下2位,您可以打包成四個(gè)組以完全使用另一個(gè)字節(jié)。這個(gè)決定產(chǎn)生了一個(gè)問題,因?yàn)槟J綄⒁耘c我用來打開燈光的格式不同的格式存儲(chǔ)。 (EEPROM格式使用邏輯格式來跟蹤被點(diǎn)亮的燈:點(diǎn)亮零到九。燈格式使用物理格式:每個(gè)端口一個(gè)字節(jié),A和B,每個(gè)位代表相應(yīng)的I/O引腳,由于板布局考慮而無序。)存在兩種格式,因?yàn)槲锢砀袷绞怯糜隍?qū)動(dòng)輸出端口的實(shí)際掩碼。但是,物理格式使用16位而不是像邏輯格式那樣僅使用10位。因此,我需要一個(gè)轉(zhuǎn)換函數(shù)。
我通常會(huì)同時(shí)寫兩個(gè)轉(zhuǎn)換函數(shù)的方向。為了最大限度地減少總處理周期,我將EEPROM邏輯格式轉(zhuǎn)換為光/物理格式。當(dāng)用戶編輯模式的這個(gè)循環(huán)時(shí),我將制作并顯示光/物理格式的變化。當(dāng)用戶完成編輯此循環(huán)后,我會(huì)將光/物理格式轉(zhuǎn)換回EEPROM/邏輯格式并保存循環(huán)。
我決定轉(zhuǎn)而支持內(nèi)存而不是處理性能。通過直接更改EEPROM/邏輯格式,我可以調(diào)用轉(zhuǎn)換函數(shù)來創(chuàng)建光/物理格式并顯示修改后的周期。每次運(yùn)行此轉(zhuǎn)換需要更多的處理周期,但同樣,這些周期僅來自輪詢循環(huán)。我獲得了廢除逆轉(zhuǎn)換函數(shù)的選項(xiàng),因?yàn)樗鼜奈幢徽{(diào)用過。因此,我節(jié)省了程序內(nèi)存和一些開發(fā)時(shí)間。我還獲得了將所有更改立即保存在EEPROM中的好處,使我無需在用戶移動(dòng)到新周期時(shí)管理保存更改,想要顯示模式,左編輯模式等等。
計(jì)時(shí)器
在我的問題上投擲處理能力而不是記憶力幾乎適用于我。 PIC16F84有一個(gè)內(nèi)部定時(shí)器TMR0,粒度為256個(gè)周期,預(yù)分頻器大小為2 8 (256×256 = 65,536個(gè)周期)。在沒有預(yù)分頻器的情況下運(yùn)行,每256個(gè)周期發(fā)生一次TMR0中斷。因?yàn)槲覍⒚總€(gè)模式的循環(huán)連接到TMR0,所以每個(gè)循環(huán)必須在256個(gè)循環(huán)內(nèi)完成執(zhí)行,或者在完成處理最后一個(gè)循環(huán)之前我會(huì)遇到TMR0事件,偶爾在模式期間丟失一個(gè)循環(huán)。增加預(yù)分頻器可以選擇將TMR0間隙增加2倍,以防止超出。通過盡可能多地處理中斷以避免中斷處理期間的中斷延遲,保持中斷處理程序的清潔和簡單也很重要。
我使用電位計(jì)讓用戶調(diào)整音序器的速度。鑒于你需要在模式的周期之間進(jìn)行一點(diǎn)處理,我選擇使用RC時(shí)鐘而不是晶體。這個(gè)決定節(jié)省了晶體成本,系統(tǒng)復(fù)雜性和I/O引腳;電位計(jì)驅(qū)動(dòng)RC時(shí)鐘,而不是告訴PIC應(yīng)該運(yùn)行多快,并在內(nèi)部管理這個(gè)速度。如果我想讓兩個(gè)序列發(fā)生器相互通信,我將不得不創(chuàng)建一個(gè)連接兩個(gè)節(jié)點(diǎn)的協(xié)議,這些節(jié)點(diǎn)具有獨(dú)立且可能變化的時(shí)鐘速度。
我想要幾種速度選項(xiàng) - 從幾分之一到幾秒 - 用于循環(huán)模式。電位器給了我一個(gè)范圍,所以我創(chuàng)建了兩個(gè)用戶可選擇的速度區(qū)域,為TMR0使用了不同的預(yù)分頻器。我的設(shè)計(jì)最初支持三個(gè)區(qū)域,但有兩個(gè)簡化的用戶選擇,將速度參數(shù)切換為1位,并簡化了TMR0事件的內(nèi)部管理。
預(yù)分頻器3(2 4 = 16)和4(2 5 <之間的差異/sup> = 32)可以變寬,特別是RC時(shí)鐘被調(diào)到5和50 kHz。當(dāng)我的設(shè)計(jì)支持三種模式時(shí),我發(fā)現(xiàn)添加(TMR0_COUNT預(yù)分頻器讓我可以更好地控制中斷。如果你用一個(gè)10-MHz時(shí)鐘運(yùn)行PIC,你可能會(huì)發(fā)現(xiàn)這個(gè)額外的預(yù)分頻器讓你測量有用的時(shí)間長度。
調(diào)試
鑒于要重復(fù)這個(gè)項(xiàng)目,我會(huì)獲得一個(gè)用于軟件開發(fā)的模擬器。嘗試解決困難編程所節(jié)省的時(shí)間很快就會(huì)彌補(bǔ)費(fèi)用。相反,我非常依賴MPLAB模擬器。
模擬器的運(yùn)行速度比我預(yù)期的要慢得多。有時(shí),我認(rèn)為系統(tǒng)已經(jīng)凍結(jié),因?yàn)樗Φ竭_(dá)我的斷點(diǎn)。有時(shí)候,我引起了一個(gè)延遲,例如當(dāng)我在輪詢循環(huán)后將斷點(diǎn)放在代碼中的某個(gè)點(diǎn)時(shí),模擬器卡在輪詢循環(huán)中等待我響應(yīng)。我的設(shè)計(jì)有一個(gè)短于256個(gè)時(shí)鐘的主循環(huán),所以我可以快速測試迭代和情況。以10 MHz運(yùn)行的設(shè)計(jì)可能有更長的主循環(huán)或更多的輪詢。
我發(fā)現(xiàn)使用Define創(chuàng)建模擬器標(biāo)簽很有用。在真正的董事會(huì)上,我想要真正的延遲。但是,通常沒有理由在模擬器中的輪詢或延遲循環(huán)中永遠(yuǎn)等待。例如,我有一個(gè)Flash功能,可以閃爍特定的線W次。在模擬器中,我沒有必要“看到”這種閃爍。因此,我添加了以下代碼以跳過無用的函數(shù)和速度模擬:
TMR0也觸發(fā)了事件。我將所有延遲量命名為常量,以便我可以將所有模擬器常量設(shè)置為零。我還添加了一些代碼來模擬按鈕按下或其他事件。有時(shí),等待TMR0中斷變得令人難以忍受。在我的輪詢循環(huán)中,然后,我添加了僅模擬器代碼,它將設(shè)置我的TMR0事件標(biāo)志(然后將TMR0重置為零,以便最終不會(huì)觸發(fā)我)。
模擬器代碼的另一個(gè)有用位置是中斷處理程序的開頭。我的中斷處理程序足夠短,可以將它留在代碼的前面,而不是調(diào)用放在內(nèi)存中其他地方的函數(shù),這會(huì)增加中斷的延遲。但是,當(dāng)我模擬輸入時(shí),會(huì)調(diào)用一個(gè)中斷,我不得不單步執(zhí)行所有中斷代碼。我添加了代碼:
此代碼創(chuàng)建了一個(gè)調(diào)用,我可以用鍵擊來代替。
我通常發(fā)現(xiàn)MPLAB環(huán)境包含很多很好的功能,但是我很痛苦地追逐一個(gè)接口問題。例如,我想測試需要按兩次按鈕才能到達(dá)的代碼。 MPLAB有一個(gè)“激勵(lì)模擬器”窗口,通過它我可以激活輸入端口。不幸的是,當(dāng)刺激窗口打開時(shí),模擬器的運(yùn)行速度明顯變慢,所以我通常不得不關(guān)閉窗口并在幾秒鐘后重新打開它。選擇刺激時(shí)鐘似乎比它值得更麻煩,因?yàn)槲冶仨毰宄蚁M斎胗|發(fā)的時(shí)鐘周期。通過查看合適的輸出引腳,我也可以看到燈是否亮起。但是,對(duì)于任何復(fù)雜的輸出序列,驗(yàn)證準(zhǔn)確的反饋可能很困難。
與MPLAB環(huán)境一樣有用,我建議您訪問一個(gè)快速而骯臟的開發(fā)環(huán)境,例如Basic,來測試算法。例如,微芯片應(yīng)用筆記庫中的隨機(jī)數(shù)生成器功能似乎在0到255的值中具有不均勻分布的數(shù)字。由于存儲(chǔ)器限制,在Microchip環(huán)境中測試此功能似乎很困難。例如,如果我有256字節(jié)的RAM,我可以很容易地計(jì)算很長一段時(shí)間內(nèi)的分布。然而,如果不到40H字節(jié),我將不得不想出一個(gè)聰明的計(jì)數(shù)方案,并且可能會(huì)多次運(yùn)行我的模擬以確定傳播是均勻的。在Basic中,我可以在幾分鐘內(nèi)彈出這段代碼并幾乎立即看到結(jié)果。
我遇到了其他令人沮喪的錯(cuò)誤;如果我使用了模擬器,我會(huì)節(jié)省數(shù)小時(shí)的調(diào)試時(shí)間。
因?yàn)槲沂褂昧丝芍匦戮幊痰脑O(shè)備,所以我不得不將設(shè)備插入板中以及從板中取出設(shè)備以將其放入設(shè)備編程器中。我在電路板上有一個(gè)插座,但是將設(shè)備插入插座意味著我必須將插座插入插座中,從而產(chǎn)生松動(dòng)且因此不良的電氣配合。我最終在一臺(tái)設(shè)備上打破了領(lǐng)先優(yōu)勢,使其無用。我還需要偶爾向外彎曲引線,因?yàn)橄騼?nèi)彎曲的引腳連接不良,I/O引腳會(huì)神秘地停止工作。使用模擬器可以消除我的大部分套接字問題。
我安裝了一個(gè)新的逆變器,可以驅(qū)動(dòng)比我當(dāng)前的逆變器更多的電線,從而使我能夠同時(shí)點(diǎn)亮幾根電線。雖然設(shè)計(jì)是在程序模式下,但我會(huì)閃現(xiàn)一條線來代表一個(gè)參數(shù)。參數(shù)One工作正常,但參數(shù)二不會(huì)閃爍。因?yàn)槲覍W⒂谟脩艨删幊棠J讲⒔昧似渌麉?shù),所以我認(rèn)為我的一些更改可能會(huì)改變代碼的閃存能力 - 通過使用變量。經(jīng)過大約一個(gè)小時(shí)的追逐幻象代碼錯(cuò)誤后,我終于將問題縮小到了實(shí)際的電線,除非我點(diǎn)亮另一根電線,否則我無法關(guān)閉。突然間,我意識(shí)到新的逆變器可能是問題所在。當(dāng)我連接舊逆變器時(shí),電線正確閃爍。
出現(xiàn)問題是因?yàn)槟孀兤鲀A向于保持電線點(diǎn)亮;一些導(dǎo)線 - 但不是其他導(dǎo)線 - 超過驅(qū)動(dòng)導(dǎo)線的三端雙向可控硅開關(guān)中的相位間隙。我通過代碼搜索,因?yàn)橐桓娋€工作,而另一根沒電。我懷疑是一個(gè)邏輯問題,并且忽視了導(dǎo)線出錯(cuò)的可能性,因?yàn)樗耙恢庇行АJ褂媚M器,我會(huì)看到端口已經(jīng)變低,我正面臨硬件,而不是邏輯問題。我還了解到,當(dāng)我使用新設(shè)備進(jìn)行測試時(shí),我應(yīng)該檢查一下,在更改硬件之前是否存在先前設(shè)置中存在的錯(cuò)誤。
值得一提的是,我保持了“健全性” - 使用舊版本代碼刻錄的幾個(gè)芯片。每當(dāng)原型開始變得怪異時(shí),我就會(huì)放入其中一個(gè)完整的燒傷。如果原型工作,那么我的最新版本的代碼已經(jīng)破壞了一些關(guān)鍵的東西。如果健全性刻錄無法正常工作,則硬件會(huì)出現(xiàn)諸如斷線之類的問題。
電源問題引發(fā)了一系列令人討厭的錯(cuò)誤。我最初使用壁式電源為我的原型供電。但是,我得到了一些奇怪的閃爍,我很快就將其評(píng)估為電源問題。由于電路板應(yīng)使用9V電池供電,因此我切換到電池供電。然而,點(diǎn)亮的電線消耗大量電力。我還做了一個(gè)不幸的假設(shè),即當(dāng)電池電量太低時(shí)我的電線就會(huì)死掉。 PIC實(shí)際上首先變得缺電,然后行動(dòng)不穩(wěn)定。我在追逐想象中的錯(cuò)誤一天之后才發(fā)現(xiàn)了這個(gè)事實(shí)。使用新電池可以處理所有事情。我希望在嘗試查找錯(cuò)誤并注釋掉部分,設(shè)置不必要的調(diào)試掛鉤等之前保存了特殊版本的代碼。
為了避免電池問題,我回到墻上供應(yīng)。然后我發(fā)現(xiàn)閃爍不是由電源引起的,正如我所假設(shè)的那樣。 (墻上插座給了我足夠的力量來看到我的弱電池上的閃爍。)相反,這是我在設(shè)置下一個(gè)周期之前短暫關(guān)閉燈并顯示它們的問題。我將代碼更改為只是從一個(gè)循環(huán)移動(dòng)到另一個(gè)循環(huán)而不顯示其間的所有燈。奇怪的閃爍消失了。
我創(chuàng)建的另一個(gè)原型錯(cuò)誤涉及使用重置按鈕。我在面包板原型上添加了一個(gè)復(fù)位按鈕,這樣我就可以輕松地重置電路板而無需進(jìn)行物理斷開,然后重新連接9V電池。模擬器可以提供相同的功能。但是,最終產(chǎn)品沒有重置按鈕。使用原型,當(dāng)我想離開程序模式時(shí),我會(huì)按下重置按鈕重新啟動(dòng)電路板。然而,這種復(fù)位不是全功率復(fù)位,這意味著標(biāo)志和存儲(chǔ)器沒有被清除;在這種情況下唯一重大的變化是程序計(jì)數(shù)器重置為0x00。當(dāng)我最終轉(zhuǎn)移到真正的用戶所擁有的制造原型時(shí),我通過關(guān)閉然后再打開電路板離開編程模式,但是電路板沒有注冊(cè)我的更改。出現(xiàn)此問題的原因是斷電復(fù)位也會(huì)清除內(nèi)存。
我列舉了這些例子,因?yàn)樗鼈冋f明了使用原型的一些危險(xiǎn)。一方面,你需要一個(gè)干凈的環(huán)境來開發(fā),所以你不會(huì)追逐幻影。您還希望訪問所有硬件,并且應(yīng)該能夠隨意進(jìn)行探測。另一方面,您需要使用與客戶相同的硬件來查看實(shí)際發(fā)生的情況。
時(shí)滯
當(dāng)我炸掉我唯一的控制器時(shí),我遇到了開發(fā)周期中最大的延遲之一。我首先訪問Microchip的網(wǎng)站以獲得更多芯片。最快的送貨服務(wù)是三天,這意味著我只能使用模擬器進(jìn)行開發(fā)。我找到了多個(gè)銷售PIC芯片的互聯(lián)網(wǎng)網(wǎng)站,并且可選擇更快的交付。雖然其他站點(diǎn)提供了有限的PIC選擇,但我確實(shí)找到了PIC16F84,這是很好的開發(fā),然后計(jì)劃換成更便宜的芯片。鑒于PIC微處理器的普遍可用性,我購買了一些零件而無需與經(jīng)銷商建立關(guān)系。我還學(xué)到了庫存的第一條規(guī)則:有一些。當(dāng)出現(xiàn)問題時(shí),您的時(shí)間和產(chǎn)品的上市時(shí)間應(yīng)該得到一些額外部件的保險(xiǎn)。
延遲的一個(gè)更具破壞性的因素是特征蠕變。在我完成基本功能之前,我已經(jīng)決定了一系列新功能,例如用戶可編程模式,這些功能已經(jīng)進(jìn)入規(guī)范。我為需要非標(biāo)準(zhǔn)模式的專家用戶構(gòu)思了用戶可編程模式。這些模式還需要與項(xiàng)目其余部分一樣多的編碼開發(fā)時(shí)間。突然之間,由于我努力解決專家代碼中的錯(cuò)誤,上市時(shí)間受到了沖擊。具有諷刺意味的是,beta測試人員對(duì)用戶可編程模式不感興趣。換句話說,如果我關(guān)閉了規(guī)范并將專家功能推遲到第二版(參見附文“經(jīng)典混音和錯(cuò)誤”),我本可以更快地將測試板交付給beta測試人員并測試音序器的基本穩(wěn)健性。
殺手NOP
每當(dāng)我得到一個(gè)新工具時(shí),我總會(huì)感到興奮。安裝后,我要做的最后一件事是特別注意說明。我已經(jīng)閱讀了足夠的內(nèi)容以便開始,然后向我保證我會(huì)返回并稍后完成。
早期,當(dāng)我嘗試實(shí)現(xiàn)演示模式時(shí),我發(fā)現(xiàn)了一個(gè)奇怪的問題:電路板只能點(diǎn)亮六盞燈。當(dāng)我刪除代碼時(shí),電路板工作正常。此時(shí),我開始重新編寫代碼片段,每次測試電路板時(shí)都會(huì)進(jìn)行測試。最后,除了一段代碼之外的所有代碼都重新進(jìn)入。當(dāng)我注釋掉代碼時(shí),電路板運(yùn)行了。奇怪的是,只有按下按鈕才會(huì)執(zhí)行此代碼。不知何故,我想,事件是錯(cuò)誤地觸發(fā)的。當(dāng)我刪除除了Goto和Return之外的所有代碼時(shí),代碼工作正常。添加CLRF標(biāo)志會(huì)導(dǎo)致失敗。但是怎么樣?然后,我決定添加非操作(NOP)指令而不是CLRF標(biāo)志。隨著NOP,董事會(huì)失敗了。如果沒有NOP,代碼就會(huì)運(yùn)行。
當(dāng)NOP指令導(dǎo)致嚴(yán)重錯(cuò)誤時(shí),通常意味著存在內(nèi)存誤解。果然,我的一張桌子越過100H邊界,因?yàn)槲衣卦谒懊嫣砑恿?a target="_blank">程序代碼。在這種情況下,出現(xiàn)問題是因?yàn)楸淼刂纷優(yōu)?位長; 14位PIC指令可以容納Goto地址的額外位,但它們會(huì)丟棄算術(shù)指令的第9位和第10位,例如Add。因?yàn)槲覝y試的代碼長5個(gè)字節(jié),所以表超過了4個(gè)字節(jié)。 (因此,在光7之前只有六個(gè)燈顯示PIC設(shè)置為00H(復(fù)位)而不是100H。)
我通過將所有表移動(dòng)到代碼部分的前面然后仔細(xì)閱讀指令集來解決問題,以查看是否有任何更多的命令具有匯編程序無法捕獲的偷偷摸摸的細(xì)微差別。后來,當(dāng)我閱讀John Peatman的使用PIC微控制器進(jìn)行設(shè)計(jì)時(shí),我發(fā)現(xiàn)將表放在存儲(chǔ)器前面是PIC的標(biāo)準(zhǔn)做法,因?yàn)檫@個(gè)原因(參考文獻(xiàn)) 2)。我快速閱讀,看看是否還有其他標(biāo)準(zhǔn)做法我應(yīng)該遵循。在中斷區(qū)域,這本書給我?guī)砹撕艽蟮谋瘋?。例如,?6位和32位的世界中,標(biāo)志會(huì)自動(dòng)保存,并且有一個(gè)堆棧來保存寄存器。使用PIC系列,您必須自己保存標(biāo)志,但首先必須以一種棘手的方式保存累加器(使用Swap)而不影響標(biāo)志(清單1)。我發(fā)現(xiàn)disable-interrupt命令特別具有欺騙性。由于PIC具有兩級(jí)流水線,因此如果中斷因此與請(qǐng)求禁用中斷同時(shí)發(fā)生,則會(huì)出現(xiàn)問題。 PIC根據(jù)您的指令清除中斷標(biāo)志,然后執(zhí)行掛起中斷。當(dāng)您從中斷返回,從而啟用中斷標(biāo)志時(shí),即使您認(rèn)為剛剛禁用了它們,也會(huì)在主代碼中啟用中斷(清單2)。
最后,我發(fā)現(xiàn)PIC規(guī)格表雖然技術(shù)上已經(jīng)完整,但需要一些澄清。至少買一本像皮特曼這樣的書。他建議一個(gè)強(qiáng)大的編程結(jié)構(gòu),可以幫助您避免許多問題。然而,他的問題部分讓我煩惱,因?yàn)槟惚仨毺崆伴喿x一兩章才能最終發(fā)現(xiàn)答案。在任何情況下,在您發(fā)現(xiàn)之前閱讀本書,與大多數(shù)錯(cuò)誤一樣,您無法理解架構(gòu)的細(xì)微差別。
你可能會(huì)問35條指令有多復(fù)雜。不幸的是,減少的指令集實(shí)際上導(dǎo)致更復(fù)雜的程序。對(duì)于一個(gè)簡單的類比,想象一下,我試著寫這篇文章而不使用字母T.較少的單詞構(gòu)成一個(gè)不太復(fù)雜的詞匯,但可用的單詞較少意味著說某些事情需要更長的時(shí)間。例如,高階語言具有復(fù)雜的詞匯表,可以讓您在一條指令中描述復(fù)雜的匯編任務(wù),例如打印或乘法。使用精簡的指令集,例如PIC系列的指令集,即使是簡單的函數(shù),例如位移,也會(huì)變得更加復(fù)雜。例如,x86的程序集提供了諸如旋轉(zhuǎn)而不進(jìn)位和旋轉(zhuǎn)CL次等命令(清單3)。當(dāng)我需要將比特封裝的位移實(shí)現(xiàn)到這個(gè)項(xiàng)目時(shí),我不得不考慮這個(gè)過程。沒有旋轉(zhuǎn) - 不進(jìn)位指令,所以在右旋轉(zhuǎn)的情況下,我必須在每次旋轉(zhuǎn)之前將進(jìn)位標(biāo)志設(shè)置到最右邊的位置。
創(chuàng)建比特移位等功能并不困難;但是,你仍然需要?jiǎng)?chuàng)建它們。如果您從未在此級(jí)別工作 - 例如,如果您始終有可用的打印指令 - 創(chuàng)建基本功能庫可能需要一段時(shí)間。您還會(huì)發(fā)現(xiàn),第一次嘗試時(shí),您可能無法確定實(shí)現(xiàn)功能的最有效或最靈活的方式。因此,我的項(xiàng)目花費(fèi)的時(shí)間比我想象的要長,因?yàn)槲揖帉懥恕盎尽焙瘮?shù),我習(xí)慣于在不太復(fù)雜的16位和32位架構(gòu)中實(shí)現(xiàn)這些函數(shù)。
我還發(fā)現(xiàn),盡早構(gòu)建我的基本功能庫可以提高我布置音序器架構(gòu)的能力。例如,一旦我編寫了用于讀寫EEPROM的基本功能,我開始將EEPROM視為一種資源,而不僅僅是我后來需要編寫代碼的東西。這種觀點(diǎn)的改變促使我考慮創(chuàng)建在斷電后保持設(shè)置的靜態(tài)用戶參數(shù)的想法。 EEPROM還打開了一組可用的數(shù)據(jù)存儲(chǔ)器,訪問速度要慢得多,但可以想象我會(huì)忘記內(nèi)存堵塞。
硬件/軟件斷開連接
在我編程16位和32位架構(gòu)的過程中,我一直使用完整的硬件系統(tǒng);也就是說,我在PC或已經(jīng)設(shè)計(jì),打印,填充和測試的電路板上工作。在這些條件下,我的首要任務(wù)之一是確定新功能的可行性。通常,您可以在軟件中實(shí)現(xiàn)任何功能,因?yàn)樵摴δ軡M足處理速度,內(nèi)存和接口的限制。如果不是這三個(gè)限制,8位μP可以執(zhí)行視頻會(huì)議,雖然速度很慢。一旦我確定我有足夠的處理能力,并且我可以在必要時(shí)實(shí)時(shí)執(zhí)行任務(wù),足夠的內(nèi)存和正確的接口,我會(huì)編寫該函數(shù)。
然而,在這個(gè)項(xiàng)目中,我是構(gòu)建電路板的設(shè)計(jì)團(tuán)隊(duì)的一員。雖然我的硬件技能有限,但我提供了一個(gè)在代碼中可以合理實(shí)現(xiàn)的視角。也就是說,包含PIC無法有效處理的硬件接口將是荒謬的。該團(tuán)隊(duì)開發(fā)的一項(xiàng)功能是自動(dòng)檢測電路,確定端口是否實(shí)際連接到電線。如果沒有這樣的電路,PIC就無法知道用戶想要點(diǎn)亮和循環(huán)多少根導(dǎo)線,除非他每次給電路板加電時(shí)輸入該值。相比之下,由于帶有電位計(jì)的RC電路為PIC提供時(shí)鐘,因此PIC永遠(yuǎn)不會(huì)知道它的運(yùn)行速度。 (PIC的設(shè)計(jì)人員認(rèn)為此功能不是必需或有用的。)
請(qǐng)注意,在我們支付第一批電路板之前,我們沒有鎖定硬件規(guī)格??紤]到產(chǎn)品上市時(shí)間的壓力,即使我們?nèi)匀恍枰帉懘a,我們也會(huì)將電路板放到屏幕上進(jìn)行篩選。我們完成了足夠的代碼來滿足團(tuán)隊(duì)需求,硬件按照我們的預(yù)期運(yùn)行,但是我們還沒有把所有的花里胡哨都用到了。
一旦我們鎖定硬件規(guī)格,整個(gè)設(shè)計(jì)氛圍就會(huì)改變:硬件和軟件之間發(fā)生斷開連接。到目前為止,硬件設(shè)計(jì)是瓶頸。軟件隨時(shí)準(zhǔn)備好等待測試電路板。一旦我們完成硬件,軟件突然成為瓶頸。此外,我們不再討論我們?cè)谟布蜍浖矫婵梢宰鲂┦裁?現(xiàn)在,這是所有的軟件。硬件團(tuán)隊(duì)離開了項(xiàng)目,因?yàn)闆]有人能做到。任何硬件“問題”,例如I/O引腳反轉(zhuǎn)或引腳布局,現(xiàn)在都是軟件問題。令人沮喪的一天,當(dāng)硬件團(tuán)隊(duì)努力解決地面問題時(shí),他們宣稱董事會(huì)已經(jīng)完成并走開了,留下了一個(gè)未能運(yùn)行與會(huì)話開始時(shí)相同代碼的原型。我發(fā)現(xiàn),有人將輸入按鈕反轉(zhuǎn)為驅(qū)動(dòng)低而不是高,但沒有給我這個(gè)信息。
此外,每個(gè)人都對(duì)如何改善董事會(huì)的職能有很好的想法,這也帶來了另一個(gè)挑戰(zhàn)。我們擁有簡單的硬件基礎(chǔ),為軟件提供了極大的靈活性現(xiàn)在我在槍口下,規(guī)格變化和特征蠕變成了流行病。存在兩類規(guī)范更改:功能更改以及如何向用戶(接口)提供這些功能的更改。在這兩者中,設(shè)計(jì)師通常認(rèn)為界面變化更簡單,但實(shí)際上它們更難。例如,音序器沒有顯示,只有兩個(gè)按鈕。經(jīng)過一些反思,我們意識(shí)到我們可以使用線本身來向用戶傳達(dá)信息,所以我現(xiàn)在有一個(gè)原始的10位顯示器。但是,我還必須創(chuàng)建一個(gè)用于“打印”到此顯示的函數(shù)庫。只有兩個(gè)按鈕創(chuàng)造了在用戶可編程序列模式下嘗試為多達(dá)10個(gè)命令提供用戶訪問的挑戰(zhàn)。我們提出了一個(gè)擴(kuò)展移位鍵的想法;也就是說,按住一個(gè)按鈕,同時(shí)反復(fù)按下另一個(gè)按鈕。盡管該計(jì)劃允許我們?cè)L問許多功能,但它在按鈕事件的評(píng)估中產(chǎn)生了復(fù)雜性。最初,當(dāng)按下按鈕時(shí),我標(biāo)記了按鈕1或按鈕2事件?,F(xiàn)在,我仍然不得不支持這個(gè)機(jī)制來編寫我編寫的代碼,同時(shí)創(chuàng)建一個(gè)計(jì)數(shù)按鈕2按下的移位狀態(tài)并觸發(fā)按鈕1的釋放。鑒于我必須在模擬環(huán)境中調(diào)試此問題,擴(kuò)展移位起到中斷的作用,并且我必須支持觸發(fā)事件的舊方法,這個(gè)函數(shù)是我設(shè)計(jì)中最復(fù)雜的部分。
PIC匯編語言最令人煩惱的一個(gè)方面是你必須記住位組合。例如,PIC16F84的文檔說您可以在累加器W(0)或正在使用的文件寄存器(1)中存儲(chǔ)計(jì)算?;蛘呤侵車钠渌绞?直到我讀到Peatman的書時(shí),我才意識(shí)到,在F84包含文件中,PIC的設(shè)計(jì)者已經(jīng)為你設(shè)置了W = 0和F = 1的常數(shù)。
使用常量和宏來簡化代碼的誘惑誘惑了我。對(duì)于W/F區(qū)別,使用常量是有意義的。但是,我猶豫是否盡可能使用宏。例如,我發(fā)現(xiàn)自己總是被SUBLW和SUBWF拋棄。首先,助記符是不一致的:SUBLW從文字(LW)中減去W,SUBWF從F中減去W(應(yīng)該是SUBWF?)。我一直不得不回到手冊(cè)來說明問題。此外,在比較期間使用減法設(shè)置標(biāo)志始終需要仔細(xì)檢查。在x86匯編中,標(biāo)志JA(如果在上面跳轉(zhuǎn)),JB(如果在下面跳轉(zhuǎn))和JZ(如果在零時(shí)跳轉(zhuǎn))清楚地定義比較后的動(dòng)作。這些命令在一條指令中測試零和進(jìn)位標(biāo)志。您還可以使用PIC(清單4)在一條指令中測試高于,低于和零。但是,您必須在從A減去A或從A減去A以僅檢查進(jìn)位標(biāo)志而不是零標(biāo)志。 (交換順序會(huì)改變進(jìn)位標(biāo)志是否占零情況。)
我考慮編寫一個(gè)宏來進(jìn)行比較,但是認(rèn)為這個(gè)任務(wù)可能變得復(fù)雜,因?yàn)橹悼赡苁菙?shù)據(jù)或常量,因此需要MOVLW或SUBLW。另外,我考慮了宏的一個(gè)有害的副作用:它們創(chuàng)建“專有”命令。專有命令的問題在于,有人閱讀代碼最初會(huì)發(fā)現(xiàn)它們令人困惑并且必須學(xué)習(xí)它們。此外,您在其他應(yīng)用程序中編寫代碼時(shí)會(huì)遇到問題,因?yàn)槟承┰蚰鸁o法使用宏,或者必須使用其他人的代碼。
Microchip可以通過管理標(biāo)準(zhǔn)宏庫來簡化該領(lǐng)域的開發(fā)。例如,幾乎每個(gè)程序都使用比較宏(參考文獻(xiàn)3)。如果您使用標(biāo)準(zhǔn)宏庫,宏將成為整個(gè)行業(yè)的命令,而不是程序員之間的絆腳石。在其辯護(hù)中,Microchip確實(shí)提供了一個(gè)令人印象深刻的應(yīng)用筆記庫(參考文獻(xiàn)4),展示了程序員如何在PIC??上實(shí)現(xiàn)各種功能。但是,需要花時(shí)間對(duì)這些筆記進(jìn)行分類,讓我自己通過自己開發(fā)代碼來節(jié)省時(shí)間。
在盒子外面思考
我們?cè)趯⒁粜蚱魍度肷a(chǎn)時(shí)學(xué)到的最重要的一課是設(shè)計(jì)不是一個(gè)線性過程。團(tuán)隊(duì)通常分為功能組:硬件;軟件;包裝,制造和測試;等等。不幸的是,設(shè)計(jì)依賴性不那么整齊。例如,包裝被證明是一種粗魯?shù)挠X醒。塑料盒似乎比電路板成本更高,我們必須將大部分元件安裝在電路板的背面,以使電路板適合我們選擇的現(xiàn)成的??盒子。設(shè)計(jì)的每個(gè)階段,無論其看似簡單,都對(duì)其他階段具有依賴性和影響。如果我們?cè)诩庇谥圃祀娐钒逯耙呀?jīng)看過盒子,我們可以用不同的外形設(shè)計(jì)電路板并擴(kuò)大我們可能的盒子選項(xiàng)。
總而言之,這種經(jīng)歷啟發(fā)了我們。我天真地認(rèn)為編碼只需要幾天時(shí)間,所以我對(duì)我們超出預(yù)計(jì)時(shí)間表的時(shí)間感到震驚。當(dāng)然,我們每個(gè)人都有其他全職工作和個(gè)人生活。但是,我嚴(yán)重低估了我加快PIC速度所需的時(shí)間。我忘記了我有多年的x86匯編經(jīng)驗(yàn),并且已經(jīng)花費(fèi)了大量的時(shí)間來理解該架構(gòu)的復(fù)雜性和細(xì)微差別,以及常見的邏輯結(jié)構(gòu),例如表格。這些知識(shí)讓我在PIC開發(fā)方面處于領(lǐng)先地位,但我仍然不得不重新構(gòu)建我可編碼的許多函數(shù),而不用考慮x86,以及克服我的偏見和假設(shè)。關(guān)于假設(shè)的令人討厭的事情是很容易忘記你曾經(jīng)做過它們。
現(xiàn)實(shí)情況是,8位μP仍然存在,并且正在尋找越來越復(fù)雜的應(yīng)用程序(參考文獻(xiàn)5)。在某些方面,它們專門用于某些任務(wù),例如接口管理,傳感器監(jiān)控和串行通信,因?yàn)?a target="_blank">音頻解碼器適用于MP3播放器。而且,在設(shè)備不斷變得更加智能化的世界中,它們以低成本提供了相當(dāng)大的智能。
經(jīng)典混淆和錯(cuò)誤
臭蟲是討厭的小家伙,特別是如果他們是你自己的錯(cuò)。以下是我制作的一些經(jīng)典混淆和錯(cuò)誤,希望您能避免:
十六進(jìn)制/十進(jìn)制混音:示例:當(dāng)您使用10代替10而不是0'0a時(shí)。我發(fā)現(xiàn)最好在整個(gè)程序中使用一個(gè)基數(shù)和編號(hào)約定來避免歧義。
文字/地址混淆:我有很多關(guān)于文字和地址的混淆,因?yàn)閮烧叨急欢x為常量。在16位和32位的世界中,匯編程序通常會(huì)標(biāo)記對(duì)常量的誤用。例如,我沒有使用ADDLW posxw_table,而是使用ADDWF posxw_table,W。很明顯,這個(gè)錯(cuò)誤是我的,因?yàn)槲以噲D在該地址而不是偏移處添加字節(jié)。然而,對(duì)于不熟悉的助記符,更容易犯這個(gè)錯(cuò)誤,因?yàn)槲伊?xí)慣于使用Offset命令而不是明確地聲明我在add指令中使用了文字。
拐杖功能:早期,我的設(shè)計(jì)需要延遲功能。我第一次寫了一個(gè)計(jì)算周期。制作這種快速和骯臟功能的問題在于我繼續(xù)使用它的時(shí)間比我應(yīng)該的時(shí)間長得多。更有用的功能,我知道我最終還是要編寫,是TMR0延遲。因?yàn)槲乙蕾囉诠照裙δ?,所以我避免編寫TMR0延遲,它定義了我的中斷結(jié)構(gòu)和事件標(biāo)記機(jī)制。當(dāng)我寫TMR0延遲時(shí),我不得不調(diào)整并重新調(diào)整它影響的部分。您應(yīng)該更早而不是更晚地編寫基礎(chǔ)和結(jié)構(gòu)函數(shù)。
始終清除內(nèi)存或假設(shè)它未定義:一度,我遇到了一個(gè)看起來像參數(shù)的問題,讓我想知道存儲(chǔ)在EEPROM中的參數(shù)是如何設(shè)置的。當(dāng)我檢查EEPROM時(shí),參數(shù)是正確的,但程序無法根據(jù)參數(shù)執(zhí)行。問題是由物理參數(shù)轉(zhuǎn)換為邏輯參數(shù)造成的。 EEPROM存儲(chǔ)上電參數(shù),但您可以在運(yùn)行模式下在RAM中更改它們。例如,您可以將速度從慢速切換到快速。我一直在為演示模式開發(fā)代碼,其中邏輯參數(shù)工作(以慢速模式啟動(dòng)),但是當(dāng)我以正常模式運(yùn)行(以快速模式啟動(dòng))時(shí)它們失敗了。我造成了這個(gè)問題,因?yàn)槲以谟帽忍匮诖a之前從未清除過邏輯參數(shù);我錯(cuò)誤地認(rèn)為內(nèi)存從0開始(當(dāng)芯片通過0xff啟動(dòng)時(shí)尤其愚蠢)!
確認(rèn)所有模式在主要代碼更改:我經(jīng)常在演示模式或編程模式下進(jìn)行更改,然后在返回運(yùn)行模式時(shí)發(fā)現(xiàn)錯(cuò)誤。模式對(duì)整個(gè)系統(tǒng)狀態(tài)做出了不同的假設(shè),并且在您花費(fèi)時(shí)間對(duì)代碼的其他部分進(jìn)行重大更改后,確認(rèn)您的代碼不會(huì)違反這些假設(shè)。
強(qiáng)大的id =“id1138604-119-strong”>了解設(shè)備的架構(gòu):沒有什么比認(rèn)識(shí)到芯片不能按照你想象的那樣工作的尷尬或沮喪。我已經(jīng)說明了PIC家族對(duì)我的一些驚喜。雖然我可能會(huì)認(rèn)為我使用了不充分的文檔,但我不理解芯片,并且我失去了寶貴的開發(fā)時(shí)間。我在16位和32位世界中學(xué)到的許多經(jīng)驗(yàn)都沒有延續(xù)到8位領(lǐng)域。僅當(dāng)我無法弄清楚某些內(nèi)容時(shí)才參考規(guī)格表,這不利于學(xué)習(xí)PIC架構(gòu)。
了解您自己的硬件:一兩次,硬件人員的任務(wù)與他們說的不同。早期,我希望我創(chuàng)建了一個(gè)簡單測試硬件特性的虛擬程序,例如它是否驅(qū)動(dòng)輸出高或低,所以我可以確認(rèn)沒有人在我的原型上“修復(fù)”或“改進(jìn)”電路板。此程序也類似于“健全性刻錄”,以確認(rèn)測試運(yùn)行失敗是您的代碼的結(jié)果,而不是因?yàn)橛布收匣蚋摹?/p>
-
PCB打樣
+關(guān)注
關(guān)注
17文章
2968瀏覽量
21758 -
華強(qiáng)PCB
+關(guān)注
關(guān)注
8文章
1831瀏覽量
27844 -
華強(qiáng)pcb線路板打樣
+關(guān)注
關(guān)注
5文章
14629瀏覽量
43108
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論