《單片機系統(tǒng)設(shè)計仿真與應(yīng)用》課件第3章_第1頁
《單片機系統(tǒng)設(shè)計仿真與應(yīng)用》課件第3章_第2頁
《單片機系統(tǒng)設(shè)計仿真與應(yīng)用》課件第3章_第3頁
《單片機系統(tǒng)設(shè)計仿真與應(yīng)用》課件第3章_第4頁
《單片機系統(tǒng)設(shè)計仿真與應(yīng)用》課件第3章_第5頁
已閱讀5頁,還剩147頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

3.1原理圖設(shè)計與說明3.2流水燈程序設(shè)計

3.3數(shù)碼管顯示程序設(shè)計

3.4矩陣鍵盤程序設(shè)計

3.5流水燈、數(shù)碼管和鍵盤的綜合應(yīng)用

3.6LCD液晶顯示

3.7LED矩陣顯示屏的應(yīng)用

3.8MCS-51單片機I/O端口的擴展小結(jié)

習(xí)題 96

3.1.1原理圖設(shè)計

本章使用的電路原理圖如圖3-1所示。3.1原理圖設(shè)計與說明圖3-1輸入/輸出應(yīng)用電路原理圖

(1)?8只LED燈連接于P3口,可實現(xiàn)任何LED流水燈的顯示。

(2)?8只數(shù)碼管均為共陰極數(shù)碼管,段控線連接于P0口,位控線由P2口通過74LS138來控制,一次只能顯示一只數(shù)碼管。

(3)4×4矩陣鍵盤接于P1口,這樣做可以節(jié)省I/O端口資源,同時增加可用鍵數(shù)量。

(4)液晶顯示的3個控制端分別接于P2.5、P2.6和P2.7引腳,數(shù)據(jù)端接于P0口。

(5)喇叭用于發(fā)出聲響,接于P2.4引腳,繼電器用于控制220?V的日光燈泡發(fā)光,接于P2.5引腳。

(6)圖中省略了時鐘電路和復(fù)位電路,這在第2章已經(jīng)作過說明,后面各章原理圖也將省略時鐘電路和復(fù)位電路,將不再說明。

(7)使用器件列表如圖3-2所示,在Proteus中輸入器件名稱即可找到該器件。圖3-2元器件列表清單3.1.274LS138功能介紹

74LS138為3-8譯碼器,它由3個輸入變量(A0~A2)控制8個輸出端(Y0~Y7),其引腳圖如圖3-3所示。圖3-374LS138引腳圖表3-13-8譯碼器74LS138的功能真值表3.2.1設(shè)計要求

共8只LED燈,連成一排,要求實現(xiàn)幾種燈的組合顯示。3.2.2流水燈設(shè)計說明

本節(jié)僅設(shè)計模式1,其他模式由讀者自行設(shè)計,模式的選擇由鍵盤控制。由于本設(shè)計比較簡單,可直接畫出流程圖,如圖3-4所示。3.2流水燈程序設(shè)計圖3-4流水燈程序流程圖3.2.3流水燈設(shè)計源碼

根據(jù)軟件流程圖,可以很容易地寫出代碼,如例3-1所示。

【例3-1】

流水燈項目代碼。

/************流水燈項目代碼************************/

voidlight(void)

{

ucharcnt,tmp=0xfe;

for(cnt=0;cnt<=7;cnt++)

{ P3=tmp;

tmp=(tmp<<1)|1;

delay(250);delay(250); //延時0.5?s

}

}【例3-2】

延時程序代碼。

/*************延時x毫秒*****************/

voiddelay(ucharx)//設(shè)晶體振蕩器的頻率為12?MHz

{uchark;

while(x--) //延時大約x毫秒

for(k=0;k<125;k++){}

}3.2.4仿真結(jié)果

使用Keil軟件對C源程序進行編譯生成?.hex文件,然后將?.hex下載到單片機中,并進行仿真,仿真結(jié)果如圖3-5所示。圖3-5流水燈仿真結(jié)果3.3.1設(shè)計要求

共8只數(shù)碼管,連成一排,要求可以任意顯示其中一個或多個數(shù)碼管。具體要求如下:

(1)依次選通8只數(shù)碼管,并讓每只數(shù)碼管顯示相應(yīng)的值。

