設計使用宏晶科技的8 位單片機STC12C5A60S2 作為中央控制器, 結合NAND 閃存芯片K9F4008 存儲漢字庫的8×128 點陣LED 數字屏, 該點陣LED 數字屏具有存儲信息后離線顯示的功能。可應用到多種顯示環境,尤其像汽車等移動工具上的脫機顯示環境。 自上世紀90 年代以來, 隨著LED 顯示技術設計制造水平的不斷提高,LED 數字屏逐漸在生產和生活中大量使用,LED 數字屏以其特有的顯示介質, 在大面積, 全天候, 高亮度和超高亮度顯示屏領域凸現優勢。LED 顯示技術發展的十幾年中, 新器件和新技術不斷采用, 制造成本逐漸降低, 生產分工不斷細化, 但大量應用的同時也暴露出LED 顯示技術的若干缺陷, 總體上技術尚未成熟, 標準尚未完全建立, 有許多方面值得進行更深入的研究與改進。 隨著大規模集成電路的迅猛發展, 微處理器的運算、控制能力大大增加, 單片計算機已在很多工業及民用系統中承擔智能化的任務, 與迅猛發展的運算速度相比, 其端口擴展能力則遜色得多( 數目有限且擴展困難), 因此研發過程中不得不在節省端口上投入大量精力, 目前國內為解決端口擴展問題可采用軟件處理的方式,這樣加重了軟件編寫的難度,或采用擴展端口的專用芯片。這兩種方法將引起軟件成本的提高或硬件電路復雜度的提高,不利于一些小型系統的研發,STC12C5A60S2單片機具有多種串行傳輸模式, 在一定程度上解決了這個矛盾。 LED 數字屏應用非常廣泛, 不僅能顯示文字, 還能顯示各種圖形、圖表, 甚至各種動畫效果, 是廣告宣傳、新聞傳播的有力工具。 本文采用STC12C5A60S2 單片機、接口NAND 閃存和上位PC 機,實現了對16×128 點陣LED 數字屏的控制。 1 芯片選型 1.1 屏體 由于屏體是商業成品, 因此系統芯片的選型首選為能與屏體配合的芯片。屏體自備電源, 能直接將蓄電池的能量轉變為5 V 的直流電源, 并且這個電源也通過屏體的接口電纜輸出到系統板上。因此系統可直接引用該電源, 不必自備電源電路。 1.2 單片機 綜合考慮屏體和系統需求, 選用國內宏晶科技生產的單時鐘/機器周期(1T) 的單片機STC12C5A60S2。 STC12C5A60S2 是新一代高速8051 單片機, 其指令代碼完全兼容傳統8051, 但速度快8~12 倍。內部集成MAX810 專用復位電路, 其工作電壓范圍是3.5 V~5.5 V,滿足要求的電壓。由于是單周期的8051 ( 傳統8051 是12 周期), 可選擇較易于獲得準確波特率的11.059 2 MHz晶振, 而不必擔心工作速度降低。 STC12C5A60S2 有60 KB 的用戶應用程序空間,256 B的RAM 和1024 B 的XRAM.能滿足程序代碼的需求和緩沖區定義的需求。另有與程序存儲空間獨立的一片閃存區域, 可在應用編程中作EEPROM 使用。 STC12C5A60S2 有雙UART 以及ISP 串口, 串口資源足夠系統使用。另外通過宏晶科技提供的軟件, 使用UART 可很容易地實現程序下載。STC12C5A60S2 有36個通用I/O 口, 大部分可位控, 并具有強推挽輸出的能力, 足夠系統使用。 STC12C5A60S2 有4 個16 bit 定時器和一個獨立的波特率發生器, 另外還有兩個PCA 模塊, 能獲得豐富的定時器資源。STC12C5A60S2 有PDIP-40 封裝的芯片, 易于快速進入實驗。 1.3 閃存 因為16 ×16 點陣的漢字庫容量在250 KB 左右, 而MCS51 的尋址空間只有64 KB.接口大于64 KB 容量的普通存儲芯片就必須進行總線擴展, 采用兩次鎖存地址的方法來讀寫, 既需要復雜的電路, 又占用較長的存取時間。同樣,NOR 閃存與EPROM 的引腳結構相類似, 有同樣的接口復雜性, 成本也十分高。要實現單片機與字庫芯片的簡單接口( 不需擴展) , 只能選用串行結構的存儲器或命令、地址和數據復用總線結構的存儲器。 串行結構的存儲器多為EEPROM, 沒有很大的容量, 不適合做字庫芯片。因此只有選用命令、地址和數據復用總線的NAND 閃存作為字庫存儲芯片。 字庫所需的容量不大, 但最好能5 V 供電, 且編程的緩存要求較小的芯片。SAMSUNG 公司出品的K9F4008W 是一款512 KB 的NAND 閃存, 僅有8 個IO端口, 且工作電壓范圍較廣(3 V~5.5 V), 可以兼容3 V 和5 V 的硬件系統, 并且幀編程時僅需要32 B 的緩沖, 正適合作為字庫存儲的芯片。 因此, 閃存芯片的可電擦寫特性頁非常適用于需要更換字庫的場合。故該芯片是十分理想的漢字庫存儲器。 2 電路設計 根據系統整體結構設計的電路的原理圖如圖1 所示。 3.1 屏體接口模塊 屏體接口包括屏體接口頭文件、屏幕緩沖區的定義、屏體接口初始化、刷新定時器中斷服務程序和SPI中斷服務程序幾個部分。 屏體接口的頭文件screen.h 應該使屏幕緩沖區對其他應用可見, 并提供屏體初始化函數。具體定義如下: #ifndef _SCREEN_H_ #define _SCREEN_H_ #include “inc\board.h” extern u8 xdata SCR_BUF[16][16]; void screen_init(void); #endif 這樣就把屏幕緩沖區的結構暴露給應用, 但應用不必關心具體的屏幕刷新操作。 具體屏體接口的實現集中在一個文件screen.c 中定義。具體如下: 首先是屏幕緩沖區定義: u8 xdata SCR_BUF[16][16]_at_0x0000;//~0x00ff 256Bytes其次是當前顯示行和輸出列變量定義, 屬于靜態變量, 應用程序不可見。 static u8 data row,col; 然后是屏幕初始化, 包括刷新定時器0 的初始化、SPI 的初始化、鎖存bLatch 信號的初始化、屏幕緩沖區的初始清零以及定時器和SPI 中斷的優先權和使能位的初始化代碼略。 SPI 和定時器0 的中斷服務程序是屏體接口的關鍵。 定時器0 的中斷服務程序首先進行掃描行增量取模運算,并將掃描行輸出。然后依據掃描行取出屏幕緩沖區對應行的第一個字節發送到SPI 端口。同時列增量。 void display_ONe_screen(void)interrupt 1 using 3{ row = (++row)&0x0f; P0 = (P0 & 0xf0)|((~row)& 0xf); col = 0;SPDAT = ~SCR_BUF[row][col++]; } 這樣編寫的屏體驅動, 應用只要在初始化屏體后,向屏幕緩沖區中寫入要顯示的數據即可, 而不必關心屏幕顯示的細節。 3.2 UART 接口 UART 接口負責與上位機的數據收發, 盡管發送可以同步進行, 但接收必須異步進行。因而UART 接口的核心仍然應該是一個中斷服務程序。 UART 接口的頭文件uart.h 隱藏了接收緩沖區的信息, 用戶可調用的函數只有初始化、發送和接收。 #ifndef _UART_H_ #define _UART_H_ void uart_init(void); void uart_put_c(u8 ch); u8 uart_get_c(u8 *); #endif UART 的接口實現首先定義一個接收緩沖FIFO, 以及對FIFO 的讀下標uart_rd 和寫下標uart_wr, 他們都是文件內可見的靜態變量: static u8 xdata uart_buf[64]; static u8 uart_rd,uart_wr; bit fSend UART 的初始化包括進行FIFO 的初始化和UART格式、波特率、中斷的初始化。代碼略。 UART 的ISR 主要是服務于接收, 無條件地將數據裝入FIFO, 并調整寫入指針。 static void uart_isr(void)interrupt 4 using 1{ if(RI){RI = 0; uart_buf[uart_wr++] = SBUF; uart_wr &= 0x0f; } } 提供給用戶的發送程序首先檢測發送結束標記, 如果為0, 表示上次發送尚未結束, 直接返回錯誤信息1。 否則將要發送的信息發送并清零發送結束標記。這樣設計的發送程序, 其目的是將發送等待不限制在接口底層, 而是給上層一個決定是否等待發送結束的機會。 u8 uart_put_c(u8 ch){ if(! TI)return 1; TI = 0;SBUF = ch; return 0; } 同樣, 接收程序也給上層一個選擇等待的機會。接收函數首先判斷接收FIFO 是否為空, 如果為空或輸入指針參數錯誤, 則直接返回錯誤, 否則才從FIFO 中讀取數據并將數據存儲到指針指向的地址, 然后返回成功。 u8 uart_get_c(u8 *ch){ u8 i; if(! ch)return 1; if((i = (uart_rd+1)&0x0f) == uart_wr)return 1; uart_rd = i; *ch = uart_buf[i];return 0; } 3.3 閃存接口 閃存的存取有特殊的時序, 閃存的內部結構也和具體應用要求有很大的不同。因此閃存的接口需要仔細設計。 K9F4008 閃存芯片的存儲結構組織如圖2所示。 閃存接口提供的閃存初始化函數中就包括對這樣情況的處理。初始化函數要從閃存的第一個塊中讀出一個塊映射表, 該表下標是邏輯扇區, 表內每項存儲的是該邏輯扇區對應的物理塊編號。初始化函數在必要時對閃存進行讀寫校驗, 然后將壞塊從表中刪除。再尋找新的良好塊, 將其編號填入到對應邏輯扇區的表項中。這樣對應用來說, 只見到連續的扇區編號, 而不知道扇區究竟對應到那個塊。 閃存的接口頭文件Flash.h 如下: #ifndef _K9F4008_H_ #define _K9F4008_H_ void read_log_page(u8 sector,u8 page,u8 xdata *buf); u8 prog_log_page(u8 sector,u8 page,u8 xdata *buf); void erase_log_blk(u8 sector); bit flash_init(void); #endif 實現閃存的接口, 首先就是依據說明書的時序定義閃存的基本操作。這里是以宏定義實現基本操作的。 #define W_CMD(cmd_)\ bCLE=1; bWE=0; P2=(cmd_); bWE=1; bCLE=0 #define W_ADDR(addr1_,addr2_,addr3_)\ bALE=1; bWE=0; P2=(addr1_); bWE=1; \ bWE=0; P2=(addr2_); bWE=1; \ bWE=0; P2=(addr3_); bWE=1; \ bALE=0 #define W_DAT(dat_) bWE=0; P2=(dat_); bWE=1 #define wait_RB while(! bRB) #define l2p(x_) fat_tbl[(x_)] 3.4 EEPROM 內部集成的EEPROM 是與程序空間分開的, 利用ISP/IAP 技術可將內部DATAFLASH 當EEPROM,擦寫次數10 萬次以上。EEPROM 可分為若干個扇區, 每個扇區包含512 B.使用時, 建議同一次修改的數據放在同一個扇區, 不是同一次修改的數據放在不同的扇區, 不一定要用滿。數據存儲器的擦除操作是按扇區進行的。 sfr IAP_DATA = 0xC2; //Flash data register sfr IAP_ADDRH = 0xC3; //Flash address HIGH sfr IAP_ADDRL = 0xC4; //Flash address LOW sfr IAP_CMD = 0xC5; //Flash command register sfr IAP_TRIG = 0xC6; //Flash command trigger sfr IAP_CONTR = 0xC7; //Flash control register 根據使用說明對EEPROM 的寄存器進行定義。 來源:電子工程網 |