建TTL計(jì)算機(jī):深入解析Isetta復(fù)古計(jì)算機(jī)的設(shè)計(jì)與調(diào)試)
1. 項(xiàng)目概述從“泡泡車(chē)”到“邏輯門(mén)”——Isetta TTL Computer的誕生看到“Isetta TTL computer”這個(gè)標(biāo)題很多朋友可能會(huì)一愣Isetta不是那款經(jīng)典的寶馬“泡泡車(chē)”嗎怎么和TTL計(jì)算機(jī)扯上關(guān)系了這正是這個(gè)項(xiàng)目的迷人之處——它是一場(chǎng)跨越時(shí)空的硬核浪漫。這個(gè)項(xiàng)目并非要造一輛能跑的微型車(chē)而是借用Isetta那小巧、經(jīng)典、充滿(mǎn)工程智慧的外形作為一臺(tái)完全由TTL晶體管-晶體管邏輯芯片搭建的復(fù)古計(jì)算機(jī)的“機(jī)箱”和設(shè)計(jì)靈感。簡(jiǎn)單來(lái)說(shuō)這是一臺(tái)從零開(kāi)始、用最基礎(chǔ)的74系列邏輯芯片“拼”出來(lái)的、能夠真正運(yùn)行程序的計(jì)算機(jī)并且被巧妙地封裝在一個(gè)致敬Isetta汽車(chē)的主題外殼里。對(duì)于硬件愛(ài)好者、復(fù)古計(jì)算迷和計(jì)算機(jī)體系結(jié)構(gòu)的學(xué)習(xí)者而言這個(gè)項(xiàng)目有著致命的吸引力。在當(dāng)今一片ARM、x86的海洋中回歸到計(jì)算機(jī)最本源的狀態(tài)——用與非門(mén)、觸發(fā)器、移位寄存器這些基本積木親手搭建出CPU、內(nèi)存和IO系統(tǒng)——是一種無(wú)與倫比的學(xué)習(xí)和創(chuàng)造體驗(yàn)。它解決的不僅僅是“做一臺(tái)計(jì)算機(jī)”的問(wèn)題更是“徹底理解計(jì)算機(jī)如何從無(wú)到有工作”的問(wèn)題。你將從比特和時(shí)鐘周期開(kāi)始親眼見(jiàn)證指令如何被解碼、數(shù)據(jù)如何流動(dòng)、程序如何一步步執(zhí)行。這個(gè)過(guò)程遠(yuǎn)比在現(xiàn)成的開(kāi)發(fā)板上寫(xiě)幾行代碼來(lái)得深刻。適合誰(shuí)來(lái)玩這個(gè)項(xiàng)目首先你需要有強(qiáng)烈的求知欲和動(dòng)手能力。它不適合只想快速看到結(jié)果的“快餐式”玩家。其次你需要一定的電子基礎(chǔ)比如能看懂電路圖、會(huì)焊接、會(huì)用萬(wàn)用表和示波器。最后也是最重要的你需要有耐心。調(diào)試一堆74系列芯片組成的系統(tǒng)就像在迷宮里尋找出路但每一次成功的“跑碼”看到TTL串口輸出預(yù)期的字符帶來(lái)的成就感也是巨大的。接下來(lái)我將為你徹底拆解這個(gè)項(xiàng)目的核心思路、設(shè)計(jì)細(xì)節(jié)、實(shí)操步驟以及那些只有親手做過(guò)才會(huì)知道的“坑”。2. 核心設(shè)計(jì)思路為什么是TTL為什么是Isetta2.1 TTL芯片的選擇回歸數(shù)字邏輯的基石選擇TTL芯片尤其是經(jīng)典的74LS系列或更早的74系列作為核心構(gòu)件是這個(gè)項(xiàng)目的靈魂所在。這并非為了懷舊而懷舊而是有著深刻的教學(xué)和體驗(yàn)價(jià)值。為什么不是FPGA或單片機(jī)FPGA現(xiàn)場(chǎng)可編程門(mén)陣列和現(xiàn)代單片機(jī)如STM32功能強(qiáng)大集成度高但它們對(duì)我們而言是一個(gè)“黑盒”或“灰盒”。你寫(xiě)的是硬件描述語(yǔ)言或高級(jí)語(yǔ)言最終由綜合工具或編譯器轉(zhuǎn)化為底層的門(mén)電路和微操作這個(gè)過(guò)程是抽象的、不直觀(guān)的。而使用離散的TTL芯片每一個(gè)邏輯功能——比如一個(gè)8位鎖存器74LS373、一個(gè)算術(shù)邏輯單元74LS181或一個(gè)程序計(jì)數(shù)器74LS161——都對(duì)應(yīng)著一顆實(shí)實(shí)在在的芯片。你需要親手用導(dǎo)線(xiàn)將它們按照數(shù)據(jù)通路、控制通路連接起來(lái)。計(jì)算機(jī)的每一個(gè)組成部分都觸手可及時(shí)鐘的每一次跳動(dòng)帶來(lái)的電平變化你都可以用邏輯分析儀或示波器清晰地捕捉到。這種物理上的具象化是理解馮·諾依曼體系結(jié)構(gòu)最直接的方式。TTL芯片的優(yōu)缺點(diǎn)分析優(yōu)點(diǎn)直觀(guān)性每顆芯片功能單一明確如四2輸入與非門(mén)74LS00雙D觸發(fā)器74LS74電路行為可預(yù)測(cè)。教育性強(qiáng)制你從最底層思考數(shù)據(jù)流、控制信號(hào)和時(shí)序。社區(qū)與資料74系列芯片已有數(shù)十年歷史數(shù)據(jù)手冊(cè)齊全有大量復(fù)古計(jì)算機(jī)項(xiàng)目如BMOW、Magic-1等可供參考生態(tài)成熟?!奥钡膬?yōu)勢(shì)TTL芯片的工作頻率通常在幾MHz到幾十MHz這個(gè)速度足以讓你用示波器觀(guān)察關(guān)鍵信號(hào)的建立和保持時(shí)間親眼看到指令周期是如何分解為一個(gè)個(gè)機(jī)器狀態(tài)的。缺點(diǎn)復(fù)雜度與規(guī)模實(shí)現(xiàn)一個(gè)功能簡(jiǎn)單的8位CPU可能需要幾十甚至上百顆芯片電路板會(huì)非常龐大這也是為什么Isetta外殼是個(gè)有趣的挑戰(zhàn)。功耗與發(fā)熱相比CMOS芯片TTL芯片功耗較大特別是LS系列需要考慮電源設(shè)計(jì)和散熱。調(diào)試難度任何一個(gè)芯片的故障、任何一根連線(xiàn)的錯(cuò)誤或任何一個(gè)時(shí)序問(wèn)題都可能導(dǎo)致整個(gè)系統(tǒng)“跑飛”或毫無(wú)反應(yīng)排查起來(lái)如同大海撈針。注意在芯片選型上74LS系列低功耗肖特基是最平衡的選擇它比原始的74系列速度快、功耗低又比更先進(jìn)的74ALS、74F系列常見(jiàn)且便宜。對(duì)于核心的算術(shù)邏輯單元74LS181是一顆傳奇芯片它單獨(dú)實(shí)現(xiàn)了4位的算術(shù)邏輯運(yùn)算兩片級(jí)聯(lián)即可構(gòu)成8位ALU是很多自制CPU的核心。2.2 Isetta主題的融合當(dāng)工程遇見(jiàn)美學(xué)將計(jì)算機(jī)裝入Isetta主題外殼這絕不僅僅是為了好看。它體現(xiàn)了項(xiàng)目制學(xué)習(xí)Project-Based Learning中“主題化”的魅力將一項(xiàng)艱巨的工程任務(wù)轉(zhuǎn)化為一個(gè)充滿(mǎn)故事性和展示性的作品。結(jié)構(gòu)設(shè)計(jì)的挑戰(zhàn)與樂(lè)趣真實(shí)的Isetta汽車(chē)圓潤(rùn)小巧。將這個(gè)形態(tài)轉(zhuǎn)化為計(jì)算機(jī)機(jī)箱需要解決內(nèi)部布局、散熱風(fēng)道、接口擴(kuò)展如電源開(kāi)關(guān)、復(fù)位鍵、串口、LED指示燈等問(wèn)題。你可能需要用到3D打印來(lái)制作外殼或者改造現(xiàn)有的模型。如何將龐大的TTL主板、電源模塊、鍵盤(pán)/顯示接口板合理地塞進(jìn)這個(gè)有限的空間本身就是一個(gè)有趣的機(jī)械設(shè)計(jì)問(wèn)題。交互設(shè)計(jì)的隱喻你可以將汽車(chē)的某些元素與計(jì)算機(jī)功能對(duì)應(yīng)。例如車(chē)頭的大燈可以作為電源指示燈方向盤(pán)區(qū)域可以放置一個(gè)小的OLED屏幕來(lái)顯示系統(tǒng)狀態(tài)車(chē)門(mén)開(kāi)關(guān)可以設(shè)計(jì)成復(fù)位鍵。這種隱喻增強(qiáng)了項(xiàng)目的趣味性和沉浸感。展示與傳播價(jià)值一個(gè)造型獨(dú)特的計(jì)算機(jī)遠(yuǎn)比一塊裸露的電路板更能吸引眼球也更能向他人傳達(dá)“這是一臺(tái)我親手制造的、有生命的機(jī)器”的理念。它成為了一個(gè)絕佳的談話(huà)起點(diǎn)用于科普計(jì)算機(jī)原理。設(shè)計(jì)思路總結(jié)因此Isetta TTL Computer的設(shè)計(jì)哲學(xué)是“內(nèi)外兼修”。對(duì)內(nèi)追求極致的邏輯透明性和教育性采用最經(jīng)典的TTL芯片搭建核心系統(tǒng)對(duì)外追求極致的創(chuàng)意表達(dá)和工藝完成度用一個(gè) iconic 的外殼包裹復(fù)雜的電子內(nèi)臟形成強(qiáng)烈的反差和記憶點(diǎn)。3. 系統(tǒng)架構(gòu)與核心模塊拆解一個(gè)最簡(jiǎn)單的、能夠運(yùn)行程序的TTL計(jì)算機(jī)通常包含以下幾個(gè)核心模塊。我們將以一個(gè)典型的8位架構(gòu)為例進(jìn)行拆解。3.1 中央處理單元CPU設(shè)計(jì)CPU是計(jì)算機(jī)的大腦對(duì)于TTL計(jì)算機(jī)我們需要用多顆芯片“拼”出它的各個(gè)部件。3.1.1 寄存器組這是CPU的快速記憶單元。我們需要累加器A用于存放算術(shù)邏輯運(yùn)算的一個(gè)操作數(shù)和結(jié)果。通常用一片8位鎖存器如74LS373實(shí)現(xiàn)。通用寄存器B, C, ...用于暫存數(shù)據(jù)??梢杂枚嗥?4LS373實(shí)現(xiàn)。程序計(jì)數(shù)器PC存放下一條要執(zhí)行的指令的地址。這是一個(gè)需要能自動(dòng)1的計(jì)數(shù)器可以用兩片4位二進(jìn)制計(jì)數(shù)器74LS161級(jí)聯(lián)成8位其并行加載功能用于實(shí)現(xiàn)跳轉(zhuǎn)指令。指令寄存器IR存放當(dāng)前正在執(zhí)行的指令。用一片74LS373實(shí)現(xiàn)。地址寄存器AR存放當(dāng)前要訪(fǎng)問(wèn)的內(nèi)存地址。用一片74LS373實(shí)現(xiàn)從PC或指令中獲取地址。3.1.2 算術(shù)邏輯單元ALU這是執(zhí)行計(jì)算的核心。如前所述兩片74LS181級(jí)聯(lián)可以構(gòu)成一個(gè)功能強(qiáng)大的8位ALU。你需要通過(guò)模式選擇引腳S0-S3和模式控制引腳M來(lái)告訴它執(zhí)行加、減、與、或、移位等操作。ALU的輸出會(huì)連接累加器或通用寄存器。3.1.3 控制單元CU這是整個(gè)CPU乃至整個(gè)計(jì)算機(jī)最復(fù)雜、最體現(xiàn)設(shè)計(jì)智慧的部分。它負(fù)責(zé)解讀指令寄存器IR中的操作碼并在正確的時(shí)鐘周期內(nèi)產(chǎn)生一系列控制信號(hào)來(lái)打開(kāi)或關(guān)閉數(shù)據(jù)通路上的各個(gè)“閘門(mén)”。實(shí)現(xiàn)方式對(duì)于簡(jiǎn)單的CPU通常采用“硬連線(xiàn)控制”方式。這意味著你需要用大量的邏輯門(mén)74LS00, 04, 08, 32等和譯碼器74LS138來(lái)搭建一個(gè)“有限狀態(tài)機(jī)”。這個(gè)狀態(tài)機(jī)的輸入是指令操作碼和時(shí)鐘輸出是幾十根控制線(xiàn)如PC_INC,AR_LOAD,ALU_EN,RAM_WE等。微指令更高級(jí)的設(shè)計(jì)會(huì)引入“微碼”Microcode。你可以用一塊ROM如27系列EPROM作為控制存儲(chǔ)器。指令操作碼作為高位地址時(shí)鐘周期狀態(tài)作為低位地址從ROM中讀出的一個(gè)字節(jié)或一個(gè)字其每一位就對(duì)應(yīng)一根控制信號(hào)線(xiàn)。這種方式更靈活但增加了設(shè)計(jì)復(fù)雜度。3.1.4 內(nèi)部總線(xiàn)CPU內(nèi)部各部件之間通過(guò)內(nèi)部數(shù)據(jù)總線(xiàn)8位和地址總線(xiàn)例如8位或16位連接。總線(xiàn)不是一根線(xiàn)而是一組共享的連線(xiàn)。關(guān)鍵在于使用三態(tài)緩沖器如74LS245。任何想要向總線(xiàn)寫(xiě)數(shù)據(jù)的部件都必須通過(guò)三態(tài)門(mén)連接到總線(xiàn)并且同一時(shí)刻只能有一個(gè)部件的輸出使能否則會(huì)發(fā)生沖突。3.2 存儲(chǔ)器系統(tǒng)3.2.1 只讀存儲(chǔ)器ROM用于存儲(chǔ)永不改變的程序和固定數(shù)據(jù)。在復(fù)古項(xiàng)目中紫外線(xiàn)可擦除的EPROM如27C64, 27C256或電可擦除的EEPROM如28C64是經(jīng)典選擇。你需要一個(gè)編程器如TL866將編譯好的機(jī)器碼寫(xiě)入ROM。ROM的地址線(xiàn)連接地址總線(xiàn)數(shù)據(jù)線(xiàn)連接數(shù)據(jù)總線(xiàn)片選和輸出使能信號(hào)由地址譯碼電路和控制單元產(chǎn)生。3.2.2 隨機(jī)存取存儲(chǔ)器RAM用于存儲(chǔ)運(yùn)行時(shí)的變量和堆棧??梢允褂渺o態(tài)RAMSRAM如62系列芯片如6264, 62256。SRAM接口簡(jiǎn)單無(wú)需刷新電路。同樣它的讀/寫(xiě)使能信號(hào)由控制單元根據(jù)指令產(chǎn)生。3.2.3 地址譯碼CPU的地址總線(xiàn)寬度決定了可尋址空間如16位地址是64KB。你需要設(shè)計(jì)一個(gè)地址譯碼電路將不同的地址范圍映射到不同的設(shè)備ROM, RAM, IO設(shè)備。這通常使用比較器74LS688或譯碼器74LS138配合邏輯門(mén)來(lái)實(shí)現(xiàn)。例如規(guī)定地址0x0000-0x7FFF是ROM0x8000-0xFFFF是RAM。3.3 輸入輸出I/O與“跑碼”調(diào)試這是讓計(jì)算機(jī)與外界對(duì)話(huà)的關(guān)鍵也是調(diào)試時(shí)最重要的窗口。3.3.1 串行通信UART這是復(fù)古計(jì)算機(jī)最常用、最可靠的輸出方式。你需要一顆UART芯片如經(jīng)典的16550或其兼容型號(hào)如16C550。它的作用是實(shí)現(xiàn)并行數(shù)據(jù)到串行數(shù)據(jù)的轉(zhuǎn)換。你將CPU數(shù)據(jù)總線(xiàn)連接到UART并為其分配一個(gè)或幾個(gè)IO端口地址。更底層、更“硬核”的做法是用TTL芯片自己搭建一個(gè)軟件UARTSoftware UART通過(guò)精確的延時(shí)循環(huán)用一根GPIO引腳模擬串行數(shù)據(jù)發(fā)送。但這需要CPU有精確的定時(shí)能力且會(huì)占用大量CPU時(shí)間。3.3.2 “跑碼”與調(diào)試接口“跑碼”這個(gè)詞在硬件調(diào)試中非常形象指的是通過(guò)串口輸出運(yùn)行日志或調(diào)試信息觀(guān)察程序執(zhí)行流程。你需要編寫(xiě)最基礎(chǔ)的監(jiān)控程序Monitor或引導(dǎo)程序Bootloader燒錄在ROM中。計(jì)算機(jī)上電后首先運(yùn)行這段程序它初始化UART然后可能打印出一個(gè)歡迎信息如“Isetta TTL Computer v1.0”并進(jìn)入一個(gè)簡(jiǎn)單的命令行循環(huán)等待用戶(hù)輸入命令如查看內(nèi)存、修改內(nèi)存、運(yùn)行程序。為了在系統(tǒng)完全無(wú)法啟動(dòng)時(shí)進(jìn)行調(diào)試你必須預(yù)留一個(gè)硬件調(diào)試接口——這就是標(biāo)題熱詞中反復(fù)出現(xiàn)的“TTL”的另一層含義串口電平轉(zhuǎn)換。你需要引出一個(gè)USB轉(zhuǎn)TTL串口的接頭通常包含TX, RX, GND三根線(xiàn)。這里的“TTL”指的是0V/5V或3.3V的邏輯電平與芯片的TTL電平兼容。通過(guò)這個(gè)接口你可以用PC上的終端軟件如Putty, Tera Term, screen連接到你的計(jì)算機(jī)查看最原始的啟動(dòng)信息這是救命的“最后一根稻草”。實(shí)操心得在設(shè)計(jì)PCB時(shí)務(wù)必將UART的TX、RX引腳通過(guò)排針引出并標(biāo)記清楚。同時(shí)最好將系統(tǒng)的主時(shí)鐘信號(hào)也引到測(cè)試點(diǎn)上。當(dāng)系統(tǒng)“跑飛”或毫無(wú)反應(yīng)時(shí)先用示波器檢查時(shí)鐘是否正常再用USB-TTL線(xiàn)連接串口看看ROM中的初始程序有沒(méi)有任何輸出。很多時(shí)候問(wèn)題就出在地址譯碼錯(cuò)誤或控制信號(hào)時(shí)序不對(duì)導(dǎo)致CPU第一條指令都取不到。3.3.3 簡(jiǎn)單輸入與輸出輸入可以連接一個(gè)簡(jiǎn)單的矩陣鍵盤(pán)或者幾個(gè)撥碼開(kāi)關(guān)作為數(shù)據(jù)輸入端口。輸出除了串口可以連接一些LED燈來(lái)顯示地址總線(xiàn)或數(shù)據(jù)總線(xiàn)上的活躍數(shù)據(jù)或者連接一個(gè)七段數(shù)碼管顯示數(shù)字。這些設(shè)備都需要通過(guò)鎖存器如74LS373或?qū)S肐O芯片如8255連接到總線(xiàn)上并分配獨(dú)立的IO地址。4. 實(shí)操構(gòu)建全流程解析假設(shè)你已經(jīng)完成了電路設(shè)計(jì)使用KiCad或Eagle繪制了原理圖和PCB并拿到了打樣回來(lái)的電路板。接下來(lái)就是充滿(mǎn)挑戰(zhàn)和樂(lè)趣的構(gòu)建階段。4.1 焊接與組裝耐心是唯一的捷徑物料準(zhǔn)備與檢查將所有74系列芯片、存儲(chǔ)器、UART、晶振、電阻電容等按BOM表清點(diǎn)。強(qiáng)烈建議使用IC插座特別是對(duì)于復(fù)雜的核心芯片如ALU、UART、ROM。這便于后續(xù)更換和測(cè)試。用萬(wàn)用表二極管檔檢查PCB電源和地之間是否有短路。這是上電前最重要的步驟焊接順序策略先電源后信號(hào)首先焊接電源相關(guān)的元件如電源插座、濾波電容、穩(wěn)壓芯片如7805。焊接完成后先不要插任何IC用可調(diào)電源限流給板子供電測(cè)量各IC插座的VCC和GND引腳電壓是否為穩(wěn)定的5VTTL標(biāo)準(zhǔn)。先核心后外圍接著焊接最小系統(tǒng)的核心時(shí)鐘電路晶振、諧振電容、復(fù)位電路、程序計(jì)數(shù)器PC、指令寄存器IR以及連接它們的必要邏輯門(mén)。目標(biāo)是讓CPU能完成最簡(jiǎn)單的“取指-執(zhí)行”循環(huán)比如一個(gè)NOP空操作指令。模塊化焊接與測(cè)試不要一次性焊完全部芯片。焊好一個(gè)模塊如ALU模塊就進(jìn)行測(cè)試。如何測(cè)試可以編寫(xiě)一個(gè)極其簡(jiǎn)單的測(cè)試程序燒入ROM該程序只測(cè)試ALU的加法功能并通過(guò)某種方式比如點(diǎn)亮特定的LED顯示結(jié)果。使用邏輯分析儀捕捉相關(guān)信號(hào)是最佳方式。焊接技巧使用合適的焊錫建議含鉛焊錫流動(dòng)性好和烙鐵溫度350°C左右。確保焊點(diǎn)飽滿(mǎn)、光亮呈圓錐形避免虛焊和橋接。焊接完成后用放大鏡檢查是否有錫珠或細(xì)微的橋接并用酒精清洗板子去除助焊劑。4.2 “心臟起搏”——時(shí)鐘與復(fù)位電路時(shí)鐘電路一個(gè)穩(wěn)定的時(shí)鐘是整個(gè)系統(tǒng)同步的基礎(chǔ)。可以使用有源晶振模塊如4MHz, 8MHz它輸出穩(wěn)定方波接上電源和地就能工作最簡(jiǎn)單可靠。也可以使用無(wú)源晶振配合反相器74LS04搭建皮爾斯振蕩器但穩(wěn)定性稍差需要仔細(xì)調(diào)整匹配電容。復(fù)位電路確保系統(tǒng)上電時(shí)處于已知狀態(tài)。一個(gè)簡(jiǎn)單的RC電路電阻電容加上一個(gè)施密特觸發(fā)器反相器74LS14可以產(chǎn)生穩(wěn)定的上電復(fù)位脈沖。務(wù)必在復(fù)位引腳附近放置一個(gè)手動(dòng)復(fù)位按鈕這在調(diào)試時(shí)無(wú)比重要。4.3 軟件工具鏈搭建從助記符到機(jī)器碼你的TTL計(jì)算機(jī)只能理解二進(jìn)制機(jī)器碼。你需要一套工具將匯編語(yǔ)言或高級(jí)語(yǔ)言轉(zhuǎn)換成它認(rèn)識(shí)的格式。匯編器你可以使用通用的跨平臺(tái)匯編器如vasm或NASM并為你的自定義CPU指令集編寫(xiě)一個(gè)特定的匯編規(guī)則文件。更直接的方法是用Python或C自己寫(xiě)一個(gè)簡(jiǎn)單的匯編器。你的指令集ISA可能很簡(jiǎn)單比如只有十幾條指令LDA, STA, ADD, JMP, JZ等自己寫(xiě)匯編器并不難。編譯器可選如果想挑戰(zhàn)更高難度可以為你的CPU設(shè)計(jì)一個(gè)后端移植一個(gè)小的C編譯器如SDCC、LLVM但這屬于“地獄難度”。編程器你需要一個(gè)EEPROM/EPROM編程器將匯編器生成的二進(jìn)制文件.bin或.hex格式燒錄到ROM芯片中。TL866系列是性?xún)r(jià)比很高的選擇。模擬器強(qiáng)烈推薦在將程序燒入物理ROM之前一定要先在軟件模擬器中運(yùn)行測(cè)試。你可以用C或Python寫(xiě)一個(gè)簡(jiǎn)單的CPU模擬器模擬你的硬件架構(gòu)執(zhí)行指令的過(guò)程。這能幫你發(fā)現(xiàn)程序邏輯錯(cuò)誤避免反復(fù)燒寫(xiě)ROMEEPROM有擦寫(xiě)次數(shù)限制EPROM需要紫外線(xiàn)擦除非常麻煩。4.4 系統(tǒng)聯(lián)調(diào)與“第一次心跳”當(dāng)所有硬件模塊焊接測(cè)試完畢并燒錄好一個(gè)最簡(jiǎn)單的“Hello World”程序通過(guò)串口發(fā)送字符串后就到了最激動(dòng)人心也最令人緊張的上電聯(lián)調(diào)時(shí)刻。上電前最后檢查目視檢查所有芯片方向、有無(wú)插反用萬(wàn)用表再次確認(rèn)電源無(wú)短路連接好USB-TTL調(diào)試串口線(xiàn)到PC終端軟件。首次上電打開(kāi)電源觀(guān)察板子有無(wú)異常冒煙、芯片過(guò)熱。立即查看終端軟件期待屏幕上出現(xiàn)你預(yù)設(shè)的歡迎信息。如果沒(méi)有輸出大概率事件檢查時(shí)鐘用示波器探頭測(cè)量CPU的時(shí)鐘輸入引腳看是否有規(guī)整的方波。檢查復(fù)位測(cè)量復(fù)位引腳上電后是否有一個(gè)從低到高的跳變。檢查地址總線(xiàn)活動(dòng)將示波器設(shè)置為滾動(dòng)模式觀(guān)察地址總線(xiàn)例如A0-A7是否有跳變活動(dòng)。如果完全沒(méi)有活動(dòng)說(shuō)明CPU可能沒(méi)有啟動(dòng)重點(diǎn)檢查時(shí)鐘、復(fù)位和電源。檢查控制信號(hào)觀(guān)察/RD讀、/WR寫(xiě)、/MREQ存儲(chǔ)器請(qǐng)求等關(guān)鍵控制信號(hào)是否有脈沖。邏輯分析儀是終極武器如果條件允許用邏輯分析儀同時(shí)捕捉地址總線(xiàn)、數(shù)據(jù)總線(xiàn)和關(guān)鍵控制信號(hào)。分析上電后第一個(gè)指令周期的波形看CPU是否正確地輸出了第一條指令的地址通常是0x0000ROM是否在/RD有效時(shí)輸出了正確的數(shù)據(jù)即第一條指令的操作碼。“跑碼”成功當(dāng)終端上終于出現(xiàn)字符哪怕是一個(gè)亂碼也是巨大的勝利這說(shuō)明數(shù)據(jù)通路基本是通的。接下來(lái)可能就是調(diào)整波特率、檢查UART初始化代碼等問(wèn)題了。5. 深度調(diào)試當(dāng)TTL“跑碼”停不下來(lái)熱詞中提到的“ttl跑碼一直停不下來(lái)解決方法”這描述了一個(gè)非常經(jīng)典的硬件調(diào)試場(chǎng)景系統(tǒng)似乎啟動(dòng)了串口也在不斷輸出數(shù)據(jù)但輸出的是無(wú)意義的亂碼、重復(fù)字符或者程序顯然沒(méi)有按預(yù)期執(zhí)行看起來(lái)就像“跑飛”了停在一個(gè)錯(cuò)誤的狀態(tài)循環(huán)輸出。5.1 問(wèn)題根源分析這通常不是單一問(wèn)題而是系統(tǒng)不穩(wěn)定的綜合表現(xiàn)根源多在時(shí)序和信號(hào)完整性。時(shí)序違例Setup/Hold Time Violation這是數(shù)字電路的頭號(hào)殺手。以CPU從ROM讀取指令為例CPU在時(shí)鐘上升沿將地址送到地址總線(xiàn)經(jīng)過(guò)一段Tco時(shí)鐘到輸出延時(shí)后地址穩(wěn)定。ROM收到地址后需要一段Tacc地址訪(fǎng)問(wèn)時(shí)間才能輸出穩(wěn)定數(shù)據(jù)。這個(gè)穩(wěn)定數(shù)據(jù)必須在CPU時(shí)鐘下一個(gè)上升沿到來(lái)之前提前一段時(shí)間建立時(shí)間Tsu就準(zhǔn)備好并且在上升沿之后還要保持一段時(shí)間保持時(shí)間Th。如果Tacc太長(zhǎng)或者布線(xiàn)導(dǎo)致延遲過(guò)大數(shù)據(jù)還沒(méi)穩(wěn)定時(shí)鐘沿就來(lái)了CPU就會(huì)讀到錯(cuò)誤的數(shù)據(jù)指令從而導(dǎo)致不可預(yù)測(cè)的執(zhí)行結(jié)果程序“跑飛”。總線(xiàn)沖突如果兩個(gè)輸出設(shè)備例如兩個(gè)寄存器同時(shí)試圖向數(shù)據(jù)總線(xiàn)寫(xiě)數(shù)據(jù)而它們的輸出使能信號(hào)有重疊就會(huì)發(fā)生沖突導(dǎo)致總線(xiàn)電平不確定讀回錯(cuò)誤數(shù)據(jù)。電源噪聲TTL芯片在狀態(tài)切換瞬間會(huì)產(chǎn)生較大的瞬態(tài)電流如果電源去耦不足比如IC旁邊沒(méi)有放置足夠的0.1uF陶瓷電容會(huì)導(dǎo)致電源網(wǎng)絡(luò)上產(chǎn)生毛刺可能被其他芯片誤認(rèn)為是邏輯信號(hào)。未初始化的狀態(tài)上電時(shí)某些觸發(fā)器或鎖存器處于隨機(jī)狀態(tài)。如果控制邏輯依賴(lài)于這些狀態(tài)系統(tǒng)可能進(jìn)入非設(shè)計(jì)狀態(tài)。** metastability亞穩(wěn)態(tài)**當(dāng)異步信號(hào)如按鍵輸入沒(méi)有經(jīng)過(guò)同步處理就直接進(jìn)入時(shí)鐘系統(tǒng)時(shí)可能引發(fā)亞穩(wěn)態(tài)導(dǎo)致后續(xù)邏輯產(chǎn)生不可預(yù)測(cè)的錯(cuò)誤。5.2 系統(tǒng)性排查與解決方法面對(duì)“跑碼停不下來(lái)”你需要像偵探一樣系統(tǒng)性地排查。第一步簡(jiǎn)化系統(tǒng)拔掉所有非核心芯片。只留下時(shí)鐘、復(fù)位、CPU最核心的PC、IR、必要的控制邏輯、ROM里面燒錄一個(gè)超級(jí)簡(jiǎn)單的死循環(huán)程序比如不斷向一個(gè)特定IO地址寫(xiě)固定值。目標(biāo)是讓系統(tǒng)執(zhí)行最簡(jiǎn)單的確定性操作。第二步靜態(tài)測(cè)試編寫(xiě)一個(gè)測(cè)試程序不依賴(lài)任何條件判斷或跳轉(zhuǎn)。例如連續(xù)執(zhí)行幾條LDA #$55加載立即數(shù)0x55到累加器和STA $8000將累加器值存儲(chǔ)到地址0x8000指令。用邏輯分析儀觀(guān)察在每一個(gè)時(shí)鐘周期地址總線(xiàn)、數(shù)據(jù)總線(xiàn)、控制總線(xiàn)/RD,/WR,/IO的信號(hào)是否完全符合你的設(shè)計(jì)預(yù)期。重點(diǎn)檢查/WR信號(hào)有效時(shí)數(shù)據(jù)總線(xiàn)上的值是否是你期望的0x55。第三步動(dòng)態(tài)時(shí)序分析使用邏輯分析儀或高性能示波器的時(shí)序分析功能。測(cè)量關(guān)鍵路徑測(cè)量從時(shí)鐘上升沿開(kāi)始到某個(gè)關(guān)鍵信號(hào)如存儲(chǔ)器讀數(shù)據(jù)穩(wěn)定所需的最大時(shí)間。與芯片數(shù)據(jù)手冊(cè)上的Tsu要求對(duì)比。檢查信號(hào)質(zhì)量用示波器探頭務(wù)必使用接地彈簧避免長(zhǎng)地線(xiàn)夾引入噪聲近距離測(cè)量數(shù)據(jù)總線(xiàn)、地址總線(xiàn)上的信號(hào)波形??瓷仙?下降沿是否陡峭有無(wú)振鈴ringing、過(guò)沖overshoot或回溝non-monotonic。振鈴和過(guò)沖嚴(yán)重時(shí)可能在邏輯閾值附近來(lái)回震蕩被誤判為多次跳變。第四步常見(jiàn)硬件整改措施增加等待狀態(tài)如果ROM速度慢是瓶頸最簡(jiǎn)單的辦法是讓CPU插入等待狀態(tài)。設(shè)計(jì)一個(gè)“就緒READY”信號(hào)生成電路當(dāng)CPU訪(fǎng)問(wèn)慢速設(shè)備時(shí)拉低READYCPU自動(dòng)延長(zhǎng)總線(xiàn)周期直到數(shù)據(jù)準(zhǔn)備好。改善電源完整性在每一片IC的VCC和GND引腳之間盡可能靠近引腳的地方并聯(lián)一個(gè)0.1uF104和一個(gè)10uF的陶瓷電容。大電容應(yīng)對(duì)低頻波動(dòng)小電容應(yīng)對(duì)高頻噪聲。電源走線(xiàn)要粗形成低阻抗路徑。處理未用輸入引腳所有TTL芯片未使用的輸入端絕不能懸空必須上拉到VCC通過(guò)一個(gè)1k-10k電阻或下拉到GND否則會(huì)因噪聲導(dǎo)致功耗增加和邏輯不穩(wěn)定。信號(hào)同步對(duì)所有來(lái)自外部的異步輸入信號(hào)如按鍵使用兩個(gè)級(jí)聯(lián)的D觸發(fā)器進(jìn)行同步化處理消除亞穩(wěn)態(tài)??偩€(xiàn)管理嚴(yán)格設(shè)計(jì)三態(tài)輸出使能信號(hào)的時(shí)序確保在切換驅(qū)動(dòng)源時(shí)存在一個(gè)所有驅(qū)動(dòng)都關(guān)閉的“死區(qū)時(shí)間”避免沖突。第五步軟件輔助調(diào)試在你的監(jiān)控程序中加入盡可能多的“燈塔”式輸出。例如在每一個(gè)關(guān)鍵函數(shù)入口通過(guò)串口打印一個(gè)特定的字符。這樣即使程序跑飛你也能通過(guò)最后打印的字符判斷出它是在哪里飛掉的。避坑技巧實(shí)錄我曾遇到一個(gè)詭異的問(wèn)題系統(tǒng)運(yùn)行幾分鐘后隨機(jī)死機(jī)。用示波器觀(guān)察電源發(fā)現(xiàn)每當(dāng)一個(gè)大電流芯片如多個(gè)LED同時(shí)點(diǎn)亮動(dòng)作時(shí)5V電源上有一個(gè)幾百毫伏的毛刺。最后發(fā)現(xiàn)是穩(wěn)壓芯片7805的散熱不足導(dǎo)致熱保護(hù)間歇性啟動(dòng)。解決方法是在7805上加了更大的散熱片并在電源入口處增加了一個(gè)大的電解電容470uF儲(chǔ)能。所以電源永遠(yuǎn)是第一嫌疑人。6. 外殼制作與系統(tǒng)集成當(dāng)你的核心板穩(wěn)定運(yùn)行能通過(guò)串口與你愉快地對(duì)話(huà)后就可以開(kāi)始Isetta外殼的創(chuàng)作了。三維建模與測(cè)量使用Fusion 360、SolidWorks或Blender等軟件根據(jù)Isetta的圖片或圖紙建立外殼模型。關(guān)鍵是要精確測(cè)量你的主板、電源模塊、鍵盤(pán)顯示模塊的尺寸在模型內(nèi)為其預(yù)留空間和安裝柱。內(nèi)部布局規(guī)劃散熱TTL芯片尤其是LS系列功耗不容小覷。需要在外殼上設(shè)計(jì)通風(fēng)孔。可以考慮在主要發(fā)熱芯片如ALU、RAM上方加裝小型散熱片甚至使用一個(gè)安靜的4010或5010風(fēng)扇進(jìn)行主動(dòng)排風(fēng)風(fēng)扇電源可從主板5V取電。接口將USB轉(zhuǎn)TTL調(diào)試口、電源開(kāi)關(guān)、復(fù)位按鈕、SD卡槽如果擴(kuò)展了存儲(chǔ)等引到外殼上方便操作的位置??梢允褂醚娱L(zhǎng)線(xiàn)或帶面板安裝的接插件。顯示與交互如果空間允許可以在“儀表盤(pán)”位置嵌入一塊小尺寸LCD或OLED屏幕用于顯示系統(tǒng)狀態(tài)。用幾個(gè)復(fù)古風(fēng)格的撥動(dòng)開(kāi)關(guān)或按鈕作為輸入。制作與裝飾3D打印這是最靈活的方式??梢允褂肞LA或ABS材料。打印后可能需要打磨、上膩?zhàn)?、噴漆?lái)獲得光滑的表面。噴漆可以選用寶馬Isetta經(jīng)典的乳白、淺藍(lán)等顏色。改裝現(xiàn)有模型購(gòu)買(mǎi)一個(gè)足夠大的Isetta汽車(chē)塑料拼裝模型將其內(nèi)部掏空用于安裝電子設(shè)備。這種方式外觀(guān)效果可能更好但改造難度大。細(xì)節(jié)添加打印或制作寶馬Logo、車(chē)燈格柵等細(xì)節(jié)貼在外殼上增加辨識(shí)度。將主板、電源等安裝進(jìn)外殼連接好所有內(nèi)部線(xiàn)纜合上外殼可以考慮用磁吸或卡扣方式方便后續(xù)打開(kāi)維護(hù)。一臺(tái)獨(dú)一無(wú)二的、充滿(mǎn)機(jī)械美感和極客精神的Isetta TTL Computer就誕生了。通電后終端上閃爍的光標(biāo)仿佛是這個(gè)“電子大腦”在呼吸而它居住在一個(gè)來(lái)自上世紀(jì)中葉的經(jīng)典汽車(chē)軀殼里這種時(shí)空交錯(cuò)的感覺(jué)正是此類(lèi)項(xiàng)目最迷人的地方。整個(gè)項(xiàng)目從邏輯設(shè)計(jì)到物理實(shí)現(xiàn)從軟件編碼到硬件調(diào)試從功能實(shí)現(xiàn)到美學(xué)包裝是一個(gè)完整的、跨學(xué)科的創(chuàng)造過(guò)程。它帶給你的不僅是一臺(tái)可以工作的計(jì)算機(jī)更是一套解決問(wèn)題的思維方法、對(duì)計(jì)算機(jī)本質(zhì)的深刻理解以及將抽象想法變?yōu)榫唧w實(shí)物的巨大滿(mǎn)足感。每一次排查故障后的豁然開(kāi)朗每一次功能實(shí)現(xiàn)后的欣喜若狂都構(gòu)成了獨(dú)屬于制造者的珍貴記憶。