(2)要求在8只數(shù)碼管中同時顯示1、2、3、4、5、6、7、8,即第1只數(shù)碼管顯示1,第2只數(shù)碼管顯示2,…,依此類推,第8只數(shù)碼管顯示8。3.3數(shù)碼管顯示程序設(shè)計3.3.2數(shù)碼管軟件設(shè)計說明

本節(jié)僅實現(xiàn)設(shè)計要求1,要求2由讀者自行設(shè)計。

(1)數(shù)碼管分共陰極和共陽極兩類。

(2)圖3-7所示的是8位數(shù)碼掃描顯示電路,其中每只數(shù)碼管的8只段h、g、f、e、d、c、b、a(h是小數(shù)點)都分別連在一起,8只數(shù)碼管分別由8個選通信號K1、K2、…,K8來選擇。被選通的數(shù)碼管顯示數(shù)據(jù),其余關(guān)閉。圖3-6共陰極數(shù)碼管及其電路圖3-78位數(shù)碼掃描顯示電路根據(jù)以上原理說明,設(shè)計實現(xiàn)要求1的程序設(shè)計流程圖如圖3-8所示。

3.3.3數(shù)碼管軟件設(shè)計源碼

根據(jù)軟件流程圖,可寫出如下代碼:

【例3-3】

數(shù)碼管項目代碼。

圖3-8數(shù)碼管掃描顯示流程圖voidled_7s(ucharkeyvalue)

{

ucharcnt,tmp=(P2&0xf0)|0x8;

//cnt用于選擇段控數(shù)碼;tmp用于位控,實現(xiàn)8只數(shù)碼管

//循環(huán)顯示

ucharled_table[16]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0x6f,0x77,

0x7c,0x39,0x5e,0x79,0x71};//0~F共16個數(shù),用于段控 for(cnt=0;cnt<16;cnt++)

{

P2=tmp++; //選擇顯示數(shù)碼管

if((tmp&0x0f)==0x0)tmp=(P2&0xf0)|0x8;

P0=led_table[cnt]; //顯示數(shù)據(jù)

delay(250);delay(250);//延時約0.5?s

}

}3.3.4仿真結(jié)果

數(shù)碼管循環(huán)顯示的仿真結(jié)果如圖3-9所示。圖3-9數(shù)碼管循環(huán)顯示的仿真結(jié)果3.4.1設(shè)計要求

矩陣鍵盤,共16個按鍵,要求可識別按鍵并執(zhí)行相應(yīng)的功能,具體要求如下:

(1)對于矩陣鍵盤,要求從左到右從上到下,依次給按鍵編碼為(編碼的結(jié)果后文簡稱為鍵號):0,1,2,3,4,5,…,E,F(xiàn),并在數(shù)碼管中顯示出來。

(2)通過按鍵來控制單片機行使相應(yīng)的功能,不同的按鍵控制單片機實現(xiàn)不同的功能。3.4矩陣鍵盤程序設(shè)計3.4.2矩陣鍵盤軟件設(shè)計說明

1.按鍵開關(guān)的抖動問題

組成鍵盤的按鍵有觸點式和非觸點式兩種,單片機中應(yīng)用的一般是由機械觸點構(gòu)成的,如圖3-10所示。圖中,當(dāng)開關(guān)S未被按下時,P1.0輸入為高電平,S閉合后,P1.0輸入為低電平。由于按鍵是機械觸點,當(dāng)機械觸點斷開、閉合時,會有抖動,P1.0輸入端的波形如圖3-11所示。圖3-10機械觸點按鍵圖3-11抖動

2.矩陣式鍵盤的按鍵識別方法

矩陣式結(jié)構(gòu)的鍵盤,其列線通過電阻接正電源,列線所接的I/O口則作為輸入,并將行線所接的單片機的I/O口作為輸出端。

(1)判斷鍵盤中有無鍵按下。

(2)判斷閉合鍵所在的位置。

下面使用圖3-12來作具體說明。

圖3-13給出了按鍵處理流程圖。

圖3-12矩陣鍵盤原理說明圖3-13按鍵處理流程圖3.4.3矩陣鍵盤軟件設(shè)計源碼

根據(jù)軟件流程圖,寫出鍵盤掃描程序的代碼:

【例3-4】

