一、8*8點陣顯示圖形所用主要器件
1.1 8*8點陣
(1)內部結構
點陣存在兩種不同的類型:
①左圖為(行)共陽;
②右圖為(行)共陰。
工藝和使用上二者無差別,需要在使用前進行測試確認其屬性。
在后續取子模時,如果行接的是二極管的陽極,列接的是二極管的陰極,則采用行掃描時列取模方式即為陽碼,采用列掃描時行的取模方式即為陰碼。對應的若行接二極管陰極,列接二極管陽極,則采用行掃描時取模方式為陰碼,采用列掃描時取模方式為陽碼。
(2)8*8點陣工作原理及控制
8*8點陣顯示圖形實質上是利用行列分別輸入的01信號,選通某一確定節點上的發光二極管,進行發光。
以行共陽LED點陣為例,只要其對應的RO、CO軸順向偏壓,即可使LED發亮。例如如果想使左上角LED點亮,則只需ROW(1)= 1,COL(1)= 0,即9腳給高電平、13腳給低電平。
圖中POS1-8對應8*8點陣的8的陽極接口,NEG1-8對應8*8點陣的8的陰極接口。
陽極由時鍾電路給入掃描信號,陰極連接74HC595輸出的8位信號,在每一掃描周期內進行選通。
(3)8*8LED點陣擴展為16*16LED點陣
顯然,需要4片8*8點陣屏進行拼裝。
同一列2片8*8點陣屏,陰極並聯;同一行2片8*8點陣屏,陽極並聯。
1.2 74LS138
(1)概述
74LS138 為3線-8線譯碼器,共有74LS138D和74LS138N兩種線路結構型式。74LS138D為軍用,74LS138N為民用。
(2)功能簡介
① 當一個選通端(E1)為高電平,另兩個選通端(/E2)和(/E3)為低電平時,可將地址端(A0、A1、A2)的二進制編碼在Y0至Y7對應的輸出端以低電平譯出。(即輸出為Y0至Y7的非)比如:A2A1A0=110時,則Y6輸出端輸出低電平信號。
② 利用 E1、/E2和/E3可級聯擴展成 24 線譯碼器;若外接一個反相器還可級聯擴展成 32 線譯碼器。
③ 若將選通端中的一個作為數據輸入端時,74LS138還可作數據分配器。
(3)基本參數
(4)引腳說明
① A0~A2:地址輸入端
② E1:選通端
③ /E2、/E3:選通端(低電平有效)
④ Y0~Y7:輸出端(低電平有效)
⑤ VCC:電源正
⑥ GND:地
⑦ A0~A2對應Y0——Y7:A0,A1,A2以二進制形式輸入,然后轉換成十進制,對應相應Y的序號輸出低電平,其他均為高電平。
(5)真值表
輸入 |
輸出 |
||||||||||||
E1 |
/E2 |
/E3 |
A2 |
A1 |
A0 |
/Y0 |
/Y1 |
/Y2 |
/Y3 |
/Y4 |
/Y5 |
/Y6 |
/Y7 |
× |
1 |
× |
× |
× |
× |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
× |
× |
1 |
× |
× |
× |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
× |
× |
× |
× |
× |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1.3 74LS161
(1)概述
4HC161和74LS161都是常用的四位二進制可預置的同步加法計數器,74HC161是CMOS型,74LS161是TTL型。它可以靈活的運用在各種數字電路,以及單片機系統中實現分頻器等很多重要的功能。
(2)功能簡介
⑧ 異步清零功能:當/CLR=0時,不論有無時鍾脈沖CLK和其他信號輸入,計數器被清零,即QD~QA=0000。
⑨ 同步並行置數功能:當/CLR=1,/LD=0時,在輸入時鍾脈沖CLK上升沿的作用下,並行輸入的數據dcba被置入計數器,即QD~QA=DBCA。
⑩ 計數功能:當/LD=/CLR=ENP=ENT=1,當CLK端輸入計數脈沖時,計數器進行二進制加法計數
⑪ 保持功能:當/LD=/CLR=1時,且ENP和ENT中有“0”時,則計數器保持原來狀態不變。
(3)基本參數
(4)引腳說明
⑫ A~D:並行輸入
⑬ ENP:計數啟用並行輸入
⑭ ENT:計數啟用涓流輸入
⑮ CLK:時鍾輸入
⑯ /LD:為同步置數控制端
⑰ /CLR:異步清零控制端
⑱ QA~QD:並行輸出
⑲ RCO:進位輸出輸出
(5)真值表
/CLR |
/LD |
ENT |
ENP |
工作模式 |
L |
X |
X |
X |
清零 |
H |
L |
X |
X |
置數 |
H |
H |
H |
H |
計數 |
H |
H |
L |
X |
保持(不變) |
H |
H |
X |
L |
保持(不變) |
1.4 AT28C64B高性能EEPROM
(1)概述
AT28C64B是一個高性能的電可擦除和可編程只讀只讀存儲器( EEPROM)中。它的內存64K是由8位,8,192字。與Atmel先進的非易失性CMOS技術,該器件還提供制造訪問時間為150 ns的只有220毫瓦的功耗。當該裝置是取消選擇,在CMOS待機電流小於100微安。
(2)特點及參數
l 快速讀取訪問時間:150納秒
l 自動頁寫操作
- 內部地址和數據鎖存為64字節
l 快速寫周期時間
- 頁寫周期時間: 10 ms最大(標准),2 ms最大(選項)
- 1到64字節頁寫操作
l 低功耗
- 40毫安工作電流
- 100 μA CMOS待機電流
l 硬件和軟件數據保護
l 數據輪詢和切換位寫檢測結束
l 高可靠性的CMOS技術
- 耐力: 100,000次
- 數據保存:10年單5V±10%供應
l CMOS和TTL兼容輸入和輸出
l JEDEC批准字節寬引腳
l 工業溫度范圍
l 綠色(無鉛/無鹵化物)的包裝選項
(3)引腳結構
AO- A12:地址
CE:芯片使能
OE:輸出使能
WE:寫使能
I/00- I/07:數據輸入輸出
NC:無連接
DC:不連接
1.5 Max7219多位LED顯示驅動器
(1)概述
MAX7219 是美國MAXIM 公司推出的多位LED 顯示驅動器,采用3 線串行接口傳送數據,可直接與單片機接口連接,用戶能方便修改其內部參數,以實現多位LED 顯示。它內含硬件動態掃描電路、BCD譯碼器、段驅動器和位驅動器。此外,其內部還含有8X8 位靜態RAM,用於存放8 個數字的顯示數據。顯然,它可直接驅動64 段LED點陣顯示器。當多片MAX7219 級聯時,可控制更多的LED 點陣顯示器。顯示的數據通過單片機數據處理后,送給MAX7219 顯示。
(2)功能簡介
一片MAX7219可驅動8個7段(包括小數點共8段)數字LED、LED條線圖形顯示器、或64個分立的LED發光二級管。該芯片具有10MHz傳輸率的三線串行接口可與任何微處理器相連,只需一個外接電阻即可設置所有LED的段電流。它的操作很簡單,MCU只需通過模擬SPI三線接口就可以將相關的指令寫入MAX7219的內部指令和數據寄存器,同時它還允許用戶選擇多種譯碼方式和譯碼位。此外它還支持多片7219串聯方式,這樣MCU就可以通過3根線(即串行數據線、串行時鍾線和芯片選通線)控制更多的數碼管顯示。
(3)關鍵特性
l 10MHz串行接口
l 獨立的LED段控制
l 譯碼/非譯碼位選擇
l 150µA低功耗關斷(數據保持)
l 數字和模擬亮度控制
l 上電時處於全滅狀態
l 驅動共陰極LED顯示器
l 段驅動器的擺率限制功能有助於降低EMI (MAX7221)
l SPI、QSPI、MICROWIRE串行接口(MAX7221)
l 24引腳DIP和SO封裝
(4)外部引腳分配和功能及內部結構
① 外部引腳分配
DIN:串行數據輸入端
DOUT:串行數據輸出端,用於級連擴展
LOAD/CS:數據裝載信號輸入
CLK:移位時鍾脈沖輸入
DIG0~DIG7:8位LED位選線,從共陰極LED中吸入電流
SEGA~SEGG:7段驅動
SEG DP:小數點驅動
ISET:硬件亮度調節端
V+:正電源
GND:接地
② 內部結構
(5)串行數據格式
16位地址/數據移位寄存器接收串行數據,實現串/並變換。16位數據含義如下:
D7~D0:寫入內部RAM和功能寄存器的數據。
D8~D11:內部RAM和功能寄存器地址。
D12~D15:無定義。
地址譯碼器是一個4~16線譯碼器,用於選擇數據存放單元,在LOAD端口信號作用下,將接收數據送入指定單元;
8字節雙端口靜態存儲器存放接收數據和提供動態顯示數據;
B譯碼和不譯碼電路對RAM數據進行BCD譯碼或直接送顯示;
段碼電流參考電路、亮度脈沖產生調制器實現對顯示器的亮度控制,段碼電流參考電路由硬件調節顯示器亮度;動態掃描控制器實現由硬件控制動態掃描顯示。
LED段/位驅動器提供顯示器的1段和1位點亮時的電流。
(6)可尋址的數據寄存器和控制寄存器
① 內部RAM地址01 ~ 08H分別對應於DIGO一DIG7。
② 譯碼方式寄存器(地址09H):該寄存器的8位二進制數的各位分別控制8個LED顯示器的譯碼方式。當高電平時,選擇BCD-B譯碼模式,當低電平時選擇不譯碼模式(即送來數據為字型碼)。
③ 掃描界限寄存器(地址0BH):該寄存器中DO ~ D3位數據設定值為0 ~ 7H,設定值表示顯示器動態掃描個數位1 ~ 8。
④ 亮度控制寄存器(0AH):共有16級可選擇,用於設置LED的顯示亮度,從0xX0~0xXF
⑤ 停機寄存器(地址0CH):當D0=0時,MAX721 處於停機狀態;當D0=1時,MAX7219處於正常工作狀態。
⑥ 顯示測試寄存器(地址0FH):當D0=0時,MAX7219 按設定模式正常工作;D0=1時,MAX7219處於測試狀態。在該狀態下,不管MAX7219處於什么模式,全部LED將按最大亮度顯示。
(7)讀寫時序
MAX7129是SPI總線驅動方式。它不僅要向寄存器寫入控制字,還需要讀取相應寄存器的數據。
MAX7129的控制字格式如下:
D15 |
D14 |
D13 |
D12 |
D11 |
D10 |
D9 |
D8 |
D7 (MSB) |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 (LSB) |
X |
X |
X |
X |
地址Address |
數據Data |
如圖,工作時,MAX7219規定一次接收16位數據,在接收的16位數據中:D15~D12可以與操作無關,可以任意寫入,D11~D8決定所選通的內部寄存器地址,D7~D0為待顯示數據或是初始化控制字。在CLK脈沖作用下,DIN的數據以串行方式依次移入內部16位寄存器,然后在一個LOAD上升沿作用下,鎖存到內部的寄存器中。注意在接收時,先接收最高位D16,最后是D0,因此,在程序發送時必須先送高位數據,在循環移位。工作時序圖見下圖:
由於51是8位單片機故需要分兩次來送數據。
二、8*8點陣顯示愛心原理
2.1LED點陣掃描顯示方式
LED一般采用掃描式顯示,主要分為三種方式:點掃描、行掃描、列掃描。
充分利用人眼的暫留效應,實現動畫效果,同時掃描時應注意亮燈留存時間,即掃描的間隔,一般控制於0.05至0.2秒水平。
詳細實現如下:
(1)點掃描
逐點進行信號輸入,效率低,不常用。
(2)行掃描
行掃描即是先讓第一行全部置於有效位,再送對應亮燈位置所需的列碼。隨后按按一定掃描間隔,用同樣的方法依次顯示所有行,8行顯示完成即完成一次完整的行掃描。
(3)列掃描
列掃描即是先讓第一列全部置於有效位,再送對應亮燈位置所需的列碼。隨后按按一定掃描間隔,用同樣的方法依次顯示所有列,8列顯示完成即完成一次完整的列掃描。
2.2使用MAX7219驅動LED點陣接線方式電路原理圖
行掃描模式
2.3使用74LS138、74LS161、AT28C64驅動LED點陣接線方式電路原理圖
ROM從IO0-IO7輸出8位二進制碼,到8*8點陣的NEGDP、NEG A-NEG G,驅動點陣陽極。3-8譯碼器輸出,進行逐行給二極管陰極0電平的行掃描模式。
三、8*8點陣顯示愛心項目實施
3.1使用MAX7219驅動LED點陣
(1)接線方式
(2)程序實現流程圖
(3)項目代碼
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
//定義MAX7219端口
sbit Max7219_pinCLK = P2^2;
sbit Max7219_pinCS = P2^1;
sbit Max7219_pinDIN = P2^0;
uchar code disp1[8]={0x66,0x99,0x81,0x81,0x42,0x24,0x18,0x00};//愛心
//設定延遲時間,單位毫秒
void Delay_xms(uint x)
{
uint i,j;
for(i=0;i<x;i++) //兩層空循環
for(j=0;j<112;j++)
;
}
//向Max7219(U3)寫入字節
void Write_Max7219_byte(uchar DATA)
{
uchar i;
Max7219_pinCS = 0; //LOAD/CS引腳低電平,數據寫入使能
for(i=8;i>=1;i--)
{
Max7219_pinCLK = 0; //移位時鍾低電平輸入
Max7219_pinDIN = DATA&0X80; //數據輸入與80相與,取最高位
DATA = DATA<<1;
Max7219_pinCLK = 1; //移位時鍾脈沖高電平輸入,將數據寫入內部存儲器
}
}
//向Max7219寫入數據
void Write_Max7219(uchar address,uchar dat)
{
Max7219_pinCS = 0; //LOAD/CS引腳低電平,數據寫入使能
Write_Max7219_byte(address);//寫入地址
Write_Max7219_byte(dat); //寫入數據
Max7219_pinCS = 1; //LOAD/CS引腳高電平,數據裝載使能
}
//初始化Max7219
void Init_Max7219(void)
{
Write_Max7219(0x09,0x00); //初始化譯碼寄存器,低電平選擇不譯碼模式
Write_Max7219(0x0a,0x03); //初始化亮度控制寄存器,選擇03檔亮度(0-16檔可選)
Write_Max7219(0x0b,0x07); //初始化掃描界限寄存器,輸入07表示動態掃描個數為8
Write_Max7219(0x0c,0x01); //初始化停機寄存器,輸入01,MAX7219處於正常工作狀態
Write_Max7219(0x0f,0x00); //初始化顯示測試寄存器,輸入0,按設定模式正常工作
}
//主函數
void main(void)
{
uchar i;
Delay_xms(50); //延遲50ms
Init_Max7219(); //初始化Max7219
for(i=1;i<9;i++) //循環掃描顯示
Write_Max7219(i,disp1[i-1]); //在i行輸入存儲愛心點陣對應行的數據
(4)實驗結果
3.2使用74LS138、74LS161、AT27C64等驅動點陣的基礎電路Proteus仿真結果
3.3使用74LS138、74LS161、AT28C64驅動LED點陣
(1)接線方式
(2)程序實現流程圖
(3)項目代碼
① 在ROM模擬部分進行圖形的二進制數組定義
...
code byte memory[8] = { 0x66,0x99,0x81,0x81,0x42,0x24,0x18,0x00 };
② 定義寫字節函數,並調用模擬ROM函數實現像物理載體MAX7219寫數據
//向Max7219寫入字節
void Write_Max7219_byte(byte DATA)
{
byte i;
Max7219_CS = 0;
for(i=8;i>=1;i--)
{
Max7219_CLK = 0;
Max7219_DIN = DATA&0X80;
DATA = DATA<<1;
Max7219_CLK = 1;
}
}
//向Max7219寫入數據 地址限制在了8位 讀者可自行調整
void Write_Max7219(byte address, byte dat)
{
Max7219_CS = 0;
Write_Max7219_byte(address);
Write_Max7219_byte(dat);
Max7219_CS = 1;
}
void Init_Max7219(void) //初始化Max7219芯片
{
Write_Max7219(0x09,0x00);
Write_Max7219(0x0a,0x03);
Write_Max7219(0x0b,0x07);
Write_Max7219(0x0c,0x01);
Write_Max7219(0x0f,0x00);
}
③ 主函數實現輸出圖形
void main(void)
{
byte i;
Delay(50);
Init_Max7219();
for(i=1;i<9;i++) //這里的示例語句將向點陣輸出一次顯示 如果想要一直顯示則應該將其放入真循環
{
Write_Max7219(i,GetRomData(i - 1));
}
}
(4)實驗結果
四.用單片機模擬ROM的方法
4.1簡介
ROM芯片,是數字電路的重要組成成分之一。想要在電路中讀取儲存好的數據,就必須要用到相應的ROM芯片。ROM芯片的規格和型號極其繁多,再加上有些ROM芯片難以獲取,甚至於某些芯片早已停產,無論是測試還是使用時都很不方便。因此可以采取使用單片機代替ROM芯片的辦法,一是因為常見的單片機,例如C51,C52等系列產量很大,容易獲取;二是僅需要修改程序就可適用於各種場景;三是可以在無儲存器芯片的情況下進行預先的電路測試,方便調試等。下面將會以C52系列的STC89C52單片機模擬AT28C64EEROM芯片為例,講述如何使用單片機進行ROM芯片的模擬和替代。
4.2模擬ROM方法
(1) 原理簡介
單片機模擬ROM芯片的原理是,使得ROM芯片的引腳輸入與單片機對應的引腳一致時,儲存的數據一致,輸出的數據相一致。但單片機的內部的RAM通常僅用於存儲程序運行時的數據,通常規格較小。因此用於模擬ROM芯片所用到的單片機的儲存空間,其實是單片機的ROM部分。本質上來講,這里使用單片機來模擬的是一塊連續的儲存空間,而不是ROM芯片的各種物理特性,例如擦除方式等,單片機的ROM部分在生產時實際上使用的是Flash器件。
注意ROM芯片的控制位對輸出數據的影響。注意ROM芯片OE等控制位發生作用的電平高低,以及這些控制位之間決定芯片當前狀態的優先級。這一點需要在程序中寫入相應的控制流。另外當ROM芯片的引腳處於高阻態時,應當不能向引腳內輸入數據。
關於ROM芯片所附帶的其他各種功能,例如保證數據安全性的檢測,防止數據信號波動等功能,不在本題目的討論范圍內,因此不加贅述。
(2) 模擬方法
在這里我們使用C52系列的單片機,具體型號為STC89C52,模擬AT28C64 EEROM芯片儲存數據。利用程序(見后文)使得單片機的功能與ROM芯片相一致。將所需的程序和數據寫入單片機內。當單片機工作時,按照映射的引腳,讀取CE,OE等控制位的信號,當處於相應的狀態時,單片機將讀取地址引腳上的數據,然后將將其在程序預留的空間中對應地址的數據讀出,將其輸出到I/O引腳上。這里的程序將AT28C64芯片的地址接口和控制位映射到了STC89C52單片機的P0,P2端口上;將AT28C64芯片的輸入輸出接口映射到了單片機的P1端口上。程序啟動之后,單片機將會持續地讀入控制位的信號。
當單片機的P2:5引腳,即模擬的CE引腳接入高電平時,P1端口,即模擬的I/O端口將處於高阻態,無法輸入輸出數據;當P2:6即模擬OE處於低電平,或者P2:7模擬WE處於高電平時,單片機將會向P1即模擬的I/O端口輸出數據,輸出的數據來自於模擬地址引腳上信號決定的儲存位置。至此,完成了對ROM芯片數據存儲功能的模擬。
實際操作中有一些地方需要注意。首先,未接入的端口是無法確定其電平的高低的,所以不用的端口應該統一接到低電平處,否則可能產生錯誤。例如,在不使用高地址位時,如果不將其接到低電平處,會使得程序讀取到錯誤的地址,從而輸出錯誤的數據。
其次,單片機模擬的ROM,是處於不斷刷新的狀態之中的。每次循環程序所用的時間決定了刷新的頻率,這一頻率與讀取ROM的單片機不盡相同,從而使得信號不同步,某些時候需要進行延時的調整。所以對ROM的這一模擬並不能精確地反映ROM工作的狀態。一般情況下單片機調用自身的ROM即可。
五.AT28C64芯片
5.1基本原理
AT28C64是一種高性能的,可電擦除的編程只讀儲存器,即EEROM芯片。它總儲存空間為64Kbit,按照8K字,每個字8bit的方式進行組織。該芯片可提供150ns內的高速存取,工作功率低至220mW。當片選信號為高電位,芯片待機時的電流小於100uA。
該芯片有13根地址線,數據寬度為8bit,讀取方式類似於靜態隨機存取儲存器,即SROM,不需要任何外加的元器件,在寫入前自動擦除。當CE和OE為低電平,WE為高電平時,由地址引腳上數據決定的儲存單元中的數據被讀出。無論CE或OE哪一個控制位為高電平時,輸出引腳上都呈現為高阻狀態。這種雙信號控制機制給設計者防止總線沖突帶來靈活性。
CE信號為芯片選擇信號,實際上也作為電源控制信號。當其為高電平時,儲存器芯片進入低功耗待機狀態,這時儲存器芯片呈現出高阻狀態,並與OE信號無關。
為了確保數據的完整性與安全性,特別是在上電和掉電過程中,AT28C64采用了以下方法實現數據保護:
利用內部檢測電路對電源電壓Vcc進行檢測。當芯片檢測到的電壓低於規定的閾值時,芯片將禁止內部非易失性程序初始化。芯片內部有一個信號濾波電路,可以防止信號波動。
在上電和掉電期間都可以通過保持WE或者CE為高電平,或者OE為低電平來封鎖字節寫入周期。
此外,AT28C64EEROM芯片還有識別查詢數據位完成寫入周期的功能,芯片識別功能,全片擦除功能等,但這些功能與本文的目標關系不大,因此不贅述。
5.2 AT28C64引腳圖
5.3引腳功能說明
引腳 |
功能 |
A0-A12 |
地址線 |
CE |
片選信號,低電平有效 |
OE |
輸出信號,低電平有效 |
WE |
寫入信號,低電平有效 |
I/O0- I/O7 |
輸入輸出線 |
VCC |
接電源 |
GND |
接地 |
NC |
無連接 |
六.程序代碼
6.1 ROM模擬部分
#include<stdio.h>
#include<reg52.h>
#define byte unsigned char
#define uint unsigned int
sbit A0=P0^0; //定義地址線
sbit A1=P0^1;
sbit A2=P0^2;
sbit A3=P0^3;
sbit A4=P0^4;
sbit A5=P0^5;
sbit A6=P0^6;
sbit A7=P0^7;
sbit A8=P2^0;
sbit A9=P2^1;
sbit A10=P2^2;
sbit A11=P2^3;
sbit A12=P2^4;
sbit _CE = P2^5; //定義片選信號
sbit _OE = P2^6; //定義輸出信號
sbit _WE = P2^7; //定義寫入信號
sbit D0=P1^0; //定義數據線
sbit D1=P1^1;
sbit D2=P1^2;
sbit D3=P1^3;
sbit D4=P1^4;
sbit D5=P1^5;
sbit D6=P1^6;
sbit D7=P1^7;
code byte memory[8] = { 0x66,0x99,0x81,0x81,0x42,0x24,0x18,0x00 }; //在程序中定義ROM需要寫入的內容 //注意寫入內容的長度,讀取時注意讀取數組的界限以防越界
//這里的示例用8個字節長度的內容
uint GetAddress() //從地址線上讀取地址
{
uint A = P0; //這里的示例因為內容的長度較短,只使用低8位的地址
/*
uint A = P0;
uint t = P2;
t <<= 3; //高位地址只取5位
t >>= 3;
A += t;*/ //讀者可以自行根據需要用到的地址線長度,重寫程序和用到的引腳來改變讀取的地址長度
return A;
}
void Refresh()
{
uint A = GetAddress();
if(_CE) //片選信號為高電平時不輸出內容
{
return;
}
if(!_OE || _WE) //OE信號為高電平時,向數據端口輸出數據
{
P1 = memory[A];
}
}
void main()
{
while(1) //單片機不斷刷新以更新數據狀態
{
Refresh();
}
}
6.2時序與邏輯
時序圖以地址0-5的數據為例:
由於單片機模擬ROM的刷新頻率遠高於電路中地址段的時鍾信號頻率,因此可以認為數據的輸出變化是即時的。
當地址端口數據發生變化時,只有當CE和OE信號同時處於低電平時,模擬ROM才會接受地址端口上的數據。
隨即模擬ROM將會讀取地址線上的數據,將其作為地址,單片機程序將會讀取代碼中寫入儲存空間相應地址的數據然后將其輸出到數據端口。
七.74HC595芯片介紹
7.1基本原理
74HC595是一個8位串行輸入、並行輸出的位移緩存器:並行輸出為三態輸出。在SCK 的上升沿,串行數據由SDL輸入到內部的8位位移緩存器,並由Q7'輸出,而並行輸出則是在LCK的上升沿將在8位位移緩存器的數據存入到8位並行輸出緩存器。當串行數據輸入端OE的控制信號為低使能時,並行輸出端的輸出值等於並行輸出緩存器所存儲的值。
7.2 74HC595芯片引腳圖
如圖7.1所示為74HC595芯片的引腳圖。
7.3 74HC595引腳功能說明
符號 |
引腳 |
描述 |
Q0-Q7 |
第15腳,第1-7腳 |
8位並行數據輸出 |
GND |
第8腳 |
地 |
Q7’ |
第9腳 |
串行數據輸出 |
/MR |
第10腳 |
主復位(低電平有效) |
SH_CP |
第11腳 |
數據輸入時鍾線 |
ST_CP |
第12腳 |
輸出存儲器鎖存時鍾線 |
/OE |
第13腳 |
輸出有效(低電平有效) |
DS |
第14腳 |
串行數據輸入 |
VCC |
第16腳 |
電源 |
7.4 74HC595芯片時序圖
如圖7.2所示為74HC595芯片時序圖。
7.5 74HC595芯片內部電路圖
如圖7.3所示為74HC595芯片內部電路圖。
7.6 74HC595芯片真值表
輸入管腳 |
輸出管腳 |
||||
SER |
SRCLK |
/SRCLR |
RCLK |
/OE |
|
X |
X |
X |
X |
H |
QA-QH輸出高阻 |
X |
X |
X |
X |
L |
QA-QH輸出有效值 |
X |
X |
L |
X |
X |
移位寄存器清零 |
L |
上升沿 |
H |
X |
X |
移位寄存器存儲L |
H |
上升沿 |
H |
X |
X |
移位寄存器存儲H |
X |
上升沿 |
H |
X |
X |
移位寄存器狀態保持 |
X |
X |
X |
上升沿 |
X |
移位寄存器鎖存狀態值 |
X |
X |
X |
下降沿 |
X |
移位寄存器狀態保持 |
7.7芯片的使用方法
74HC595的數據端:
Q0--Q7: 八位並行輸出端,可以直接控制數碼管的8個段。
Q7': 級聯輸出端。將它接下一個595的DS端。
DS: 串行數據輸入端,級聯的話接上一級的Q7'。
74HC595的控制端說明:
/MR(10腳): 低電平時將移位寄存器的數據清零。通常接到VCC防止數據清零。
SH_CP(11腳):上升沿時數據寄存器的數據移位。Q0->Q1->Q2-->Q3-->...-->Q7;下降沿移位寄存器數據不變。
ST_CP(12腳):上升沿時移位寄存器的數據進入數據存儲寄存器,下降沿時存儲寄存器數據不變。通常我將ST_CP置為低電平,當移位結束后,在ST_CP端產生一個正脈沖,更新顯示數據。
/OE(13腳): 高電平時禁止輸出(高阻態)。如果單片機的引腳不緊張,用一個引腳控制它,可以方便地產生閃爍和熄滅效果。比通過數據端移位控制要省時省力。
具體工作方式 :
第一步:目的:將要准備輸入的位數據移入74HC595數據輸入端上。
方法:送位數據到74HC595。
第二步:目的:將位數據逐位移入74HC595,即數據串入。
方法:SH_CP產生一上升沿,將DS上的數據移入74HC595移位寄存器中,先送低位,后送高位。
第三步:目的:並行輸出數據。即數據並出
方法:ST_CP產生一上升沿,將由DS上已移入數據寄存器中的數據送入到輸出鎖存器。
7.8 74HC595芯片工作參數
符號 |
參數 |
最小值 |
最大值 |
單位 |
VCC |
直流電源電壓 |
2.0 |
5.5 |
V |
VIN |
直流輸入電壓 |
0 |
5.5 |
V |
VOUT |
DC輸出電壓 |
0 |
VCC |
V |
TA |
工作溫度 |
-55 |
125 |
℃ |
更多參數請查閱 https://www.21icsearch.com/ 以獲得詳細信息。
八.總體設計
九.接口電路設計
如圖2.1為16×16點陣漢字顯示的接口電路設計。單片機通過P2口與4片74HC595芯片相連,通過串行數據輸出的方式將要顯示的漢字數據存儲到74HC595芯片中。然后通過上升沿信號控制74HC595芯片並行輸出數據到點陣,即可完成點陣的漢字顯示。
十.提取漢字編碼的方法
10.1 簡介
字符或者漢字顯示在點陣屏幕上,就必須有相應的字庫,字體和大小不同,其對應的字庫也不相同。字庫的編碼有多種方式;在點陣上顯示的編碼就有多種,每一種編碼必須和點陣顯示相對應。下面就以字符“E”的16´16字庫的編碼為例介紹字符(漢字)編碼過程。為了敘述方便,我們將要顯示的字符(漢字)描在方格坐標上。如下圖我們將顯示字符“E”在16´16方格紙上描出的圖形。其中,畫“○”處表示該點“亮”,未畫“○”處表示“不亮”。如圖3.1所示,然后根據“亮”與“不亮”的狀態,將畫“○”定義為“1”,未畫“○”定義為“0”。這樣就形成了一個字符“E”的字庫,根據點陣的數據線的排列方式,字庫編碼有多種方式,有按照行線方向(水平)編碼,也有按照列線方向(垂直)編碼;每一種方式中,都是以字節為單位編碼,不過字節的高位各不相同。
下面我們按照行線方向(水平),且將字節的高位設定在左邊的方式編碼。例如,圖10.1所示的“E”字,第3行的二進制碼組為0000111111110000,用十六進制表示則為0FH和F0H;第4行的二進制碼組為0000100000000000,用十六進制表示則為08H和00H。可見,對16´16點陣字符進行編碼時,每一行可用兩個字節的編碼表示,則16行共有32個字節。最后將1~16行的十六進制代碼順序地寫入點陣對應位置的存儲單元中。點陣就會在指定的位置顯示字符“E”。
如果按照列線方向(垂直),且將字節的高位設定在下邊的方式編碼。16´16點陣中每一列的16個點可用兩個字節的編碼表示,則16列共有32個字節。如圖3.1所示的“E”字,第4列的二進制碼組為0001111111111100,用兩個字節的十六進制表示則為1FH和FCH。下面所使用的點陣采用的就是這種編碼方式。
10.2 提取漢字編碼的方法
點陣的顯示數據存儲器與顯示屏幕的物理位置是一一對應的。當對DDRAM中的某一個單元寫入一個字符的編碼時,該字符就在對應的位置顯示出來。所以要顯示字符就必須把字符的編碼寫入DDRAM中,也就是寫入對應的字符存儲器中。
顯示漢字時首先根據漢字字形編出字模數據塊,一個漢字如用16×16點陣,則需32個字節數據,漢字字模除手工編寫外,也可以使用一些字模提取工具軟件創建(如HZDotReader軟件等)。一般用軟件來提取漢字的點陣。
在提取漢字前,必須確認三件事情:
(1)送入液晶顯示漢字點陣緩存區的數據的方向。是上下還是左右。如果是上下方向,上面是低位還是高位。如果是左右方向,左面是低位還是高位。
(2)漢字點陣大小的選擇。是16×16(小四號),還是32×32,等等。
(3)漢字點陣的輸出格式。是C語言方式還是匯編語言方式。
下面以取模軟件提取漢字點陣為例,介紹“華中科技大學”六個漢字點陣的提取方法。假設選擇16×16點陣,C語言輸出方式。
打開軟件,出現如圖10.2所示的界面。在此界面可以直接輸入取模的漢字,設置字體大小,選擇字體以及特殊字體的操作(如粗體,斜體,添加下划線等)。同時可以通過下拉菜單改變字型,編碼方式以及方向。最后還有點陣顏色選擇,方便預覽輸出效果。
可以在操作欄中選擇字體,以及對應的長寬比。
取模方式:
①在字體下拉菜單處點擊下箭頭,選擇字體為“宋體”。
②在字型選擇下拉菜單處點擊下箭頭,選擇字型為“16×16”
③在編碼選擇下拉菜單處點擊下箭頭,選擇編碼為“D0~D7”
④在方向選中下拉菜單處點擊下箭頭,選擇方向為“橫向”
⑤設置完成后在輸入框內逐字輸入“華中科技大學”並點擊“執行”。此時需要的字模數據就出現在下面的工作框中。如圖10.3所示。
十一.代碼實現
11.1流程圖
11.2代碼
//點陣顯示數組
unsigned char code tab0[] = {0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80,0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x00};
unsigned char code tab8[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//空格
unsigned char code tab1[] =
{16,1,16,17,8,9,12,7,138,1,104,33,8,33,8,62,136,0,128,0,254,63,128,0,128,0,128,0,0,0,0,0};//華
unsigned char code tab2[] =
{128,0,128,0,252,31,132,16,132,16,132,16,132,16,132,16,252,31,132,16,128,0,128,0,128,0,128,0,0,0,0,0};//中
unsigned char code tab3[] =
{0,8,96,9,28,10,16,10,144,8,126,9,16,9,24,56,184,15,84,8,18,8,16,8,16,8,16,8,0,0,0,0};//科
unsigned char code tab4[] =
{8,2,8,2,8,2,222,31,8,2,8,2,200,15,152,8,142,8,8,5,8,2,8,5,136,8,110,48,0,0,0,0};//技
unsigned char code tab5[] =
{128,0,128,0,128,0,128,0,254,63,128,0,64,1,64,1,64,1,32,2,32,2,16,4,8,8,6,48,0,0,0,0};//大
unsigned char code tab6[] =
{72,8,144,4,0,2,254,63,2,32,2,32,248,7,0,2,128,1,254,63,128,0,128,0,128,0,224,0,0,0,0,0};//學
unsigned char code tab7[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//空格
#include <REG51.H>
#include <intrins.h>
#include "array.h"
//--重新定義函數變量--//
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
//--定義SOU要使用的IO--//
sbit MOSIO = P3^4;
sbit R_CLK = P3^5;
sbit S_CLK = P3^6;
//--全局函數聲明--//
void HC595SendData( uchar BT3, uchar BT2,uchar BT1,uchar BT0);
/*******************************************************************************
*函數名 : main
*函數功能 :主函數
*輸入 :無
*輸出 :無
*******************************************************************************/
void main(void)
{
int k, j, ms;
//--定義一個執政數組指向每個漢字--//
uchar *p[] =
{tab8, tab1, tab2, tab3, tab4, tab5, tab6, tab7};
while(1)
{
for(ms = 20; ms > 0; ms--) //移動定格時間設置
{
for(k = 0; k < 16; k++) //顯示一個字
{
HC595SendData(~(*(p[0] + 2*(k+j) + 1)),~(*(p[0] +
2*(k+j) )),tab0[2*k],tab0[2*k + 1]); //因為字模軟件取的數組是高電平有效,所以列取反
}
//清屏//
HC595SendData(0xff,0xff,0,0);//清屏
}
j++;
if(j == (7*15) )//7表示輸出字的個數
{
j = 0;
}
}
}
/*******************************************************************************
*函數名 : HC595SendData
*函數功能 :通過74HC595發送四個字節的數據
*輸入 :BT3:第四個74HC595輸出數值
* :BT2:第三個74HC595輸出數值
* :BT1:第二個74HC595輸出數值
* :BT0:第一個74HC595輸出數值
*輸出 :無
*******************************************************************************/
void HC595SendData( uchar BT3, uchar BT2,uchar BT1,uchar BT0)
{
uchar i;
//--·發送第四個字節--//
for(i=0;i<8;i++)
{
MOSIO = BT3 >> 7 ; //從高位到低位
BT3 <<= 1;
S_CLK = 0;
S_CLK = 1; //時鍾信號控制發送
}
//--·發送第三個字節--//
for(i=0;i<8;i++)
{
MOSIO = BT2 >>7;//從高位到低位
BT2 <<= 1;
S_CLK = 0;
S_CLK = 1; //時鍾信號控制發送
}
//--·發送第二個字節--//
for(i=0;i<8;i++)
{
MOSIO = BT1 >> 7;//從高位到低位
BT1 <<= 1;
S_CLK = 0;
S_CLK = 1; //時鍾信號控制發送
}
//--·發送第一個字節--//
for(i=0;i<8;i++)
{
MOSIO = BT0 >> 7;//從高位到低位
BT0 <<= 1;
S_CLK = 0;
S_CLK = 1; //時鍾信號控制發送
}
//--輸出--//
R_CLK = 0; //set dataline low
R_CLK = 1; //片選
}
將以上源程序復制到MCS-51的C語言程序中,用Keil編譯並下載到如圖2.1所示MCS-51單片機系統中即可運行。點陣的中部位置會顯示“華中科技大學”字樣