一、i/o引腳的特性
單片機(jī)的外部屬性就是它有眾多的i/o引腳,如40腳封裝的51系列,就有32個(gè)腳是i/o引腳。它們也叫單片機(jī)的并口。
這32個(gè)i/o引腳全是數(shù)字的(即只會(huì)出現(xiàn)或只允許0、1變化)。
這32個(gè)i/o引腳分成4組,每組8位(即8根i/o引腳),用p0、p1、p2、p3標(biāo)注,每組里的各位用px.y區(qū)別,如p0口的8位標(biāo)記為p0.0~p0.7(x=0~3;y=0~7)。
當(dāng)然,這四個(gè)口p0、p1、p2、p3是有區(qū)別的,它們都有另外的功能;若只做一般的i/o引腳用,可視它們是一樣的(我們這一講只考慮做一般的i/o引腳用)。
二、i/o引腳的尋址
這四個(gè)口p0、p1、p2、p3(共32根引線)在內(nèi)部映射有4個(gè)8位專用寄存器,名字也叫p0、p1、p2、p3,對這4個(gè)寄存器進(jìn)行操作,也就可對32根引線進(jìn)行操作(它們一一對應(yīng)),很方便。
這里介紹一下字操作、字節(jié)操作、位操作的概念:字是由字節(jié)組成的,一個(gè)字節(jié)為8位二進(jìn)制。字的位數(shù)由cpu的位數(shù)(或cpu里寄存器的位數(shù))決定,即字長;若cpu為8位機(jī),則字長為8位,正好等于一個(gè)字節(jié);若cpu為16位機(jī),則字長為16位,所以字操作時(shí),一次就對兩個(gè)字節(jié)進(jìn)行處理,同理,我們就知道當(dāng)cpu為32位機(jī)、64位機(jī)時(shí),字操作所處理的字節(jié)數(shù)了。所謂字節(jié)操作,就是一次對8位二進(jìn)制同時(shí)進(jìn)行操作。說到這里,大家肯定能回答什么叫位操作了,即對一個(gè)字節(jié)里的某一位進(jìn)行操作。再次強(qiáng)調(diào)一下,以上所講的操作、處理,就是對i/o引腳的尋址、就是執(zhí)行指令的過程,執(zhí)行的結(jié)果就是各位變0或1。
有了以上概念,我們就可以告訴大家,這四個(gè)口p0、p1、p2、p3即可字節(jié)操作,也可位操作。(同學(xué)們好好想一想,拿p1口做例,字節(jié)操作是怎么回事?位操作又是怎么回事?)再進(jìn)一步,操作的含義是什么呢?答:輸入和輸出,即i/o。這32根線,每一根都可以輸入和輸出,輸入是單片機(jī)從外部接收數(shù)據(jù)和命令、感知外部世界的過程;輸出是單片機(jī)根據(jù)設(shè)定、經(jīng)過運(yùn)算、甚至是智能的對外部世界作出反應(yīng),進(jìn)行控制的過程。從指令的角度看,輸入和輸出稍有不同,輸入稍復(fù)雜一些,所以,51單片機(jī)的這32個(gè)輸入和輸出口,也叫準(zhǔn)雙向口。我們下邊先講簡單的輸 出過程,而把輸入過程放在后邊的講座里。
三、i/o引腳的輸出
在第一講里,在最小系統(tǒng)的電路圖里,大家已知p1口和p3口接了16只發(fā)光二極管,現(xiàn)在我們將這兩個(gè)口作為輸出口用,很明白,當(dāng)其中的某個(gè)腳為1時(shí),該腳所接的led是“滅”的;反之,為0時(shí),則“亮”。如下圖所示??梢?,這里的亮或滅是由硬件的接法決定的(若換一種接法,亮滅的電平會(huì)顛倒的)。
由此我們也看出,學(xué)習(xí)單片機(jī),軟、硬件是分不開的,這是它的顯著的特點(diǎn)。
下面給大家介紹幾條i/o引腳輸出的指令:
先介紹指令格式
【標(biāo)號:】操作碼操作數(shù)1,操作數(shù)2 【,操作數(shù)n】【;注釋】
以上的指令格式中,方括號內(nèi)的內(nèi)容可有可無,若要的話,一定注意標(biāo)點(diǎn)符號不能省略;操作碼必有,它是簡單的英語單詞以助記符形式出現(xiàn),便于記憶,它說明了操作的性質(zhì);操作數(shù)可有可無,可多可少,中間以逗號分隔,它和操作碼之間至少空一格,它說明了操作的具體內(nèi)容;注釋也是可有可無,但規(guī)范和專業(yè)的做法是要有詳細(xì)的注釋,且不是簡單的指令說明,而是其物理的、硬件的、實(shí)質(zhì)性的解釋。
字節(jié)輸出的指令
mov p1,#00000000b ;該指令可使p1口的8個(gè)腳(p1.0~p1.7)全部變?yōu)榈碗娖?,?dāng)然,p1口的8只發(fā)光管都會(huì)點(diǎn)亮;(指令中的操作數(shù)2也可寫成#0、#0h,前者是10進(jìn)制寫法,后者是16進(jìn)制寫法,均可)
mov p1,#11111111b ;這條指令相反,8只發(fā)光管都會(huì)滅。
位輸出的指令
clr p1.0 ;該指令使p1口的0腳變?yōu)榈碗娖剑拥哪侵话l(fā)光管亮,不會(huì)影響其他。
而 setb p1.0 這條指令就使p1口的0腳變?yōu)楦唠娖健?br>有了以上這些準(zhǔn)備,下面我們就來編一段程序,讓p1口和p3口的發(fā)光管輪流點(diǎn)亮,每個(gè)發(fā)光管點(diǎn)亮200ms,輪流不息,俗稱“流水燈”。
四、流水燈編程
1.字節(jié)方式處理
;****************************************
org 0000h
;org為偽指令,告訴匯編程序,下面的指令從rom的0000h處開始放
main: mov p1,#11111110b
mov p3,#11111110b
;可見,以上兩條指令使p1口的p1.0腳和p3口的p3.0腳所接發(fā)光管點(diǎn)亮
lcall ys200ms
;上面是一條調(diào)用子程序指令,用意是讓cpu執(zhí)行一些其他無關(guān)的指令,耗費(fèi)掉200ms的時(shí)間,讓剛亮的兩只發(fā)光管能亮200ms時(shí)間,否則,由于cpu執(zhí)行指令太快,我們將無法分清哪只發(fā)光管亮了。
mov p1,#11111101b
mov p3,#11111101b ;很顯然,換了兩只發(fā)光管亮
lcall ys200ms
mov p1,#11111011b
mov p3,#11111011b ;很顯然,又換了兩只發(fā)光管亮
lcall ys200ms
mov p1,#11110111b
mov p3,#11110111b ;很顯然,又換了兩只發(fā)光管亮
lcall ys200ms
mov p1,#11101111b
mov p3,#11101111b ;很顯然,又換了兩只發(fā)光管亮
lcall ys200ms
mov p1,#11011111b
mov p3,#11011111b ;很顯然,又換了兩只發(fā)光管亮
lcall ys200ms
mov p1,#10111111b
mov p3,#10111111b ;很顯然,又換了兩只發(fā)光管亮
lcall ys200ms
mov p1,#01111111b
mov p3,#01111111b ;很顯然,又換了兩只發(fā)光管亮
lcall ys200ms
;到此為止,p1口和p3口的發(fā)光管輪流亮了一遍
ljmp main
;我們應(yīng)該讓cpu返回開始處,再次開始亮燈循環(huán),上邊這條指令就是無條件跳轉(zhuǎn)指令,命令cpu跳回標(biāo)號為main處,繼續(xù)執(zhí)行指令,永遠(yuǎn)往復(fù)。
以下給出延時(shí)子程序,以保持程序的完整性,但不講解,以后再說。
ys200ms: mov r7,#4
ys0: mov r6,#100
ys1: mov r5,#250
djnz r5,$
djnz r6,ys1
djnz r7,ys0
ret
end
;************************************************************
位處理方式
;**************************************************
org 0000h
main: mov p1,#0ffh
mov p3,#0ffh ;先做準(zhǔn)備工作,使所有l(wèi)ed全滅
loop: clr p1.0 ;p1.0腳所接發(fā)光管點(diǎn)亮
clr p3.0 ;p3.0腳所接發(fā)光管點(diǎn)亮
lcall ys200ms
setb p1.0
setb p3.0 ;在點(diǎn)亮下一只前,關(guān)掉已點(diǎn)亮的
clr p1.1 ;p1.1腳所接發(fā)光管點(diǎn)亮
clr p3.1 ;p3.1腳所接發(fā)光管點(diǎn)亮
lcall ys200ms
setb p1.1
setb p3.1 ;在點(diǎn)亮下一只前,關(guān)掉已點(diǎn)亮的
clr p1.2 ;p1.2腳所接發(fā)光管點(diǎn)亮
clr p3.2 ;p3.2腳所接發(fā)光管點(diǎn)亮
lcall ys200ms
setb p1.2
setb p3.2 ;在點(diǎn)亮下一只前,關(guān)掉已點(diǎn)亮的
clr p1.3 ;p1.3腳所接發(fā)光管點(diǎn)亮
clr p3.3 ;p3.3腳所接發(fā)光管點(diǎn)亮
lcall ys200ms
setb p1.3
setb p3.3 ;在點(diǎn)亮下一只前,關(guān)掉已點(diǎn)亮的
clr p1.4 ;p1.4腳所接發(fā)光管點(diǎn)亮
clr p3.4 ;p3.4腳所接發(fā)光管點(diǎn)亮
lcall ys200ms
setb p1.4
setb p3.4 ;在點(diǎn)亮下一只前,關(guān)掉已點(diǎn)亮的
clr p1.5 ;p1.5腳所接發(fā)光管點(diǎn)亮
clr p3.5 ;p3.5腳所接發(fā)光管點(diǎn)亮
lcall ys200ms
setb p1.5
setb p3.5 ;在點(diǎn)亮下一只前,關(guān)掉已點(diǎn)亮的
clr p1.6 ;p1.6腳所接發(fā)光管點(diǎn)亮
clr p3.6 ;p3.6腳所接發(fā)光管點(diǎn)亮
lcall ys200ms
setb p1.6
setb p3.6 ;在點(diǎn)亮下一只前,關(guān)掉已點(diǎn)亮的
clr p1.7 ;p1.7腳所接發(fā)光管點(diǎn)亮
clr p3.7 ;p3.7腳所接發(fā)光管點(diǎn)亮
lcall ys200ms
setb p1.7 ;p1.7腳所接發(fā)光管滅
setb p3.7 ;p3.7腳所接發(fā)光管滅
ljmp loop ;跳至標(biāo)號loop處繼續(xù)反復(fù)
;***********************************************************
延時(shí)子程序同上,不再重復(fù)。
以上我們可看出,完成相同的任務(wù),但編寫程序的方法卻不一樣,其實(shí)還有更多的方法完成這一任務(wù)。由此,我們的同學(xué)們應(yīng)該領(lǐng)會(huì)到,“指令是死的,人是活的”,“條條大道通北京”,只要發(fā)揮我們的聰明才智,總是可以達(dá)到目的的。
最后強(qiáng)調(diào)一下,做這些發(fā)光管亮滅實(shí)驗(yàn)的意義何在?它的意義就在于:我們能使發(fā)光管隨心所欲的亮和滅,且有精確的時(shí)間控制,就能對任何其他的外部設(shè)備進(jìn)行控制,如彩燈、電動(dòng)機(jī)、車床等,只是變一變相應(yīng)的電路而已。