矩陣鍵盤項目代碼。/*************獲取按鍵值,一次按鍵處理一次*****************/

//鍵盤從左到右從上到下的鍵值依次為:

//0,1,2,3

//4,5,6,7

//8,9,10,11

//12,13,14,15

ucharkeyscan(void)

{ucharscode,rcode,keycode,keycode_v;

P2=P2&0xf7;

//關(guān)閉所有數(shù)碼管,第4個管腳控制138不使能端

P1=0x0f;

//使P1高4位為低電平,低4位為高電平

keycode=0;

//無鍵按下時,鍵值為0,建立無效標(biāo)志

if((P1&0x0f)!=0x0f)

{delay(10); //延時10?ms消抖

P1=0x0f;

if((P1&0x0f)!=0x0f)

{

scode=0xef;

while((scode&0x01)!=0)

//此while語句使P1高4位依次為低電平

{P1=scode;

if((P1&0x0f)!=0x0f)

{

rcode=(P1&0x0f)|0xf0;

keycode=~rcode|~scode; //有鍵按下時,取得鍵值

}

else

scode=_crol_(scode,1); //sccode左移1位}

}

}

//下面swithc語句對鍵值進行編碼

switch(keycode)

{

case0:keycode_v=0xff;break;

case0x11:keycode_v=0;break;

case0x12:keycode_v=1;break;

case0x14:keycode_v=2;break; case0x18:keycode_v=3;break;

case0x21:keycode_v=4;break;

case0x22:keycode_v=5;break;

case0x24:keycode_v=6;break;

case0x28:keycode_v=7;break;

case0x41:keycode_v=8;break;

case0x42:keycode_v=9;break;

case0x44:keycode_v=10;break;

case0x48:keycode_v=11;break;

case0x81:keycode_v=12;break;

case0x82:keycode_v=13;break;

case0x84:keycode_v=14;break;

case0x88:keycode_v=15;break;

}

//下面這兩句作用:等待按鍵釋放

P1=0x0f;//使P1高4位為低電平,低4位為高電平

while((P1&0x0f)!=0x0f);

returnkeycode_v;

}3.4.4仿真結(jié)果

程序在運行過程中,按下任一鍵,則鍵值會在數(shù)碼管中顯示出來。圖3-14為按下第一排第3個鍵時的結(jié)果。圖3-14鍵盤仿真結(jié)果3.5.1功能說明

完成的功能主要有:

(1)首先展示流水燈效果,用數(shù)碼管輪流顯示0,1,2,…,F(xiàn)。

(2)然后進行鍵盤掃描,根據(jù)按鍵決定程序的執(zhí)行。

具體功能流程圖如圖3-15所示。3.5流水燈、數(shù)碼管和鍵盤的綜合應(yīng)用圖3-15流水燈、數(shù)碼管和鍵盤綜合應(yīng)用功能流程圖3.5.2源碼

對前面各子功能塊的代碼進行增減修改,一方面使各功能塊間相互獨立,另一方面增加了相互交互的作用。

代碼寫在main.c和pin_inout.c兩個文件中,如例3-5和例3-6所示?!纠?-5】main.c文件。

#defineucharunsignedchar

#defineuintunsignedint

//以下為函數(shù)聲明

voidlight(void);

voidled_7s(uchar);

ucharkeyscan(void);

voidspeaker(void);

voidrelay(bit);

voiddelay(ucharx);voidmain(void)

{

uchartmp,disp=0xff;

//喇叭不工作

speaker(?);

//流水燈

light(?);

//七段數(shù)碼管

led_7s(0xff);

//繼電器不工作

relay(0);

while(1)

{ if((tmp=keyscan())!=0xff)disp=tmp;

//如果有按鍵按下,則保存該鍵值

if(disp!=0xff)led_7s(disp);

if(disp==0)

{//第1個按鍵控制繼電器工作

relay(1);

}

elseif(disp==1)

//第2個按鍵控制喇叭發(fā)聲,按后發(fā)聲

{

speaker(?);

relay(0);

}

}

}【例3-6】pin_inout.c文件。

#include<reg51.h>

#include<absacc.h>

#include<intrins.h>

#defineucharunsignedchar

#defineuintunsignedintsbitspk=P2^4; //定義喇叭引腳

sbitrly=P2^5; //定義繼電器引腳

//以下為函數(shù)聲明

voidlight(uchar);

voidled_7s(uchar);

ucharkeyscan(void);

voidspeaker(void);

voidrelay(bit);

voiddelay(ucharx);/************喇叭發(fā)聲代碼************************/

voidspeaker(void)

{

ucharcnt;

for(cnt=0;cnt<=100;cnt++)

{

spk=~spk; //產(chǎn)生方波

delay(2);

//改變延時值可產(chǎn)生不同頻率的聲音

}

}/************繼電器工作代碼************************/

//繼電器由鍵盤控制

voidrelay(bitctrl)

{

rly=ctrl;//繼電器工作狀態(tài)由輸入?yún)?shù)決定

}

/************流水燈項目代碼************************/

voidlight(void)

{ ucharcnt,tmp=0xfe;

P2=P2&0xf7;

//關(guān)閉所有數(shù)碼管,第4個管腳控制74LS138不使能端

for(cnt=0;cnt<=7;cnt++)

{

P0=tmp;

tmp=(tmp<<1)|1;

delay(250);delay(250); //延時0.5?s

}

}/************七段數(shù)碼管項目代碼***********************/

//當(dāng)參數(shù)keyvalue為0xff時,依次顯示0,1,…,F一次;

//當(dāng)參數(shù)keyvalue為i時,則僅在第一個數(shù)碼管上顯示i一次(i取值范圍0~15)

voidled_7s(ucharkeyvalue)

{

ucharcnt,tmp=(P2&0xf0)|0x8;

//cnt用于選擇段控數(shù)碼;tmp用于位控,實現(xiàn)8個

數(shù)碼管循環(huán)顯示ucharled_table[16]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0x6f,0x77,0x7c,0x39,0x5e,

0x79,0x71}; //0~F共16個數(shù),用于段控

if(keyvalue==0xff)

{

for(cnt=0;cnt<16;cnt++)

{

P2=tmp++; //選擇顯示數(shù)碼管 if((tmp&0x0f)==0x0)tmp=(P2&0xf0)|0x8;

P0=led_table[cnt]; //顯示數(shù)據(jù)

delay(250);delay(250);

//延時約0.5?s

}

}

else//要不斷刷新,才能保證LED持續(xù)亮

{

P2=tmp;

P0=led_table[keyvalue];

}}

