基於FPGA通用異步收發器UART設計

摘要

通用異步收發器(UART)是一種能同時支持近距離和遠距離傳輸的異步串行接口,具有傳輸速率較高、傳輸距離長、抗干擾性能好、電路結構簡單以及節省佈線資源等優點。然而,隨着社會的發展,信息傳輸容量越來越大,傳統的 UART 成爲信息傳輸中的瓶頸。因此,提升 UART 的傳輸速率具有重大的意義。FPGA 芯片擁有數量衆多的 LE(邏輯單元),再加上數量衆多的佈線資源,使它具有非常強的靈活性。因此,使用 FPGA 實現的 UART 在傳輸速率使用靈活性以及性價比方面具有很大的優勢。
本文對 UART 芯片採用 FPGA 自頂向下的方法進行設計,所設計的 UART 模塊主要包括三大模塊,分別是 UART 接收模塊,UART 發送模塊和 OLED 顯示模塊。其中, UART 模塊按照傳統的 UART 協議進行設計,其波特率爲9600 baud/s,且波特率可調。另外,爲了驗證 UART 的正確性,利用串口調試助手,雙方之間按照 UART 通信協議進行通信,並利用 OLED 進行發送接收數據及波特率顯示。在具體的設計過程中,將結合 FPGA 的最新技術並利用 Quartus II 11.0,Modelsim 等 EDA 軟件對各個模塊進行綜合優化、功能仿真及下載實現。驗證結果表明, UART 模塊和串口調試助手之間能正常進行通信,OLED 模塊可正常顯示發送和接收數據以及波特率。

關鍵詞 UART;FPGA;OLED;自頂向下;RS232

第一章 緒 論

1.1 本課題的應用背景及研究的意義

UART(Universal Asynchronous Receiver Transmitter,通用異步收發器)是一種能同時支持近距離和遠距離傳輸的異步串行接口,是計算機中最普遍通用的一部分,被廣泛應用於微機和外設的數據交換,例如和鼠標、調制解調器、打印機之間以及微機與微機之間的串行數據傳輸[1]。因爲異步串行通信接口具有傳輸線少、成本低、 可靠性高、實現簡單等優點。因此,在 PC 和外設之間的串行通信中得到了廣泛的應用[2-3]。與此同時,異步串行通信接口廣泛應用在當今的嵌入式微處理芯片的設計中,另外,UART 總線標準廣泛應用在工控領域及家用電器領域。
現場可編程門陣列(Field-Programmable Gate Array,FPGA)誕生於上個世紀 90 年代,經過幾十年的飛快發展,顯然已成爲近幾年來電子通信行業的一個熱門名詞,有取代專用集成電路的趨勢[4-6]。一般的 FPGA 芯片是基於 4-LUT 的 SRAM 結 構,帶有豐富的 D 觸發器和佈線資源,除此之外,具有功能豐富、操作靈活的 Quartus II 軟件等,這些特點促使了 FPGA 的飛速發展,使其具有先天的靈活性以及高的性能與價格比[6]。FPGA 可廣泛應用於協議易於改變的通信領域、集成電路製造及驗證領域、儀器領域甚至是家用電器等領域,促進了這些領域的快速發展。
目前市場上國外的中高端 FPGA 芯片,不僅擁有傳統 FPGA 芯片的查找表+觸發器+佈線資源結構,還加入了一定數量的鎖相環路(PLL/DLL)、數字信號處理器 (DSP)核、ARM 核等等,甚至還加入了高速串行總線收發器模塊,這些額外的模 塊爲 FPGA 在高性能通信系統中的應用提供了現實的、廉價的解決方案,也爲高性能、小體積、低功耗的航空航天設備,個人便攜數字多媒體設備提供了可能。
雖然目前市場上主流嵌入式 CPU 片上都包含 1 或 2 個 UART 控制器,但是對於低端嵌入式控制器,尤其是 8 位甚至是 4 位機,鑑於成本的考慮,往往不帶有 UART 控制器,而且有時候嵌入式 CPU 本身的 UART 也不夠用,而市場上往往又沒有這樣的 UART 芯片,讓 IC 公司定製的話,成本往往很高。
因此,一種比較流行的方法是用硬件描述語言(HDL)對 UART 控制器電路進行建模、編譯、綜合、前後仿真、佈局佈線後,最後在 FPGA 芯片上實現。優點有 很多:1) 便於日後對控制器的少許電路進行修改,而不必像定製芯片那樣進行很大幅度的包括佈局、版圖等等的修改;2) 設計過程中的很多關鍵而複雜繁瑣的步驟, 由 EDA 工具(如 Altera 的 Quartus Ⅱ,Xilinx 的 ISE 等等),爲設計人員節省很多時間而又提升了設計準確度;3) 相對於定製芯片來說,大幅度節約製造成本。