/*************獲取按鍵值,一次按鍵處理一次*****************/

//鍵盤從左到右從上到下的鍵值依次為:

//0,1,2,3

//4,5,6,7

//8,9,10,11

//12,13,14,15

ucharkeyscan(void)

{ucharscode,rcode,keycode,keycode_v;

P2=P2&0xf7;

//關(guān)閉所有數(shù)碼管,第4個引腳控制138不使能端

P1=0x0f;

//使P1高4位為低電平,低4位為高電平

keycode=0;

//無鍵按下時,鍵值為0

if((P1&0x0f)!=0x0f)

{delay(10); //延時10?ms消抖

P1=0x0f;

if((P1&0x0f)!=0x0f)

{

scode=0xef;

while((scode&0x01)!=0)

//此while語句使P1高4位依次為低電平

{

P1=scode;

if((P1&0x0f)!=0x0f)

{rcode=(P1&0x0f)|0xf0;

keycode=~rcode|~scode; //有鍵按下時,取得鍵值

}

else

scode=_crol_(scode,1); //sccode左移1位

}

}

}

//下面swithc語句對鍵值進行編碼

switch(keycode){

case0:keycode_v=0xff;break;

case0x11:keycode_v=0;break;

case0x12:keycode_v=1;break;

case0x14:keycode_v=2;break;

case0x18:keycode_v=3;break;

case0x21:keycode_v=4;break;

case0x22:keycode_v=5;break;case0x24:keycode_v=6;break;

case0x28:keycode_v=7;break;

case0x41:keycode_v=8;break;

case0x42:keycode_v=9;break;

case0x44:keycode_v=10;break;

case0x48:keycode_v=11;break;

case0x81:keycode_v=12;break;

case0x82:keycode_v=13;break;

case0x84:keycode_v=14;break;

case0x88:keycode_v=15;break;

}//下面這兩句作用:等待按鍵釋放

P1=0x0f; //使P1高4位為低電平,低4位為高電平

while((P1&0x0f)!=0x0f);

returnkeycode_v;

}