1.2 本課題研究現狀

1.2.1 UART 芯片研究現狀

一般情況下,UART 芯片主要集成在主板上,比較常見的 UART 有 National Semiconductor Inc 生產的 INS 8250 系列(8250、16450 等)和 Zilog Inc 生產的 Z80SIO[7]。由於數據在計算機的內部採用的是並行傳輸方式,因此不能直接將並行數據發送到Modem。在進行數據傳輸之前必須經過UART的轉換才能進行異步傳輸。 就目前的發展來看,隨着集成電路的飛速發展,UART 產品已標準化,並且已經集成到了更大的電路中,但一些寄存器定義、接口等仍與 INS 8250 兼容[7]。
但是,有些速度比較慢的 UART 芯片,它很難實現一些應用所需求的高速的數據傳輸[8],雖然有些比較先進的 UART 芯片,例如 16550、16750 等,能達到高速通信的要求,但難免會存在一些問題,比如電路比較複雜、引腳較多、和其他器件的接口太複雜、成本比較高等,進而降低了系統的可靠性以及穩定性。隨着 FPGA 技 術的發展,設計者常常使用 FPGA 來實現 UART 接口,這樣不僅電路簡單,而且具有可移植性,能增加系統的穩定性和可靠性。

1.2.2 FPGA 器件研究現狀

在 80 年代,Xilinx 公司提出了一種半定製器件,即 FPGA(Field Programmable Gate Array),它以 PAL、GAL、EPLD、CPLD 等可編程通用器件爲基礎,並經歷了一系列的發展,是一種半定製的通用可編程器件[9-12]。它的到來,一方面優化了 ASIC 電路中的不足,另一方面也解決了之前的可編程通用器件的邏輯門數目比較少的問 題[13]。設計者可以根據項目目標需求,通過對 FPGA 器件進行編程設計以及進行相應配置來完成所需實現的邏輯功能。
在很久以前,FPGA 只是用作 ASIC 設計,或者是被認爲是 ASIC 設計的驗證平臺。但是,目前,隨着 FPGA 技術的不斷髮展和創新,越來越多的設計者看到了基於 FPGA 設計的衆多優點,因此越來越喜歡使用它來設計產品。基於 FPGA 的可編程設計在通信、航天和醫療電子等領域得到了廣泛的應用[14]。隨着 FPGA 芯片飛速的發展,它會具有越來越豐富的資源[15-17],可以用它來實現越來越多的電路功能。 與此同時,它又具有其他器件所沒有的特點。爲此,FPGA 在數字系統設計中的地位越來越重要。使用 FPGA 來實現電路設計,不僅電路會比較簡單,所佔用的邏輯資源也會減少[18],能滿足設計需求。
世界上目前製造 FPGA 芯片並且提供 EDA 軟件(綜合、仿真、IDE)以及技術性服務的廠商主要有:Altera、Xilinx、Latice、Mentor Graphics、Synopsys 等等,其中以 Altera、Xinlinx 的全系列 FPGA 以及 CPLD 芯片配套的集成開發環境(IDE)以及 Mentor Graphics 的 Modelsim 很受工程師的歡迎。

1.3 本課題主要研究內容

本課題研究的是基於 FPGA 的通用異步收發器設計,主要包含 UART 模塊和PC串口調試助手部分。UART 模塊分 UART 發送模塊和 UART 接收模塊。UART 模塊選擇 Altera 公司的 Cyclone IV EP4CE6E22C8 芯片,並採用 Altera 公司的 Quartus II 11.0 IDE 進行綜合設計,採用軟件自帶仿真工具進行仿真,硬件描述語言採用 Verilog HDL。另外,爲了 UART 模塊邏輯的正確性,採用PC串口調試助手對其進行設計驗證。根據 FPGA 的邏輯功能, UART 模塊與串口調試助手之間進行互相發送數據,並在 OLED 屏幕顯示收發數據及波特率,從而完成對 UART 的校驗。

第二章 基於 FPGA 的 UART 總體設計

2.1 UART 相關知識

2.1.1 異步串行通信基本概念

串行通信的通信方式是將傳輸的數據按照順序一位一位地進行傳送[8]。它具有傳送距離長、可靠性高、需要的數據線少等特點,因此外設和計算機之間的通信廣泛用串行通信[8]。串行通信的數據傳輸方式包括單工方式,半雙工方式和全雙工方式。
(1) 單工方式 單工方式最大的特點是隻允許按一個固定的方向進行數據傳送。這種通信方式的前提是已經規定了一端爲發送方,另一端爲接收方,並且傳輸方向不可以改變。比如常見的遙控、遙測等採用的單工通信方式。
(2) 半雙工方式 這種通信方式下 A 和 B 都具有發送和接收的功能,但是隻有一條通信線。因此,在特定的時間只能一方發送,另一方接收。或者一方爲接收端, 另一方爲發送端。在此種通信方式下不允許雙方同時發送或者同時接收。例如日常生活中常用的對講機。
(3) 全雙工方式 全雙工通信方式具有 2 條獨立的通信線路[19],一條爲 txd 用來發送,一條爲 rxd 用來接收。因此解決了單工或半雙工帶來的雙方不能同時發送和接收的缺點。但是,爲了保證全雙工通信,雙方的串行接口必須具備一套完全獨立 的發送器和接收器。
在串口通信中,異步通信方式是以字符爲單位進行傳送的,傳送的字符之間的間隔是沒有規律的,這樣可能使接收設備不能正確接收數據,因爲每接收完一個字符之後都不能確切的判斷下一個將被接收的字符將從何時開始[7]。因此就需要在每個字符的開始和結束處各加一個比特位[20],用來表示一個字符的開始以及結束。這些額外的位叫做起始位和停止位,爲了判斷傳輸的正確性,通常會加上一個奇偶校驗位。

2.1.2 UART 通信基礎

UART 是一種在通信領域、計算機領域、工控領域及家用電器領域中廣泛使用的一種接口設備[21]。它的工作方式爲:1) 採用全雙工通信方式,允許控制器同時進 行數據的發送與接收。其中 TXD 信號線爲數據發送信號線,即控制器由此信號線向外發送數據,RXD 信號線爲數據接收信號線,即控制器由此信號線從外部接收數據。 2) 採用異步通信方式,即收發器雙方沒有統一的同步時鐘線或在接收器方沒有采用時鐘提取電路,它的信號同步方式是靠信號幀的首尾定界符,其中電路空閒狀態爲高電平,當電路狀態由高電平轉變爲低電平且保持一定的時間後,則認定爲起始信號,接下來開始傳輸數據及校驗位。而當電路的狀態變爲高電平且保持一定的時間後,則認定爲終止電平,數據傳輸結束。3) 採用串行通信方式,發送數據之前,控 制器把來自 CPU 的並行數據轉換成串行數據,接收數據之後,控制器把串行數據轉 換成並行數據[21]。因此,UART 接口具有較高的數據傳輸速率、傳輸距離長、抗幹 擾性能好、電路結構簡單以及節省佈線資源等優點。
UART 要想實現全雙工異步串行通信[22],3 個主要部分是必不可少的:控制電路部分、發送電路部分和接收電路部分。其中,控制電路部分主要負責產生接收或發送的時鐘以及產生一些和 CPU 進行通信的控制信號[23];發送電路部分包括髮送緩衝 器和發送移位寄存器;接收電路部分包括接收緩衝器和接收移位寄存器。在實際的工程實現中,發送和接收緩衝器通常有兩種實現方法,即:寄存器組法和 FIFO 法。 寄存器組法簡單方便,但是其緩存容量有限,因此它會限制 UART 的波特率;FIFO 法有較高的存儲深度,可方便實現高波特率的 UART,但是其電路實現較複雜,但可以使用現成的 FIFO IP Core,實際的 UART 芯片,也幾乎均使用 FIFO 作爲緩衝區。 鑑於本設計的複雜性,本設計在 UART 模塊採用 8bit 寄存器組法來實現緩衝區。其內部結構如圖 2-1 所示。
在這裏插入圖片描述