/*************延時x毫秒*****************/

voiddelay(ucharx)//設(shè)晶體振蕩器的頻率為11.0592?MHz

{uchark;

while(x--)//延時大約x毫秒

for(k=0;k<125;k++){}

}3.6.1LCD1602引腳與功能

LCD1602引腳排列如圖3-16所示。

其引腳功能說明見表3-2所示。

在端口中,RS、R/W、E為液晶模塊的控制信號,其真值表見表3-3。3.6LCD液晶顯示圖3-16LCD1602芯片引腳圖表3-2LCD1602芯片引腳功能表3-3控制信號真值表3.6.2字符顯示原理

HD44780內(nèi)置了DDRAM、CGROM和CGRAM。

DDRAM就是顯示數(shù)據(jù)RAM,用來寄存待顯示的字符代碼。共80個字節(jié),其地址和屏幕顯示位置的對應(yīng)關(guān)系如表3-4所示。表3-4DDRAM地址和屏幕顯示位置的對應(yīng)關(guān)系從表3-5可以看出,“A”字對應(yīng)上面的高位代碼為0100,對應(yīng)左邊的低位代碼為0001,合起來就是01000001,也就是41H。因此,若要在LCD1602屏幕的第一行第一列顯示一個“A”字,就要向DDRAM的00H地址寫41H,在LCD1602內(nèi)部則根據(jù)41H從CGROM中取出字模數(shù)據(jù),驅(qū)動LCD屏幕的第一行第一列的陣點顯示“A”字。表3-5CGROM和CGRAM與字符的對應(yīng)關(guān)系3.6.3LCD1602指令描述

LCD1602有11個控制指令,下面分別闡述每條指令的格式及其功能。

1)清屏指令2)光標(biāo)歸位指令

3)進入模式設(shè)置指令4)顯示開關(guān)控制指令5)設(shè)定顯示屏或光標(biāo)移動方向指令使光標(biāo)移位或使整個顯示屏幕移位,但不改變DDRAM的內(nèi)容。參數(shù)設(shè)定的情況如表3-6所示。表3-6設(shè)定顯示屏或光標(biāo)移動的真值表6)功能設(shè)定指令7)設(shè)定CGRAM地址指令8)設(shè)定DDRAM地址指令9)讀取忙信號或AC地址指令10)數(shù)據(jù)寫入DDRAM或CGRAM指令11)從CGRAM或DDRAM讀出數(shù)據(jù)的指令3.6.4讀寫操作時序

根據(jù)上述指令的介紹可知,LCD1602有4種基本操作,見表3-7。表3-7LCD1602的4種基本操作讀寫操作時序如圖3-17和圖3-18所示。

3.6.5液晶驅(qū)動程序及仿真

根據(jù)以上介紹,我們可以寫出LCD1602的液晶驅(qū)動程序。圖3-17讀操作時序圖3-18寫操作時序【例3-7】

引腳定義和函數(shù)聲明。

#include<reg51.h>

#defineucharunsignedchar

sbitRS=P2^5;

sbitEN=P2^7;

sbitRW=P2^6;

//各函數(shù)調(diào)用的delay函數(shù)聲明

voiddelay(uchar);【例3-8】

忙檢查函數(shù)。

bitBusy_check()

{

bitlcd_status;

P0=0xff;

RS=0; //選擇狀態(tài)寄存器

RW=1; //讀狀態(tài)寄存器

EN=0;

delay(1);

EN=1; //開始讀

delay(1);

lcd_status=(P0&0x80);

EN=0;

returnlcd_status;

}【例3-9】

讀LCD數(shù)據(jù)函數(shù)。

ucharLcd_read_data()

{

ucharlcd_data;

while(Busy_check()); //忙等待

RS=0; //讀數(shù)據(jù)

RW=1;

EN=0; delay(1);

EN=1;

//開始讀

delay(1);

lcd_data=P0;

EN=0;

returnlcd_data;

}【例3-10】

寫LCD命令函數(shù)。

voidLcd_write_cmd(ucharcmd)