圖 2-1 UART 內部結構
通常,在一個通信系統中,一個典型的 UART 的幀格式如圖 2-2 所示。
在這裏插入圖片描述
圖 2-2 UART 數據幀
按照 UART 的通信原理,本論文中所設計的 UART 模塊數據幀由 11 位數據構成。第 1 位是數據幀的起始位,低電平有效,標誌着一幀數據的開始;接下來的第 2 位至第 9 位是數據幀的串行數據部分,共 8 位,低位在前,高位在後;第 10 位和第 11 位 是數據幀的停止位,高電平有效,標誌着一幀數據的結束。

2.2 FPGA 芯片結構

一般的 FPGA 芯片內部包括可配置邏輯模塊 CLB、輸入輸出模塊 IOB 和內部佈線資源三個部分。其中,一個 CLB 一般包括 8 個或 10 個邏輯單元 LE,一個 LE 包 括一個 4 輸入查找表和一個 D 觸發器;每一個 IOB 一般由一個 IO buffer 和一個 D 觸發器構成;佈線資源有全局時鐘佈線資源、長線資源和短線資源[25]。除此之外, 目前的 FPGA 內部一般還包括 RAM、PLL、DSP 核,有的甚至有 ARM 核和高速串行總線收發器等模塊。FPGA 的芯片內部資源佈局如圖 2-3 所示。
在這裏插入圖片描述
圖 2-3 FPGA 的芯片內部資源佈局
在本課題的設計中,選擇的 FPGA 芯片爲 Altera Cyclone IV EP4CE6E22C8 芯片,開發板的型號爲 RZ-EasyFPGA A2.1。
(1) Altera Cyclone IV EP4CE6E22C8 芯片 Altera Cyclone IV EP4CE6E22C8 是 Altera 公司針對工業廉價解決方案這種應用場合推出的小規模 FPGA 芯片。該芯片擁有6272 LEs,92 User I/Os,276480 Memory Bits,30 Embedded multiplier 9-bit elements, 2 PLLs,10 Global Clocks。其中內核電壓爲 1.2V,IO 電壓可提供包括 3.3V LVCMOS 和 LVTTL、3.0V LVCMOS 和 LVTTL、default 2.5V、3.0V PCI 和 PCI-X、差分 HSTL 和差分 SSTL 各類電平標準、LVDS、差分 LPECL 等等多種電平標準,爲基於混合電平標準的大型電子系統模塊之間的互聯提供了極大的便利性。本設計綜合成的邏輯電路預計使用 150 個 LEs 左右。因此,採用這款芯片是綽綽有餘。
(2) FPGA 開發板 由於考慮到整個過程需耗費一定的資金,況且本設計的重點不在於硬件設計,關鍵在於 UART 代碼的編寫、編譯、綜合、時序約束及時序仿真等過程的正確實現。因此,本文作者使用現成的開發板,省去了硬件電路設計的 麻煩,把精力放在了程序設計上。本開發板的型號是 RZ-EasyFPGA A2.1,採用 Altera 公司的小規模、低價位的 FPGA 芯片 Cyclone IV EP4CE6E22C8 爲核心,並配以 hynix HY57V641620E 4Banks1Mbits16 的 SDRAM 顆粒以及各種時鐘、測溫、紅外、顯示、各種規格的 IO 接口等豐富的外設資源。開發板如圖 2-4 所示。

在這裏插入圖片描述
圖 2-4 FPGA 開發板

2.3 總體功能框圖及各部分的作用

本設計中採用 FPGA 的自頂向下的方法進行設計[26]。自頂向下(top-down)指的是先將一個大型系統自上而下分解成許多基本的小模塊,然後尋求每個小模塊的 設計思路,最後將這種思路用某種精確的方式去描述出來。它的實質是逐步分解。自頂向下的設計方法可用於絕大多數設計的建模,設計人員或者開發人員通常將一個大型系統劃分爲若干層模塊,首先對劃分出來的每個子模塊分別進行描述,最後採用實例化的方法來將每個模塊組成一個完整正確的系統。因此,自頂向下的設計方法是一種層次化的設計思想。
對於採用自頂向下的設計方法來說,編寫完各個模塊之後,在編寫頂層模塊時,需要把各個子模塊例化在頂層模塊中。常見的端口映射方法有兩種:基於名稱的映射方法和基於位置的映射方法。本設計採用基於位置映射的方法。
可見,大型系統分模塊化的設計方法將使整個設計結構清晰、層次分明,便於各個設計人員的分工合作、也便於後期的時序約束。在實際工程中,劃分模塊的原則是:高內聚、低耦合[27]。也就是說,模塊之間的接口聯絡信號越少越好,這樣能降低時序分析時接口時序分析的難度。此外,模塊的劃分也要適度,不能劃分的太粗,也不能劃分的太細,視情況而定。一般情況下,大型設計劃分 4-5 層就足夠了。
本論文中設計的 UART 模塊主要包括三大模塊,分別爲 UART 發送模塊, UART 接收模塊和 OLED 顯示模塊。設計的整體 UART 框圖如圖 2-5 所示。