{

while(Busy_check());

//忙等待

delay(1);

RS=0; //選擇命令寄存器

RW=0; //寫寄存器 EN=0;

P0=cmd;

delay(1);

EN=1; //開始寫

delay(1);

EN=0;

}【例3-11】

寫LCD數(shù)據(jù)函數(shù)。

voidLcd_write_data(uchardat)

{

while(Busy_check()); //忙等待

delay(1);

RS=1; //選擇數(shù)據(jù)寄存器 RW=0; //寫寄存器

EN=0;

P0=dat;

delay(1);

EN=1; //開始寫

delay(1);

EN=0;

}【例3-12】LCD初始化函數(shù)。

voidLcd_initialize(?)

{

Lcd_write_cmd(0x38);

//2行,5×7字符

delay(1);

Lcd_write_cmd(0x01);

//清顯示,每次調(diào)用則清空顯示屏

}

delay(1);

Lcd_write_cmd(0x06);

//字符輸入模式:地址增量,顯示屏不動,字符后移

delay(1);

Lcd_write_cmd(0x0e);

//顯示開,光標(biāo)不顯示,光標(biāo)不閃爍

delay(1);

【例3-13】LCD顯示字符串函數(shù)。

//輸入addr為地址,范圍為:0x00~0x0f,0x40~0x4f

voidLcd_display(ucharaddr,uchar*str)

{

uchari=0;

//設(shè)置顯示起始位置

Lcd_write_cmd(addr|0x80);

//輸出字符串 delay(1);

for(i=0;str[i]!='\0';i++)

{

Lcd_write_data(str[i]);

delay(1);

}

}【例3-14】

上面幾個函數(shù)用到的延時函數(shù),延時約x毫秒。

voiddelay(ucharx)

//設(shè)晶體振蕩器的頻率為11.0592?MHz

{uchark;

while(x--)

//延時大約x毫秒

for(k=0;k<125;k++){}

}【例3-15】LCD顯示函數(shù)。

voidmain(void)//主函數(shù)

{

Lcd_initialize();

Lcd_display(0,"Welcome!");

Lcd_display(0x44,"---hjk");

while(1);

}圖3-19LCD1602仿真結(jié)果3.7.1設(shè)計要求

按圖3-20連接單片機與LED矩陣。試設(shè)計一個LED矩陣顯示屏的應(yīng)用程序,要求由單片機控制LED矩陣循環(huán)顯示00~99。3.7LED矩陣顯示屏的應(yīng)用圖3-20單片機與LED矩陣的接口原理圖3.7.2設(shè)計說明

下面首先介紹8×8LED點陣的構(gòu)造及顯示原理。

8×8LED點陣顯示器排列起來剛好是正方形,因此構(gòu)造方面并沒有行共陽或行共陰之分,其內(nèi)部由64個LED排列而成,內(nèi)部排列如圖3-21所示,而外觀引腳可參考圖3-22。

程序設(shè)計流程圖如圖3-23所示。圖3-218×8LED點陣內(nèi)部排列圖3-228×8LED點陣引腳圖圖3-23LED矩陣顯示的程序流程圖3.7.3設(shè)計源碼

【例3-16】

矩陣LED顯示源碼。

//*************8x8矩陣LED顯示函數(shù)*****************//

//本例使用的是共陰極接法,列線由Y控制,行線接LED

//可顯示1,2,3,4,5,6,7,8,9,a,b,c,d,e,f。顯示范圍:00~FF

//本例僅顯示十進制數(shù)00~99,可以看做100進制計數(shù)器

//使用74LS138譯碼器來節(jié)省端口資源

voidled8x8(void)