圖 2-5 整體 UART 框圖

2.4 本章小結

本章主要介紹了 UART 的相關知識,詳細介紹了本設計中 UART 數據幀格式。介紹了 UART 的總體功能框圖及各部分的作用,以及本設計中所採用的 FPGA 芯片。整體設計對於大型系統的設計來說是至關重要的。它的核心思想是採用自頂向下的設計方法進行多層模塊的劃分,劃分好模塊後,單獨設計每一個子模塊,最後進行封裝即可。它的關鍵要點是如何恰到好處的劃分好每一個模塊,使每一個模塊的之 間的耦合度最低,方便後期的接口設計。因此,好的系統整體設計的基礎爲系統的設計成功奠定了基礎。

第三章 各功能模塊設計

3.1 OLED 模塊設計

OLED 模塊用於顯示UART發送和接收的數據,其 IO 管腳如圖 3-1 所示。
在這裏插入圖片描述
圖 3-1 OLED 模塊的 IO 管腳圖
各個 IO 管腳的具體功能如下:
█ clk:全局時鐘信號;
█ rst_n:全局異步復位信號,低電平有效;
█ key_123:按鍵調試信號;
█ rx_data[7…0]:接收數據寄存器,保存直至下一個數據來到 ;
█ rx_int:接收數據中斷信號,接收到數據期間始終爲高電平;

3.2 波特率選擇 模塊設計

波特率產生模塊負責生成發送模塊和接收模塊的波特率時鐘信號,然後利用這 個信號對發送模塊發送數據和接收模塊接收數據進行控制。它生成的波特率時鐘信 號週期爲外部時鐘的 16 倍。波特率選擇 模塊的 IO 管腳如圖 3-2 所示。
在這裏插入圖片描述
圖 3-2 波特率選擇模塊的 IO 管腳圖
各個 IO 管腳的具體功能如下:
█ clk:全局時鐘信號;
█ rst_n:全局異步復位信號,低電平有效;
█ key_123:按鍵調試信號;
█ bps_start:波特率起始信號 ;

3.3 串口接收 模塊設計

接收模塊是 UART 電路的重要組成部分。它負責利用接收波特率時鐘信號, 來控制接收電路接收串行輸入總線上的一幀數據,然後將其轉換爲 8 位並行數據並 在恰當時刻將其送入接收緩衝區中。由於大量使用數據選擇器鏈,造成組合邏輯延時很長,因此它也是 UART 電路的關鍵路徑。串口接收 模塊的 IO 管腳如圖 3-3 所示。
在這裏插入圖片描述
圖 3-3 串口接收 模塊的 IO 管腳圖
各個 IO 管腳的具體功能如下:
█ clk:全局時鐘信號;
█ rst_n:全局異步復位信號,低電平有效;
█ rx_data[7…0]:接收數據寄存器,保存直至下一個數據來到;
█ clk_bps:波特率時鐘信號;
█ rx_int:接收數據中斷信號,接收到數據期間始終爲高電平;
當接收波特率時鐘信號開始工作且接收移位寄存器爲空時,接收數據幀計數器 開始工作。此時接收的數據並不包括起始位,對於異步通信方式來說,起始位只起 到數據幀檢測標誌信號的作用。

3.4 串口發送 模塊設計

發送模塊是 UART 電路的重要組成部分。它負責將發送移位寄存器中的 8 位並行數據按照 UART 數據幀的幀格式轉換成串行發送數據,然後利用發送波特 率時鐘信號將其送上串行發送總線上。 當發送波特率時鐘開始工作時,發送數據幀計數器也同時工作。如果發送移位寄存器中的數據是有效的,那麼接下來將進行數據的移位發送。 當數據發送完畢時,接下來發送奇偶校驗位和停止位;待停止位發送完畢後, 電路又回到空閒狀態,等待下一幀數據的發送。發送 模塊的 IO 管腳如圖 3-4 所示。
在這裏插入圖片描述
圖 3-4串口發送 模塊的 IO 管腳圖
各個 IO 管腳的具體功能如下:
█ clk:全局時鐘信號;
█ rst_n:全局異步復位信號,低電平有效;
█ rx_data[7…0]:接收數據寄存器,保存直至下一個數據來到;
█ clk_bps:波特率時鐘信號;
█ rx_int:接收數據中斷信號,接收到數據期間始終爲高電平;

頂層模塊設計

UART 模塊一共包括六個子模塊,分別爲發送模塊,接收模塊,時鐘分頻模塊,波特率產生模塊,起始位檢測模塊,和液晶顯示模塊。頂層模塊的 IO 管腳如圖 3-5 所示。
在這裏插入圖片描述

第四章 總體仿真及調試

引腳分配

在這裏插入圖片描述

仿真時序圖

OLED模塊時序圖:在這裏插入圖片描述在這裏插入圖片描述
UART發送、接收仿真圖:在這裏插入圖片描述

串口助手調試

在這裏插入圖片描述

總體調試圖

在這裏插入圖片描述

總電路圖

在這裏插入圖片描述

第五章 Verilog代碼部分

module my_uart_top(			
clk,rst_n,				
rs232_rx,rs232_tx,				
key_1,key_2,key_3,			
oled_rst_n_out,oled_cs_n_out,			  
oled_dc_out,oled_clk_out,				
oled_data_out 				
);
input clk;			// 50MHz主時鐘
input rst_n;		//低電平復位信號
input key_1,key_2,key_3;
input rs232_rx;		// RS232接收數據信號
output rs232_tx;	//	RS232發送數據信號
output wire oled_rst_n_out;  //nokia5110 reset, active low
output wire oled_cs_n_out;  //nokia5110 chip select, active low
output wire oled_dc_out;  //nokia5110 data or command control
output wire oled_clk_out;  //nokia5110 clock
output wire oled_data_out;  //nokia5110 data 
wire key1,key2; 
wire bps_start1,bps_start2;	//接收到數據後,波特率時鐘啓動信號置位
wire clk_bps1,clk_bps2;		// clk_bps_r高電平爲接收數據位的中間採樣點,同時也作爲發送數據的數據改變點
wire[7:0] rx_data;	//接收數據寄存器,保存直至下一個數據來到
wire rx_int;		//接收數據中斷信號,接收到數據期間始終爲高電平
speed_select		speed_rx(								
.clk(clk),							
.rst_n(rst_n),							
.key_1(key_1),					     
.key_2(key_2),							
.key_3(key_3),							
.bps_start(bps_start1),							
.clk_bps(clk_bps1)						
);
my_uart_rx			my_uart_rx(
.clk(clk),	//接收數據模塊
.rst_n(rst_n),
.rs232_rx(rs232_rx),
.rx_data(rx_data),
.rx_int(rx_int),
.clk_bps(clk_bps1),
.bps_start(bps_start1)						
);
speed_select		speed_tx(
.clk(clk),	//波特率選擇模塊
.rst_n(rst_n),
.key_1(key_1),
.key_2(key_2),
.key_3(key_3),
.bps_start(bps_start2),
.clk_bps(clk_bps2)
);
my_uart_tx			my_uart_tx(
.clk(clk),	//發送數據模塊							
.rst_n(rst_n),							
.rx_data(rx_data),							
.rx_int(rx_int),							
.rs232_tx(rs232_tx),							
.clk_bps(clk_bps2),							
.bps_start(bps_start2)						
);
OLED				OLED(                  .clk(clk),//OLED顯示						
.rst_n(rst_n), 						
.rx_data(rx_data),						
.rx_int(rx_int),						
.oled_rst_n_out(oled_rst_n_out),						
.oled_cs_n_out(oled_cs_n_out),						
.oled_dc_out(oled_dc_out),						
.oled_clk_out(oled_clk_out),						
.oled_data_out(oled_data_out)                 );	

代碼不全,完整代碼整理好將上傳此博客,供大家學習。

分享決定高度,學習拉開差距

作爲學習者給大家分享自己完成的此作品,希望對大家有幫助,當然上文若有不妥之處,歡迎指正。

歡迎大家留言,批評指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章