{

uchari,j,index_h,index_l;

ucharcodedisp_tab[]=

{

0x00,0x3e,0x22,0x3e,0x00,0x3e,0x22,0x3e, //0

0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x3e, //1

0x00,0x2e,0x2a,0x3a,0x00,0x2e,0x2a,0x3a, //2

0x00,0x2a,0x2a,0x3e,0x00,0x2a,0x2a,0x3e, //3

0x00,0x38,0x08,0x3e,0x00,0x38,0x08,0x3e, //4

0x00,0x3a,0x2a,0x2e,0x00,0x3a,0x2a,0x2e, //5

0x00,0x3e,0x2a,0x2e,0x00,0x3e,0x2a,0x2e, //6

0x00,0x20,0x20,0x3e,0x00,0x20,0x20,0x3e, //7

0x00,0x3e,0x2a,0x3e,0x00,0x3e,0x2a,0x3e, //8

0x00,0x3a,0x2a,0x3e,0x00,0x3a,0x2a,0x3e, //9

};

while(1)

{

for(index_h=0;index_h<10;index_h++)

//顯示下一個數(shù)字

{

for(index_l=0;index_l<10;index_l++)

//顯示下一個數(shù)字

{

for(j=0;j<20;j++) //每個數(shù)字刷新顯示N次,相當(dāng)于延長一段時間

{

P2=(P2&0x0f)|0x80;

for(i=0;i<4;i++) //每屏一個數(shù)字由8字節(jié)構(gòu)成

{ P1=disp_tab[index_h*8+i]; //行碼

delay(2);

P2=P2+0x10;

//列碼

}

for(i=4;i<8;i++) //每屏一個數(shù)字由8字節(jié)構(gòu)成

{ P1=disp_tab[index_l*8+i]; //行碼

delay(2);

P2=P2+0x10; //列碼

}

}

}

}

}

}3.7.4仿真結(jié)果

將源程序編譯下載后進行仿真,仿真結(jié)果如圖3-24所示,圖中正在顯示的數(shù)字為34。圖3-24LED矩陣仿真結(jié)果3.8.18255A可編程并行接口工作原理

1.內(nèi)部結(jié)構(gòu)簡介

PA端口輸出具有鎖存和緩沖的功能,輸入具有鎖存功能。PA端口結(jié)構(gòu)如圖3-25所示。

8位并行端口PB:通過編程可以分別設(shè)置成單向輸出和單向輸入。PB端口輸出具有鎖存和緩沖的功能,輸入具有緩沖功能。PB端口結(jié)構(gòu)如圖3-26所示。3.8MCS-51單片機I/O端口的擴展圖3-25PA端口的輸出鎖存和緩沖、輸入鎖存結(jié)構(gòu)圖3-26PB端口的輸出鎖存和緩沖、輸入緩沖結(jié)構(gòu)

2.外部電氣引腳配置與功能

8255采用40線雙列直插式封裝(見圖3-27)。40條引腳信號可分為兩組:

1)?CPU控制信號

A1、A0(輸入):A1、A0為端口選擇信號、A1,A0輸入不同時,數(shù)據(jù)總線D7~D0將與不同的轉(zhuǎn)接口或控制字寄存器相連(見表3-8)。圖3-278255引腳配置表3-88255A芯片功能表

3.8255A并行接口的編程操作

(1)寫入8255A命令字:用于設(shè)置8255A電路的工作模式與傳送方向。

8255A的命令字格式與功能如下:

(2)寫入PC端口操作字:用于設(shè)置PC端口的位輸入或輸出狀態(tài)。

8255A的PC端口操作字格式與功能如下:

D7=0:操作字特征位。

D3、D2、D1用于指定PCi位線。其組合如下所示。

3.8.2使用8255拓展單片機端口的原理圖

電路圖采用層次電路圖的形式給出,如圖3-28和圖3-29所示。圖3-28層次電路中的頂層電路圖圖3-29頂層圖中的SUB1子電路圖

(1)?MCS-51系統(tǒng)與8255A電路的接口設(shè)計說明。

(2)?8只LED燈連接于8255A的PA端口,可實現(xiàn)任何LED流水燈的顯示。

(3)?8只數(shù)碼管均為共陰極數(shù)碼管,段控線與8只LED燈共用PA端口,位控線由8255A的PB端口通過74LS138來控制。

(4)?4×4矩陣鍵盤接于8255A的PC端口,這里需要說明的是,在單片機P1端口接矩陣鍵盤時,矩陣鍵盤沒有接上拉電阻,這是因為單片機內(nèi)部P1端口已經(jīng)接了上拉電阻。

(5)根據(jù)PA端口、PB端口和PC端口的功能,可將8255A的命令字寫成0x81,即PA、PB均為輸出,PC低4位輸入,高4位輸出。

(6)喇叭用于發(fā)出聲響,接于8255A的PB4,繼電器用于控制220?V的日光燈泡發(fā)光,接于8255A的PB5。

(7)使用器件列表如圖3-30所示,在Proteus中輸入器件名稱即可找到該器件。該元器件清單中比圖3-2多了鎖存器74LS373和可編程并行接口芯片8255A。

(8)若使8255A正常工作,需要在8255的屬性“--hiddenPins”中將VCC修改為VDD,將GND修改為VSS,這樣就可以給8255A提供工作電源。圖3-30元器件列表清單3.8.3軟件設(shè)計及源碼

使用8255A僅僅是進行I/O接口擴展,因此流水燈、數(shù)碼管、矩陣鍵盤的程序設(shè)計流程圖與不使用8255A時完全一致,對喇叭和繼電器的控制也完全一致,唯一需要修改的就是端口地址,因為單片機的I/O接口與8255A的I/O接口在地址空間中的位置是不同的,注意到這一點,軟件代碼很容易由pin_inout.c文件修改而成?!纠?-17】

由pin_inout.c作少許改動修改成的pin_8255.c文件。

#include<reg51.h>

#include<absacc.h>

#include<intrins.h>

//以下為函數(shù)聲明

voidlight(uchar);

voidled_7s(uchar);

ucharkeyscan(void);

voidspeaker(void);

voidrelay(bit);

voiddelay(ucharx);voidinit_8255(void);

//下面地址定義中包含使能138芯片的信息

#definePA8255XBYTE[0x80fc]

//8255端口A的地址

#definePB8255XBYTE[0x80fd]

//8255端口B的地址

#definePC8255XBYTE[0x80fe]

//8255端口C的地址

#defineCOM8255XBYTE[0x80ff]

//8255命令字的地址voidinit_8255(void)

{

COM8255=0x81; //8255命令字,PA/PB均為輸出,?PC低4位輸入,高4位輸出

}

/************喇叭發(fā)聲代碼************************/

voidspeaker(void)

{

ucharcnt;

F`or(cnt=0;cnt<=100;cnt++)

{ PB8255=PB8255^0x10;

//產(chǎn)生方波

delay(2); //此延時用于產(chǎn)生不同頻率的聲音

}

}

/************繼電器工作代碼************************/

//繼電器由鍵盤控制,本函數(shù)繼電器工作狀態(tài)由輸入?yún)?shù)決定

voidrelay(bitctrl)

{ if(ctrl) PB8255=PB8255|0x20;

//PB5為1,繼電器工作

elsePB8255=PB8255&0xdf;

//PB5為0,繼電器不工作

}

/************流水燈項目代碼************************/

voidlight(void)

{ ucharcnt,tmp=0xfe;

PB8255=PB8255&0xf7;

//關(guān)閉所有數(shù)碼管,第4個管腳控制138不使能端

for(cnt=0;cnt<=7;cnt++)

{

PA8255=tmp;

tmp=(tmp<<1)|1;

delay(250);delay(250); //延時0.5?s

}

}/************七段數(shù)碼管項目代碼***********************/

voidled_7s(ucharkeycode)

{

ucharcnt,tmp=(PB8255&0xf0)|0x8;

//cnt用于選擇段控數(shù)碼;tmp用于位控,實現(xiàn)8個

//數(shù)碼管循環(huán)導(dǎo)通

ucharled_table[16]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0x6f,0x77,

0x7c,0x39,0x5e,0x79,0x71};

//0~F共16個數(shù),用于段控 if(keycode==0xff)

{

for(cnt=0;cnt<16;cnt++)

{

PB8255=tmp++;

//選擇顯示數(shù)碼管

PA8255=led_table[cnt];

//顯示數(shù)據(jù)

if((tmp&0x0f)==0x0)tmp=(PB8255&0xf0)|0x8;

delay(250);delay(250);

//延時約0.5?s }

}

else//要不斷刷新,才能保證LED持續(xù)亮

{

PB8255=tmp;

PA8255=led_table[keycode];

}

}/*************獲取按鍵值,一次按鍵處理一次*****************/

//鍵盤從左到右從上到下的鍵值依次為:

//0,1,2,3

//4,5,6,7

//8,9,10,11

//12,13,14,15

ucharkeyscan(void)

{ucharscode,rcode,keyvalue,keycode;

PB8255=PB8255&0xf7;

//關(guān)閉所有數(shù)碼管,第

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論