www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 電源 > 數(shù)字電源
[導(dǎo)讀]單片機(jī)入門(mén)不難------談PIC系列(轉(zhuǎn)自礦石收音機(jī)論壇---嶗山)十年前的老帖子,講得通俗易懂,分享之。請(qǐng)看圖1 這個(gè)8條腿的小螃蟹就是我們的第一頓飯,只要把它吃下去,以后

單片機(jī)入門(mén)不難------談PIC系列(轉(zhuǎn)自礦石收音機(jī)論壇---嶗山)十年前的老帖子,講得通俗易懂,分享之。

請(qǐng)看圖1

 

 

這個(gè)8條腿的小螃蟹就是我們的第一頓飯,只要把它吃下去,以后的大餐就好辦了。

第1、8條腿接電源 +5V 和 地線。頭兩條腿是螃蟹鉗子,好吃的很。 現(xiàn)在剩下了 6 條腿

第2、3條腿 使用時(shí)外接一個(gè)晶振的東西 我們接一個(gè) 4 MHz的。

第4條腿是復(fù)位腳,是一個(gè)信號(hào)輸入腳。單片機(jī)正常運(yùn)行時(shí)接高電平。當(dāng)有一個(gè)低電平脈沖輸入到這個(gè)腳時(shí)單片機(jī)就復(fù)位。所謂復(fù)位就是單片機(jī)內(nèi)部所有的工作部件統(tǒng)統(tǒng)回到規(guī)定的狀態(tài),程序也復(fù)位到頭一句上開(kāi)始逐條運(yùn)行。例如,你設(shè)計(jì)的一個(gè)報(bào)警鎖定的 LED紅燈亮后,當(dāng)需要解除報(bào)警時(shí),用一個(gè)按鈕給這個(gè)腳瞬時(shí)接地一下,相當(dāng)于給它一個(gè)夫脈沖,系統(tǒng)就復(fù)位了,led燈就熄滅了,程序從頭開(kāi)始。

以上5個(gè)腳,幾乎所有單片機(jī)都有,包括世界上最復(fù)雜的,和世界比較簡(jiǎn)單的單片機(jī)-----PIC12CE519

輪到底幾條腿啦?奧是第5條腿,這條叫單片機(jī)的 I/O 腳。就是輸入輸出腳。你可通過(guò)程序動(dòng)態(tài)地控制它作為輸入或輸出,作為輸出時(shí)可以程序控制它的輸出電平為高1或低0。所以,他的工作狀態(tài)有四種:輸入0,輸入1,輸出0,輸出1

剩下的兩條腿和第5腳功能一個(gè)樣。

上邊我們已經(jīng)把8條腿消化掉了,其實(shí)我們要弄明白的也就3只腿,我們?cè)俸?jiǎn)單一些,先整明白兩條腿,即GP0,GP1.這兩條腿低級(jí)一點(diǎn)的用法,可以控制繼電器,LED燈,高級(jí)一些的用法可以進(jìn)行I2C總線,RS232總線的通信,作為擴(kuò)展輸入可以模擬出來(lái)A/D轉(zhuǎn)換器(6--7bit),可以測(cè)量一個(gè)電阻的粗略值。作為輸出也可以直接推動(dòng)揚(yáng)聲器奏出音樂(lè)。這是后話(huà)暫且不提。

現(xiàn)在要控制使用這兩只腿,我這個(gè)三腳貓功夫的說(shuō)書(shū)的不得不講一下軟件了,要想講明白軟件又不得不涉及到單片機(jī)的內(nèi)部結(jié)構(gòu)。那位說(shuō)啦,你可別提這軟件和結(jié)構(gòu)了,以前俺就是讓它們打敗的,現(xiàn)在聽(tīng)到這個(gè)心里就打鼓。嘿嘿,不要緊,果真如你所說(shuō),那你就不妨跟著我再失敗一次, 反正嗎多一次失敗又不納稅,嘿嘿。不過(guò)你也要有思想準(zhǔn)備,徹底弄明白是個(gè)漸進(jìn)的過(guò)程。

要說(shuō)這程序和單片機(jī)內(nèi)部結(jié)構(gòu),還真是老大難,不過(guò)蟹黃蟹肉都可都在里面。我現(xiàn)在要是給你說(shuō)PIC單片機(jī)是哈佛結(jié)構(gòu)的,51系列是馮-諾伊曼結(jié)構(gòu)的,恐怕你要立馬扎走人了。所以我得用點(diǎn)心思不讓你溜號(hào)。

好在PIC系列的制造商(microchip 微芯公司 美國(guó))理解我等苦衷,全部只有35條指令,而且有一些指令我們一般很少使用,常用的也就十幾句,用的時(shí)候查手冊(cè),無(wú)需記憶。就算我們兩天學(xué)習(xí)一句,也就兩三個(gè)月時(shí)間,總比到老了還怕它們強(qiáng)啊。廢話(huà)少說(shuō)先看下面的兩個(gè)例語(yǔ):

my_name006: movlw 02h '常數(shù)2進(jìn)入w

movwf GPIO 'W 的數(shù)進(jìn)入 寄存器GPIO

這就是我們編的程序里的兩個(gè)句子,也叫源程序。有以下特點(diǎn)

每行只能寫(xiě)一句話(huà)

每句話(huà)由四部分組成:

標(biāo)號(hào): 操作指令 操作數(shù) '程序注釋

下面我結(jié)合例子把這四部分解釋一下。

第一部分 my_name006: 叫做標(biāo)號(hào),它是由字母或數(shù)字組成,由冒號(hào)結(jié)束。標(biāo)號(hào)可有可無(wú),比如第二句就沒(méi)有標(biāo)號(hào)。

第二部分movlw 叫做操作指令。它是必須有的,不能省略。PIC 系列的單片機(jī)共有 35 條指令。

第三部分02h 叫做操作數(shù)。有的指令沒(méi)有操作數(shù)或者操作數(shù)是默認(rèn)的,也不用寫(xiě)。

第四部分是程序注釋?zhuān)仨氁詥我?hào)開(kāi)頭,主要作用是提醒和備忘。注釋也是可有可無(wú)。

第二個(gè)例句中,省略了標(biāo)號(hào),當(dāng)然注釋也可以省略。他的指令是movwf, 操作數(shù)是GPIO。操作數(shù)不一定是數(shù)字,也可能是一個(gè)由字母組成的字符串。

知道了語(yǔ)句格式以后,我們下面就學(xué)習(xí)一些常用語(yǔ)句。我們先把這兩個(gè)例句弄清楚。

這兩句話(huà)的作用是把 2 這個(gè)常數(shù)寫(xiě)入到 GPIO 這個(gè)寄存器里。

單片機(jī)里有一些部件需要我們使用和操作,都是通過(guò)讀寫(xiě)寄存器來(lái)實(shí)現(xiàn)的。每個(gè)部件都對(duì)應(yīng)有操控它的寄存器,例如我們要控制使用的管腳GP0,GP1 這兩個(gè)管腳對(duì)應(yīng)的寄存器就叫做GPIO。對(duì)GPIO寄存器讀操作,實(shí)際等效察看管腳電平的高低;對(duì)GPIO寄存器相應(yīng)的位寫(xiě)1操作,實(shí)際等校讓管腳輸出高電平。寫(xiě)0,輸出低電平。

每個(gè)寄存器可以?xún)?chǔ)存一個(gè)八位的二進(jìn)制數(shù)。這八個(gè)位的每個(gè)位都有名稱(chēng),從左向右的名稱(chēng)是:

左端第首位名稱(chēng)叫D7,

左端第二位名稱(chēng)叫D6,

左端第三位名稱(chēng)叫D5,

左端第四位名稱(chēng)叫D4,

左端第五位名稱(chēng)叫D3,

左端第六位名稱(chēng)叫D2,

左端第七位名稱(chēng)叫D1,

最后一位叫D0,

而每一個(gè)位對(duì)應(yīng)一個(gè)管腳的電平,例如當(dāng)GPIO寄存器的D0位等于1時(shí)表示管腳GP0 的電平是高電平。D0位等于0時(shí)表示管腳GP0 的電平是低電平。常數(shù)2的八位二進(jìn)制表示是“00000010” 所以,GPIO寄存器存放的8位2進(jìn)制數(shù)的每個(gè)位的值以及管腳電平是:

D7對(duì) 應(yīng)于內(nèi)部總線管腳的電平 D7=0 內(nèi)部總線管腳輸出低電平

D6對(duì)應(yīng)于內(nèi)部總線管腳的電平 D6=0 內(nèi)部總線管腳輸出低電平

D5對(duì)應(yīng)于GP5 管腳的電平 D5=0 GP5 管腳輸出低電平

D4對(duì)應(yīng)于GP4 管腳的電平 D4=0 GP4 管腳輸出低電平

D3對(duì)應(yīng)于GP3 管腳的電平 D3=0 GP3 管腳輸出低電平

D2對(duì)應(yīng)于GP2 管腳的電平 D2=0 GP2 管腳輸出低電平

D1對(duì)應(yīng)于GP1 管腳的電平 D1=1 GP1 管腳輸出低電平

D0對(duì)應(yīng)于GP0 管腳的電平 D0=0 GP0 管腳輸出低電平

GP0---GP5管腳我們可以從上一講的圖1硬件中查出所對(duì)應(yīng)的管腳。d7 d6 對(duì)應(yīng)的內(nèi)部時(shí)鐘和數(shù)據(jù)總線我們現(xiàn)在暫且不要管它。以后本事大了在調(diào)教它們。在我們的例句中,向GPIO寄存器寫(xiě)入了2,常數(shù)2的八位二進(jìn)制表示是“00000010” 因此如果此時(shí)GP0, Gp1等都已經(jīng)被定義成輸出的話(huà),那么GP1輸出高電平(接LED燈亮),GP0 輸出低電平(所接led燈熄) 。

截止到現(xiàn)在,你已經(jīng)學(xué)會(huì)如何控制管腳的電平高低了。盡管還有一些疑問(wèn),比如怎樣定義管腳為輸出腳(以后會(huì)說(shuō)),我得說(shuō)如果事先gp1,gp0這兩個(gè)管腳處于輸入狀態(tài),這兩個(gè)例句無(wú)效,是控制不了電平的。

無(wú)論如何,這一會(huì)兒,你就學(xué)會(huì)了兩個(gè)指令,35條我看也沒(méi)啥難的。

'------------------------------------------------------------------------------

再加深一下對(duì)寄存器的認(rèn)識(shí):

要把一個(gè)常數(shù)存儲(chǔ)到,或者說(shuō)寫(xiě)到一個(gè)寄存器中,僅用一條指令是辦不到的,必須通過(guò)一個(gè)特殊的寄存器W,把數(shù)據(jù)倒過(guò)去. 這就應(yīng)該使用到兩個(gè)語(yǔ)句。

movlw 02H 指令的意思是把一個(gè)常數(shù)存入特殊寄存器W, 這個(gè)常數(shù)是3,后面的H是表示十六進(jìn)制

movwf GPIO 指令的意思是把特殊寄存器W的數(shù)值存入寄存器. 這個(gè)寄存器的名稱(chēng)是 GPIO

這里涉及到兩個(gè)概念,常數(shù)和寄存器.

常數(shù)好說(shuō),比如說(shuō)十進(jìn)制數(shù) 35, 26 但要注意,在單片機(jī)系統(tǒng)里我們一般不用十進(jìn)制,而使用十六進(jìn)制. 有關(guān)數(shù)制轉(zhuǎn)換方面的知識(shí),是計(jì)算機(jī)的基礎(chǔ),必須會(huì)熟練地在二進(jìn)制、十六進(jìn)制、十進(jìn)制之間轉(zhuǎn)換,我就不羅索了.

寄存器也叫單片機(jī)的內(nèi)存。

一個(gè)寄存器可以存儲(chǔ)的數(shù)值范圍是0--255,用十六進(jìn)制表示就是 0---FFH.用二進(jìn)制表示就是00000000----11111111.

以后要養(yǎng)成習(xí)慣用十六進(jìn)制表示數(shù).

那么,一個(gè)單片機(jī)里有多少個(gè)這樣的寄存器哩,pic12ce512里面有1024個(gè)這樣的寄存器可以供你使用,為了使用方便生產(chǎn)商已經(jīng)給它們編上了號(hào)碼,第一號(hào)碼是000H,往下依照次序?yàn)?001H,002H........3FFH.(怎么樣,開(kāi)始用十六進(jìn)制說(shuō)事了吧,如果你不熟悉熟制轉(zhuǎn)換趕緊補(bǔ)課來(lái)得及)

有了編號(hào)就像我們居住的房間有了房間號(hào)碼,使用就方便的多了.房間號(hào)碼在郵政行業(yè)叫地址,因此我們稱(chēng)這些號(hào)碼叫做寄存器地址,或稱(chēng)地址數(shù) 例如 名稱(chēng)為 GPIO 的寄存器,他的地址,或地址數(shù)是 06H 。所以我們的兩個(gè)例句完全等同于:

my_name006: movlw 02h '常數(shù)2進(jìn)入w

movwf 06H 'W 的數(shù)進(jìn)入 寄存器GPIO

'-----------------------------------------

有兩個(gè)寄存器比較特殊,它們沒(méi)有地址,一個(gè)名字叫做 W, 另一個(gè)叫做 TRIS. 所以他們兩個(gè)在存儲(chǔ)數(shù)據(jù)的時(shí)候比較快,一個(gè)指令就可以解決問(wèn)題,例如: movlw 03H 一條指令就把常數(shù)3寫(xiě)入到W寄存器了。關(guān)于TRIS寄存器,我們以后用到它再說(shuō).

除了他們兩個(gè)以外的其他所有寄存器,在寫(xiě)入數(shù)據(jù)時(shí)一般都要用兩條指令進(jìn)行。

今天就扯到這里,雖然只有兩個(gè)指令,但主要目的是要同學(xué)們接觸一下指令,建立寄存器的概念以及他們同硬件部件的聯(lián)系。增強(qiáng)學(xué)習(xí)的信心。能有這些體會(huì),這一節(jié)就算過(guò)關(guān)了。

隨著以后的深入,你會(huì)發(fā)現(xiàn)小小單片機(jī)里面是一個(gè)大世界,興趣也由此而生。

我們上一次講的兩個(gè)指令是是如何控制管腳電平的高低。前提是所有管腳已經(jīng)被定義成輸出了(OUT)如果被定義成了輸入,則上次的指令雖然也能運(yùn)行,但運(yùn)行后絲毫不能改變管腳電平高低,因?yàn)榇藭r(shí)管腳是輸入狀態(tài),電平取決于外部輸入,指令無(wú)法改變。

在PIC單片機(jī)系列中,改變I/O口的輸入輸出依靠寫(xiě)入寄存器TRIS的值,相應(yīng)位寫(xiě)0,表示對(duì)應(yīng)管腳被定義成了輸出,寫(xiě)1,就是輸入。

現(xiàn)在假如預(yù)把GP1、GP2管腳定義成輸出,其他腳全是輸入。那就應(yīng)該向TRIS 寄存器寫(xiě)入二進(jìn)制數(shù) 11111001,換算成十六進(jìn)制就是

F9H.

依照以前我們學(xué)到的知識(shí),在PIC系列單片機(jī)里,本來(lái)應(yīng)該用下列的語(yǔ)句來(lái)完成我們的設(shè)定:

movlw 0F9H '常數(shù)進(jìn)W 以字母開(kāi)頭的常數(shù)前面必須加0

movwf TRISA '把W內(nèi)的數(shù)復(fù)制到TRIS

實(shí)際上PIC系列的單片機(jī)也都是這么寫(xiě)的,后面加的A,表示第一個(gè)8位的口(有的單片機(jī)不僅一個(gè)口,還有好幾個(gè)8位的I/O口如TRISB TRISC TRISD等等) .

但是,記住了, PIC12系列的單片機(jī)必須改寫(xiě)成為:

movlw 0F9H '常數(shù)進(jìn)W 以字母開(kāi)頭的常數(shù)前面必須加0

tris GPIO '把W內(nèi)的數(shù)復(fù)制到TRIS 以后凡見(jiàn)到這個(gè)指令一律理解成 movwf TRISA

寫(xiě)法不同,意思是一樣的. 這樣你就又學(xué)了一個(gè)指令TRIS,不過(guò)這個(gè)指令的實(shí)質(zhì)還是你曾經(jīng)學(xué)過(guò)的movwf 只是寫(xiě)法不同罷了.

在PIC12系列里TRIS作為指令, 在其他系列(PIC161718)里把 TRIS 作為普通寄存器看待.

因?yàn)槲覀儸F(xiàn)在講的就是PIC12CE519,所以我們暫時(shí)用

tris GPIO

這個(gè)格式,等以后進(jìn)入PIC16C877 我們?cè)賹?xiě)成 movwf TRISA , 至于理解按照后者進(jìn)行.

'-----------

如果我們要控制GP1 GP2管腳的輸出電平, 其他管腳作為輸入.并且讓GP1輸出低電平,GP2輸出高電平.完整的程序如下:

movlw 0F9H '常數(shù)進(jìn)W

tris GPIO '把W內(nèi)的數(shù)復(fù)制到TRIS ,GP1 GP2為輸出,其他為輸入

'此行無(wú)命令,起到的作用是容易讀懂程序

movlw 04H '常數(shù)4的二進(jìn)制是 00000100 ,GP1=0 GP2=1

movwf GPIO 'W內(nèi)的數(shù)進(jìn)GPIO 輸出生效,原來(lái)定義成輸入的腳的電平,不會(huì)受該句影響

上面已經(jīng)學(xué)會(huì)了三條指令,但是8位寄存器的概念概念一定要建立起來(lái),程序通過(guò)寫(xiě)入寄存器不同的數(shù)據(jù)

控制管腳作為輸入使用還是輸出使用,作為輸出時(shí)是輸出高電平還是低電平。

這樣的操作又一個(gè)特點(diǎn),就是每次寫(xiě)入數(shù)據(jù),同時(shí)控制的往往不是一個(gè)管腳,而是好幾個(gè)個(gè).最多一次可

以控制8個(gè)管腳.在單片機(jī)里往往每8個(gè)腳叫做一個(gè)口,如口A, 口B,用英文表示就是GPIO PORTA PORTB PORTC 等.

更多的情況是:某個(gè)口內(nèi)的某一個(gè)管腳需要改變電平,其他腳電平不變.例如我們僅需要GPIO口上的GP1

這個(gè)管腳的電平拉高,其他管腳電平不發(fā)生變化.這時(shí)候位操作指令為我們提供了方便,假如我們事先已經(jīng)把GP1管腳定義過(guò)輸出了(方法見(jiàn)前面講過(guò)的):

bcf GPIO,GP1 '注釋 GPIO口上GP1管腳電平拉低,我們行話(huà)叫 清除。

bSf GPIO,GP1 '注釋 GPIO口上GP1管腳電平拉高,我們行話(huà)叫 置位。

怎么樣,這樣控制某一個(gè)管腳的電平就方便多了,你的編程效率大大提高啊.

記住:PIC所有單片機(jī)所有寄存器都是可以位操作的,這在51的單片機(jī)上是不能完全實(shí)現(xiàn)的.

不僅如此,PIC所有單片機(jī)所有管腳的單腿驅(qū)動(dòng)輸出電流可以高達(dá) 25mA,所以如果你驅(qū)動(dòng)一個(gè) 5到10mA電流的LED發(fā)光二極管,根本不用加三極管,串個(gè)電阻直接掛在單片機(jī)上就得了,這在51的單片機(jī)上也是不能實(shí)現(xiàn)的,要加驅(qū)動(dòng)三極管或驅(qū)動(dòng)芯片.

怎么樣,學(xué)PIC有好處吧. 也別急,好處還有那,且聽(tīng)我慢慢地白話(huà)。

一不小心,你已經(jīng)會(huì) 5 個(gè)指令了,還有30個(gè),加油啊。

繼續(xù)

單片機(jī)的大部分指令,或者說(shuō)單片機(jī)所做的大部分工作,多數(shù)在寫(xiě)入或讀出寄存器。關(guān)于寄存器的初步概念我想我們已經(jīng)建立起來(lái)了,它是一個(gè)能夠存儲(chǔ)8位二進(jìn)制數(shù)據(jù)(最大255 = 0FFH) 的單元 每個(gè)單元都有它的編號(hào),我們叫做它的地址,或地址編碼. 地址編碼也是十六進(jìn)制的. 另外寄存器里的數(shù)據(jù)掉電就會(huì)丟失。

寄存器的英文是RAM 也要記住.

PIC12CE519 里面共有有48個(gè)寄存器供我們操作使用, 它們每一個(gè)都有固定的地址編碼。

地址編碼并不是連續(xù)的號(hào)碼,而是分成了兩段:

第一段: 從00H 開(kāi)始, 依次是01H, 02H, 03H ....0AH, 0BH......到1FH 結(jié)束. 計(jì)32個(gè)寄存器

第二段: 從30H 開(kāi)始, 依次是31H, 32H, ......................到3FH 結(jié)束 計(jì)16個(gè)寄存器

這種地址不連續(xù)編號(hào), 而是要跳過(guò)去一段的做法, 對(duì)于我們新手來(lái)說(shuō)很是不習(xí)慣. 為了讓我們?nèi)菀兹腴T(mén), 我們暫時(shí)先不管第二段RAM, 只當(dāng)它不存在, 所有程序我們只涉及到第一段連續(xù)的ram 地址. 等我們熟練的掌握好了ram 的使用,再涉及第二段地址的RAM, 那時(shí),你就會(huì)理解單片機(jī)設(shè)計(jì)者把它們分成兩段的苦心了.

為了規(guī)范,我們今后一律把RAM的分段, 叫做分頁(yè). 第一地址段叫00頁(yè)面, 第二地址段叫01頁(yè)面.

例如: 我們學(xué)過(guò)的 I/O 口電平控制寄存器 GPIO, 它的地址編碼是 06H, 屬于00頁(yè)面.

'-----------------

所有這32+16=48個(gè)寄存器除了在地址上分成了兩個(gè)頁(yè)面以外,又把它們分成兩類(lèi):

一類(lèi)專(zhuān)用寄存器,一類(lèi)通用寄存器.

所謂專(zhuān)用,就是這個(gè)寄存器的功能已經(jīng)由系統(tǒng)分配好了.例如 地址為06H 的名稱(chēng)就做GPIO寄存器的功能,是它的每個(gè)位,都對(duì)應(yīng)到一個(gè)I/O腳的電平.

另一類(lèi) 是通用寄存器,你可以理解成它的功能系統(tǒng)沒(méi)有事先預(yù)定,而是由你在編程序的時(shí)候隨機(jī)使用.

pic12ce519 的專(zhuān)用寄存器有 7 個(gè), 位置在我們第00葉面的最前面. 這7個(gè)專(zhuān)用寄存器的地址編碼是: 00H,01H, 02H, ----06 H

剩下的所有寄存器包括所有第01頁(yè)面, 全部都是通用寄存器.

例子: 在兩個(gè)通用寄存器 09H, 0AH 內(nèi), 寫(xiě)入常數(shù) FC H

movlw 0FCH '常數(shù)進(jìn)W

movwf 9H '復(fù)制W內(nèi)的數(shù)到通用寄存器09H

movwf 0AH '復(fù)制W內(nèi)的數(shù)到通用寄存器0AH 由于此時(shí)W內(nèi)并沒(méi)有改變,W不用再進(jìn)常數(shù).

'----------------------------------------------

下面是PIC12CE519的 寄存器ram的地址地圖:

圖最上端的 00 01 表示的是頁(yè)面號(hào)碼,或叫頁(yè)面地址。

左側(cè) 從00 --- 1FH 是00頁(yè)面, 右側(cè)是01頁(yè)面。

從00H 到 06H 都已經(jīng)起好了名稱(chēng) ,它們是專(zhuān)用寄存器,用處各有不同。以后我們會(huì)逐個(gè)介紹它們

剩下的都是通用寄存器 或者叫普通寄存器 General Purpose Registers 意思是一般用途的寄存器

地址從20H 到 2FH 也不是“空洞”,也不是不能訪問(wèn),只是讀寫(xiě)它們的時(shí)候等于讀寫(xiě)它們左側(cè)對(duì)應(yīng)的00頁(yè)面。這一點(diǎn)我們可能有些迷惑,弄不明白也沒(méi)有關(guān)系,以后隨著程序理解的深入,會(huì)搞清楚的。

內(nèi)存圖譜,不要求記下來(lái),但是應(yīng)該有個(gè)大體印象,用的時(shí)候會(huì)察看就可以了。等編程時(shí)間一長(zhǎng)

就那么幾個(gè)字節(jié),自然就記住了。

所謂字節(jié)是衡量二進(jìn)制數(shù)據(jù)長(zhǎng)度的一個(gè)單位。一個(gè)寄存器剛好能記住一個(gè)字節(jié)的數(shù)據(jù)。如果你要存儲(chǔ)的數(shù)據(jù)比較大超過(guò)了255,那就要占2個(gè)存儲(chǔ)器甚至更多。描述的時(shí)候通常我們不說(shuō)這個(gè)數(shù)值占了多少個(gè)寄存器,而是說(shuō)這個(gè)數(shù)據(jù)是幾個(gè)字節(jié)的。

字節(jié)的英文是byte 一個(gè)二進(jìn)制數(shù)的一位,叫比特 英文bit 1 byte 包含 8 bit

繼續(xù)

下面我們學(xué)習(xí)一條新指令,叫做空操作指令

nop '什么事情也不做,但執(zhí)行這個(gè)指令也要消耗掉一點(diǎn)時(shí)間。它沒(méi)有操作數(shù)。

'不要理解成程序停了,實(shí)際上程序仍在正常運(yùn)行。執(zhí)行一連串的空操作指令,單片機(jī)

'白耗費(fèi)時(shí)間,什么活也不干,往往用于延時(shí)

如果你需要一個(gè)很短時(shí)間的延時(shí),可以采用一連串的空操作。注意每個(gè) nop 也是占一行, 例如:

movlw 0F9H '常數(shù)進(jìn)W

tris GPIO '把W內(nèi)的數(shù)復(fù)制到TRIS ,GP1 GP2為輸出,其他為輸入

bsf GPIO,GP1 '管腳GP1輸出高電平點(diǎn)亮LED燈(如果你已經(jīng)接上燈的話(huà))

nop

nop

nop

nop

nop

... .

bcf GPIO,GP1 '管腳GP1輸出低電平關(guān)閉LED燈

nop

nop

nop

nop

...

運(yùn)行的效果是接在管腳GP1上的LED燈先亮一段時(shí)間,再熄滅一段時(shí)間的閃爍。

這回再說(shuō)一個(gè)程序轉(zhuǎn)向的語(yǔ)句,goto 指令,學(xué)過(guò)basic 和 c 等語(yǔ)言的對(duì)它不陌生。

單片機(jī)對(duì)程序的執(zhí)行是逐句自上而下進(jìn)行。當(dāng)它運(yùn)行到某個(gè)位置,如果你不希望繼續(xù)運(yùn)行它下面的語(yǔ)句,而是希望它無(wú)條件的強(qiáng)行轉(zhuǎn)到某一句上,就可以使用goto語(yǔ)句。

我們還是通過(guò)例子來(lái)說(shuō)明goto 的使用方法。

已知外部晶振的頻率為4 MHz, 設(shè)計(jì)程序從pic12ce512 單片機(jī)的GP1管腳上輸出一個(gè)方波信號(hào),信號(hào)頻率固定并計(jì)算出頻率的值。

movlw 0F9H '常數(shù)進(jìn)W

tris GPIO '把W內(nèi)的數(shù)復(fù)制到TRIS ,GP1 GP2為輸出,其他為輸入

myWAVE: bsf GPIO,GP1 '管腳GP1輸出高電平點(diǎn)亮LED燈(如果你已經(jīng)接上燈的話(huà))

nop

nop

nop

nop

nop

nop

nop

bcf GPIO,GP1 '管腳GP1輸出低電平關(guān)閉LED燈

nop

nop

nop

nop

nop

goto myWAVE 'myWAVE是標(biāo)號(hào),某行必須有這個(gè)標(biāo)號(hào),否則程序通不過(guò)

nop '由于goto的存在,以下語(yǔ)句得不到運(yùn)行

nop

nop

當(dāng)程序自上而下運(yùn)行到goto 語(yǔ)句時(shí), 不再繼續(xù)運(yùn)行它底下的語(yǔ)句, 而是讓程序強(qiáng)行轉(zhuǎn)向到標(biāo)號(hào)為myWAVE的語(yǔ)句上,并繼續(xù)運(yùn)行.

這樣一來(lái)的結(jié)果,程序會(huì)永遠(yuǎn)在標(biāo)號(hào)myWAVE的這一句 bsf GPIO,GP1 到goto之間循環(huán), 打轉(zhuǎn)轉(zhuǎn).

客觀運(yùn)行的結(jié)果是 GP1管腳電平不停地一會(huì)高,一會(huì)低, 就輸出了方波信號(hào).

要計(jì)算方波的頻率,我們必須知道單片機(jī)每運(yùn)行一條指令需要多少時(shí)間.這個(gè)時(shí)間的單位不以通常的秒 毫秒 或微秒作為單位, 而是以”機(jī)器周期” 為單位. 以后凡是我們討論單片機(jī)內(nèi)部的時(shí)間問(wèn)題都要以機(jī)器周期作為時(shí)間單位. 至于一個(gè)機(jī)器周期究竟是多少微妙或毫秒, 取決于單片機(jī)的品牌和振蕩頻率頻率大小, 等一會(huì)我們?cè)儆霉接?jì)算我們PIC12CE512在4MHz震蕩頻率下的機(jī)器周期是多少個(gè)微妙。

我們先看看我們的程序中GP1腳的高電平低電平都是用了多少個(gè)機(jī)器周期.

PIC單片機(jī)所有指令都是單機(jī)器周期的指令,

例外的情況是goto 語(yǔ)句要用2個(gè)機(jī)器周期 還有一個(gè)call指令用的時(shí)間也不完全是一個(gè)機(jī)器周期(待后續(xù))

其他品牌的某些單片機(jī)可不是這樣,一條指令往往要用幾個(gè)周期……

從bsf 到bcf有8個(gè)指令,都是單周期指令,所以GP1高電平時(shí)間長(zhǎng)度是8個(gè)機(jī)器周期

從bcf 到bsf有7條指令,其中6條是單周期指令 1條雙周期指令(goto). 所以GP1低電平時(shí)間長(zhǎng)度也是8個(gè)機(jī)器周期

這樣,我們輸出方波的周期長(zhǎng)度就是16 個(gè)機(jī)器周期.

Pic品牌的機(jī)器周期 = 4/振蕩頻率 (公式)

所以,在我們的例子當(dāng)中 1個(gè)機(jī)器周期=4/4MHz= 1 uS

也就是說(shuō),我們的例子中,執(zhí)行一條指令僅需要1微秒的時(shí)間.

這樣,我們輸出的方波周期就是16微秒, 頻率是 f =1/16 =0.0625 兆赫 =62.5 KHz

如果這個(gè)方波的頻率比較低,你再接一個(gè)揚(yáng)聲器到GP1腳上你就可以聽(tīng)到聲音了

頻率降低到幾赫茲的時(shí)候, 接一個(gè)led燈, 就會(huì)不停的閃爍.

當(dāng)然, 頻率太低你用的nop指令的數(shù)目會(huì)很多,程序雖簡(jiǎn)單但是臃腫, 這沒(méi)有關(guān)系,我們主要是在學(xué)習(xí)程序, 弄清楚道理是目的。

要想使得程序不臃腫我們有的是辦法,這就必須再學(xué)習(xí)新的指令.

如果此前我講的你基本都弄明白了,那你現(xiàn)在已經(jīng)抓住單片機(jī)入門(mén)的門(mén)把手了, 還需輕輕的推開(kāi).

當(dāng)你坐在家里吃著月餅,愜意地用電視遙控器選擇電視頻道,不停地用 +/- 鍵盤(pán)調(diào)節(jié)電視音量到合適的時(shí)候,你可曾想過(guò),此時(shí)嶗山也許正鉆在在溫度高達(dá)35攝氏度以上的樹(shù)叢里,忍耐蚊子螞蟻的叮咬,研究用什么樣的通信線更好地防止雨水侵蝕和動(dòng)物的啃咬。

也許你從沒(méi)有留意你按下的節(jié)目頻道、音量等這些 標(biāo)有 + / - 符號(hào)的鍵盤(pán)是怎樣工作控制大小的。

下面我們學(xué)習(xí)兩個(gè)新指令 incf 和 decf ,它們都是對(duì)某一個(gè)寄存器進(jìn)行增1 或減1 操作,例句中假如我們要操作的寄存器是 09H

movlw 02H '常數(shù)2進(jìn)入W

movwf 09H '把w 內(nèi)的數(shù)2 復(fù)制到09H 這個(gè)寄存器

'現(xiàn)在09H 寄存器內(nèi)存儲(chǔ)的數(shù)是2

incf 09H '寄存器09H內(nèi)存儲(chǔ)的數(shù) 增加1

'現(xiàn)在09H內(nèi)存儲(chǔ)的數(shù)變成3

decf 09H '寄存器09H內(nèi)存儲(chǔ)的數(shù) 減掉1

'現(xiàn)在09H內(nèi)存儲(chǔ)的數(shù)變成2

movlw 0FFH '常數(shù)255進(jìn)入W

movwf 09H '把w 內(nèi)的數(shù)255 復(fù)制到09H 這個(gè)寄存器

'現(xiàn)在09H 寄存器內(nèi)存儲(chǔ)的數(shù)是255

incf 09H '寄存器09H內(nèi)存儲(chǔ)的數(shù) 增加1

'現(xiàn)在09H內(nèi)存儲(chǔ)的數(shù)變成0

decf 09H '寄存器09H內(nèi)存儲(chǔ)的數(shù) 減掉1

'現(xiàn)在09H內(nèi)存儲(chǔ)的數(shù)又變成255

如果你事先定義好了地址為09H 的這個(gè)寄存器里存儲(chǔ)的數(shù)字大小,代表電視機(jī)節(jié)目頻道的話(huà),你會(huì)很喜歡這兩個(gè)指令的。并且當(dāng)節(jié)目頻道到達(dá)最大值255 或最小值0的時(shí)候無(wú)需擔(dān)心,寄存器在0時(shí)減1 會(huì)得255, 255狀態(tài)下增1 會(huì)得0

至于為什么會(huì)這樣,學(xué)過(guò)環(huán)形計(jì)數(shù)器的人不會(huì)感到奇怪的。你要是沒(méi)有學(xué)過(guò)計(jì)數(shù)器電路也不要緊,記住一個(gè)寄存器的最大存儲(chǔ)數(shù)值是255 = 0FFH 就可以了,加減法都會(huì)導(dǎo)致它“進(jìn)位”

當(dāng)然控制音量時(shí)這個(gè)程序不能使用,因?yàn)樗?和255之間變化,音量忽大忽小怎們行。

為解決這個(gè)問(wèn)題, 我們必須再學(xué)習(xí)兩條指令 incfsz 和 decfsz

它們與上兩個(gè)功能基本相同,不同的是: 寄存器增1 或減1操作以后,該指令會(huì)自動(dòng)判定寄存器內(nèi)的結(jié)果是否為零,如果不為零,繼續(xù)正常執(zhí)行該指令后面的語(yǔ)句. 但如果結(jié)果為零的話(huà),則程序會(huì) "跳一步" .繞過(guò)緊挨著它下面的一條指令,繼續(xù)執(zhí)行更下面的語(yǔ)句,舉例子說(shuō)明

假定我們操作的寄存器還是09H:

movlw 0FDH '常數(shù)253進(jìn)入W

movwf 09H '把w 內(nèi)的數(shù)253 復(fù)制到09H 這個(gè)寄存器

'現(xiàn)在09H 寄存器內(nèi)存儲(chǔ)的數(shù)是253

incfsz 09H '寄存器09H內(nèi)存儲(chǔ)的數(shù) 增加1,結(jié)果變成254 結(jié)果不等于0,故程序繼續(xù)執(zhí)行下一指令

nop '該句得到執(zhí)行(因?yàn)樯弦痪浼拇嫫?9H的計(jì)算結(jié)果不等于0)

incf 09H '寄存器09H內(nèi)存儲(chǔ)的數(shù) 增加1,結(jié)果是255

incfsz 09H '寄存器09H內(nèi)存儲(chǔ)的數(shù) 增加1,結(jié)果變成0

'因?yàn)榻Y(jié)果等于0,故程序要跳過(guò)下面的一句(不運(yùn)行下面的一句).

incf 09H '由于上一句的存在并結(jié)果為0,該句得不到執(zhí)行,被忽略

incf 09H '程序跳入這一句繼續(xù)運(yùn)行 寄存器09H內(nèi)存儲(chǔ)的數(shù) 增加1

nop '因此現(xiàn)在 09H寄存器存儲(chǔ)的數(shù)是1

nop '繼續(xù)運(yùn)行

.

.

.

.

.

思考題:設(shè)計(jì)一段程序代碼,當(dāng)用戶(hù)連續(xù)按下音量減小鍵后,判定音量寄存器09H的存儲(chǔ)音量數(shù)值,

防止該寄存器的值從0 變成255,以免震驚到用戶(hù)。

.

.

.

.

SMALL_SOUND: nop '標(biāo)號(hào)可以任意寫(xiě)的,此前用戶(hù)一旦按下音量減,就把程

' 序引導(dǎo)到這一句上來(lái)

decfsz 09H '寄存器09H內(nèi)存儲(chǔ)的數(shù) 減1,如果結(jié)果為0 就跳一步

goto OK '如果上一句結(jié)果不為0,執(zhí)行該句后,程序去了ok語(yǔ)句

movlw 01H '跳到這一步說(shuō)明寄存器結(jié)果是0

movwf 09 '強(qiáng)行把 09H內(nèi)的數(shù)值寫(xiě)成1,仍然是小音量,這樣音量不會(huì)被因?yàn)?減小而變成255

OK: nop '繼續(xù)運(yùn)行

.

.

思考題:利用decfsz 指令設(shè)計(jì)一段延時(shí)代碼,使得延時(shí)時(shí)間可以在10個(gè)機(jī)器周期到65535個(gè)機(jī)器周期之間,

可以通過(guò)程序任意控制

在這個(gè)例子中,設(shè)我們要控制的延時(shí)時(shí)間大約是24086個(gè)及其周期,用16進(jìn)制表是就是 5E16 H.

如果用到通用寄存器,請(qǐng)使用 0AH, 0BH

yanshi: movlw 5EH ' 常數(shù)5E進(jìn)W 標(biāo)號(hào)是延時(shí)

movwf 0BH , '0B寄存器數(shù)為5EH

movlw 16H '常數(shù)16進(jìn)W

movwf 0AH '0A寄存器數(shù)為16H

jixu: decfsz 0AH '0A寄存器內(nèi)的數(shù)減1,如果結(jié)果為0跳步

goto jixu '結(jié)果不為0,繼續(xù)

decfsz 0BH '0B寄存器內(nèi)的數(shù)減1,如果結(jié)果為0跳步

goto jixu '結(jié)果不為0,繼續(xù)

nop '延時(shí)完畢

.

.

.

.

你現(xiàn)在可以只用這幾個(gè)簡(jiǎn)單句子完成任意時(shí)間的延時(shí)程序了。

下面介紹單片機(jī)匯編語(yǔ)言里的一個(gè)概念 “子程序”

下面我介紹 “子程序”

我先打個(gè)比方,如果你做一頓飯,要做湯,炒菜,燉魚(yú),汆丸子, 奧,忘了還有炒小螃蟹(大螃蟹現(xiàn)在都叫人吃的逮不著了:))期間有一個(gè)動(dòng)作在我看來(lái)不斷的重復(fù),這個(gè)動(dòng)作就是放鹽 放鹽的過(guò)程描述是這樣的:

放鹽: 用一把小勺子深入鹽罐

舀出氯化鈉適量 。

把小勺子里的氯化鈉

均勻?yàn)⒃阱伬铩?/p>

完畢

如果我們把做飯定義為主任務(wù) 那么放鹽這個(gè)動(dòng)作就叫做 子任務(wù)。

這樣定義的一個(gè)好處就是描述主任務(wù)的時(shí)候比較方便,當(dāng)你用語(yǔ)言文字描述主任務(wù)的時(shí)候,無(wú)論哪一道菜,到了該加鹽的時(shí)候不必細(xì)說(shuō)用一把小勺子深入鹽罐...... 因?yàn)楹芏嗖硕加型瑯拥倪@個(gè)過(guò)程,所以,你用 “放鹽” 兩個(gè)字就可以了。但是在你使用 放鹽 這個(gè)詞之前或者之后,你應(yīng)該解釋一下放鹽 這個(gè)詞的具體過(guò)程是什么。

我們單片機(jī)的程序也是一樣的,如果你設(shè)計(jì)一個(gè)電視機(jī)的自動(dòng)搜索頻道的程序,程序要求電視機(jī)每搜索成功一個(gè)頻道,它面板上的發(fā)光二極管就眨一次眼睛,也就說(shuō),先熄滅一段時(shí)間然后再點(diǎn)亮。這樣就會(huì)遇到很多這樣的眨眼動(dòng)作,為了簡(jiǎn)化主程序我們可以把眨眼這樣一個(gè)過(guò)程定義為一段子程序,以后每次遇到需要眨眼的時(shí)候就調(diào)用一次子程序就可以了。

子程序的定義是這樣的

Zhayan: bcf GPIO,GP1 '管腳GP1輸出低電平關(guān)閉LED燈 做為子程序標(biāo)號(hào)是必須有的 標(biāo)號(hào)

' 就是子程序的名字

nop

nop

nop

nop

nop

... .

bsf GPIO,GP1 '管腳GP1輸出高電平點(diǎn)亮LED燈

nop

nop

nop

nop

...

return '這個(gè)命令表示子程序的結(jié)束 是必需的 否則這個(gè)子程序沒(méi)有結(jié)束

這樣,子程序就定義完了 如果想在程序的某個(gè)位置需要led燈熄滅以下(眨眼一次),只需在那個(gè)程序位置調(diào)用一下子程序就可以了。

調(diào)用的方法是用 call 命令。

主程序:

.... '這些點(diǎn)點(diǎn)表示主程序里的語(yǔ)句

....

......

...... '這個(gè)位置搜所成功一個(gè)臺(tái) 需要“眨眼”一次

call Zhayan

...... '繼續(xù)搜索下一個(gè)臺(tái)的命令行

......

......

......

...... '這個(gè)位置搜所成功一個(gè)臺(tái) 需要“眨眼”一次

call Zhayan

...... '繼續(xù)搜索下一個(gè)臺(tái)的命令行

......

......

...... '這個(gè)位置搜所成功一個(gè)臺(tái) 需要“眨眼”一次

call Zhayan

...... '繼續(xù)搜索下一個(gè)臺(tái)的命令行

......

疑問(wèn)1 我在一個(gè)主程序里固然可以調(diào)用另一個(gè)子程序,而我在一個(gè)子程序里能不能調(diào)用另一個(gè)子程序?

答 可以的,這叫子程序嵌套,甚至還可以在另一個(gè)子程序中再繼續(xù)調(diào)用別的子程序。

疑問(wèn)2 嗯,那繼續(xù)往下調(diào)用下去,有限制么?

答 有,這叫允許嵌套的層數(shù) 每個(gè)品牌 型號(hào)的單片機(jī)允許的嵌套層數(shù)都是有規(guī)定的 例如pic16f74 允許8層

pic12e519 允許兩層 也就是說(shuō)pic12e519的主程序里可以調(diào)用子程序,子程序里??梢栽僬{(diào)用子程序,到此為止不要再往下調(diào)用 了,否則程序報(bào)錯(cuò)或者超出你預(yù)計(jì)的結(jié)果。

疑問(wèn)3 在同一層程序空間里,例如在我的某個(gè)子程序之中,調(diào)用另一個(gè)子程序的次數(shù)有限制么?

回答 沒(méi)有限制,只要你的程序寄存器裝得下你的程序。

疑問(wèn)4 我聽(tīng)說(shuō)單片機(jī)在調(diào)用子程序以前,好像需要程序“堆棧”訪問(wèn)什么的,要進(jìn)行一些程序計(jì)數(shù)器的保存保護(hù),以保證子程序返回來(lái)得時(shí)候,程序能夠正確回到原來(lái)位置和環(huán)境。是這樣的么?

答 pic單片機(jī)不用管這些問(wèn)題,它是硬件自動(dòng)完成這些堆棧的事情,我們的指令里不用關(guān)心這些。盡管如此,中檔pic單片機(jī)的例如 pic16等系列,它們的程序存儲(chǔ)器地址是分頁(yè)的,盡量調(diào)用本頁(yè)的子程序,如果子程序不在本頁(yè),而是在另一個(gè)頁(yè)面里存放,你還是要告訴單片機(jī)你的子程序所在的頁(yè)面數(shù)據(jù)的,具體操作指令可以查相關(guān)指令說(shuō)明。我們的pic12c519的程序存儲(chǔ)器,沒(méi)有分頁(yè),不用關(guān)心這事。

繼續(xù)講

我們學(xué)習(xí)到這里,就已經(jīng)初窺門(mén)庭了,下一步還有一個(gè)重要的關(guān)口-------中斷

單片機(jī)的中斷,概念并不難以理解。只是要真正理解運(yùn)用編程處理一些實(shí)際中斷的例子,卻也不是很容易,甚至是單片機(jī)學(xué)習(xí)、入門(mén)的攔路虎。要想學(xué)會(huì)實(shí)際的中斷處理編程,也還需要清楚一些程序存儲(chǔ)器,程序結(jié)構(gòu),程序計(jì)數(shù)器,硬件堆棧,現(xiàn)場(chǎng)保護(hù)等這些個(gè)另雜碎概念。

因此,我們?cè)趯W(xué)習(xí)中斷以前,以后和學(xué)習(xí)中斷過(guò)程中,都有必要介紹回顧復(fù)習(xí)一些有關(guān)上述關(guān)鍵詞的概念和知識(shí),否則,盡管你學(xué)了中斷,用起來(lái)可還是不能得心應(yīng)手,以至于茫然。

我還是用比喻的方法介紹一下中斷的概念:

你的主程序任務(wù)是做一桌可口的飯菜,期間可能要多次調(diào)用子程序“撒鹽”。

盡管子程序下邊還有更小的子任務(wù),比如“計(jì)算食鹽的量”等過(guò)程,盡管這些子過(guò)程很復(fù)雜,但他們的出場(chǎng)時(shí)間和順序是可以預(yù)料的,是可以預(yù)先安排的。也就說(shuō)你肯定知道在什么時(shí)候放鹽。

有一類(lèi)子程序,他的出場(chǎng)時(shí)間是不確定的,突然的,處理他們的時(shí)間刻不容緩,必須趕緊的。我們稱(chēng)這一類(lèi)子程序?yàn)?中斷子程序。 也就是我們所說(shuō)的 中斷

你正在做菜的過(guò)程中,隔壁鄰居小孩突然敲門(mén)說(shuō) 他的二大爺在他房間里摔倒了 請(qǐng)你幫忙把二大爺扶起來(lái)。這是急迫的,必須處理的事務(wù)。

你肯定關(guān)掉爐子一溜煙跑出去幫忙,等回來(lái)以后再點(diǎn)著爐子繼續(xù)做菜。

這個(gè)事件的特點(diǎn)就是發(fā)生的時(shí)間你無(wú)法預(yù)先知道,而這個(gè)任務(wù)必須得停下當(dāng)前工作去處理,并且是刻不容緩。

從開(kāi)始關(guān)爐子到回來(lái)點(diǎn)著爐子的這段時(shí)間里以及你的救人行為,就叫做 “中斷子程序”。

在中斷子程序過(guò)程中,你關(guān)爐子的動(dòng)作,叫做“中斷現(xiàn)場(chǎng)保護(hù)” 點(diǎn)著爐子叫做“中斷現(xiàn)場(chǎng)恢復(fù)”中間走出去扶起隔壁二大爺?shù)交貋?lái) 叫做“中斷任務(wù)處理”

小孩子敲門(mén)就叫做“中斷請(qǐng)求”

這就是中斷的基本概念。

在單片機(jī)里,中斷的例子也是很多的。我舉一個(gè)你手里的手機(jī)的例子,你的GSM手機(jī)正工作在賦閑,屏幕上也就顯示個(gè)時(shí)間日期中國(guó)電信什么的,表面看沒(méi)有什么。其實(shí)它內(nèi)部的cpu高速運(yùn)行忙碌地工作在諸如聯(lián)絡(luò)無(wú)線網(wǎng)絡(luò),查詢(xún)是否有短消息發(fā)來(lái),計(jì)算當(dāng)前信號(hào)強(qiáng)度,時(shí)間等任務(wù)中。

你突然按下數(shù)字鍵“8”,此時(shí)內(nèi)部cpu必須停下它正在干的工作來(lái)應(yīng)付你,也就是清屏,顯示你按下的數(shù)字8,然后再回到它原來(lái)的任務(wù)接著運(yùn)行。(當(dāng)然,這個(gè)例子不一恰當(dāng),現(xiàn)在有操作系統(tǒng)Windows-ce windows-mobile的手機(jī)的工作機(jī)制遠(yuǎn)沒(méi)有如此的簡(jiǎn)單)

下面我們要接觸和復(fù)習(xí)一些另雜碎,學(xué)習(xí)中斷必須要弄明白單片機(jī)這些另雜碎,所以你還得忍耐他們一陣子。

再說(shuō)這不是教材,只是想為入門(mén)學(xué)習(xí)指劃個(gè)門(mén)徑,我的帖子里面有很多細(xì)節(jié)錯(cuò)誤,例如內(nèi)存頁(yè)面問(wèn)題,519也是分頁(yè)的。

但為了入門(mén),我們還是不先不要理會(huì)這些,等入門(mén)以后,還有很多細(xì)節(jié)需要搞明白,那時(shí)候就容易啦。

這不,我也是現(xiàn)學(xué)現(xiàn)賣(mài),在想寫(xiě)個(gè)具體中斷代碼的例子的時(shí)候,才現(xiàn)行的查閱了pic12f519 的數(shù)據(jù)手冊(cè),竟然沒(méi)有查到中斷方面的說(shuō)明,感情這款芯片沒(méi)有中斷的功能!不會(huì)是我英文水平低沒(méi)有看懂吧,又拿出來(lái)中文的,同樣的,程序存儲(chǔ)器里沒(méi)有中斷說(shuō)明,只有復(fù)位(復(fù)位也是單片機(jī)的概念) 。

總之,我們學(xué)習(xí)中斷代碼,這款芯片不適合我們啦。

怎么辦?只好換一款中檔的型號(hào):PIC16C74. 那位說(shuō)從低端芯片一下子到中端芯片跨度太大啦吧,能適應(yīng)嗎。我回答:肯定能!

高端芯片無(wú)非腿腳更多,片內(nèi)資源也多,但是原理和方法,和低端的沒(méi)有區(qū)別。我們只要掌握了單片機(jī)的使用操作方法入門(mén),慢說(shuō)中檔,就是高端芯片pic18、24、99999 系列,那也是一樣。我們?nèi)匀豢梢糟@進(jìn)去,出得來(lái)。

其實(shí)啊,所謂高端的語(yǔ)句,學(xué)起來(lái)更簡(jiǎn)單和使用起來(lái)更方便。要實(shí)現(xiàn)同樣功能,如果限定僅使用低端35條,反而會(huì)比較羅索。

下面以 PIC16C74 這款芯片為例,仍然不出35條基本指令,寫(xiě)出一個(gè)完整的中斷代碼的例子,注意這個(gè)例子程序的總體結(jié)構(gòu)。題目要求:

1、當(dāng)一個(gè)鍵盤(pán)按動(dòng)一下后,中斷主程序,改變某管腳上的一只LED燈的狀態(tài),如果再次按動(dòng),再次改變。

2、主程序?qū)嶋H上和我們的中斷任務(wù)處理沒(méi)有關(guān)系,我們可以隨便寫(xiě)個(gè)任務(wù),例如主任務(wù)程序是計(jì)算:123 + 45 = ?

在這個(gè)例子里,計(jì)算123 + 45 = ?相當(dāng)于我們?cè)谧霾?,突然有人按?dòng)按鍵,相當(dāng)于小孩子敲門(mén)請(qǐng)求中斷,那么改變(點(diǎn)亮或者熄滅)某管腳上的一只LED燈的狀態(tài),就是我們刻不容緩的拯救行動(dòng)。

為了理解中斷代碼,我們先看看硬件設(shè)計(jì),下面是這個(gè)例子的電路圖。(缺)

如圖:11、12 管腳接電源和地線,13、14管腳接振蕩器, 管腳 1 是復(fù)位管腳,只要它是高電平,程序就運(yùn)行,只要是低電平,程序就馬上停止,并回到程序特定的開(kāi)始位置,也叫做“復(fù)位”

我們真正用到的是 管腳40 名字叫做 RB7 接一個(gè)鍵盤(pán)??梢钥闯?,該腳平時(shí)為高電平,一旦有人按下鍵盤(pán),就會(huì)變成低電平,從而導(dǎo)致主程序發(fā)生中斷。它是作為輸入 I 使用。

管教27 控制一個(gè)發(fā)光二極管,輸出高電平點(diǎn)亮。 它是作為輸出管腳.

剩下的那些管腳,先不管,實(shí)際使用的時(shí)候懸空好了。

根據(jù)我們以前所學(xué),主程序和子程序已然明了。在以前的程序中,凡是涉及專(zhuān)用寄存器如 GPIO 或者通用寄存器如的時(shí)候,

我都是在程序注釋里說(shuō)明該符號(hào)如GPIO 、020H,是一個(gè)寄存器的地址。這里有一個(gè)差別,特殊寄存器都是用字符串表示,而通用寄存器使用它的地址數(shù)表示。這樣做主要是為了便于理解寄存器的本質(zhì)和使用。

事實(shí)上,通用寄存器也是可以用字符串來(lái)表示的,并且在實(shí)用的程序里往往是用字符串表示通用寄存器,而不是直接用它的地址,因?yàn)橛米址苊鞔_這個(gè)通用寄存的用途性質(zhì)。僅用地址數(shù)是允許的,但是通用寄存器一旦多起來(lái),連程序作者自己也搞不清楚哪一個(gè)是干什么用的了。

為了便于程序理解,閱讀,容易編寫(xiě)。允許程序作者給通用寄存器 例如020H 起用一個(gè)漂亮直接的字符串名字。 我們來(lái)學(xué)習(xí)一個(gè)嶄新的語(yǔ)句 EQU

我們看幾個(gè)例子:

BeijiaShu EQU 020H '定義字符串 BeijiaShu 的值是數(shù)字 020H

'此前或者此后的程序代碼中, 只要遇到 BeijiaShu 就可以用數(shù)字 020H取代

'盡管BeijiaShu也可以寫(xiě)在一行的最左頂格,但是別用冒號(hào),它不是程序標(biāo)號(hào)

有了上述的語(yǔ)句,下列語(yǔ)句

MOVLW 123H

MOVWF 020H

就完全可以寫(xiě)成

MOVLW 123H

MOVWF BeijiaShu

程序中下列兩組語(yǔ)句是等價(jià)的,相同的意義。這樣,所有的通用寄存器都可以有自己的名號(hào)可以使用了。

新語(yǔ)句中的 EQU 不屬于35條指令里面的,因?yàn)樗趩纹瑱C(jī)運(yùn)行的時(shí)候,不能被執(zhí)行,也不會(huì)占用單片機(jī)里的程序存儲(chǔ)空間。

僅僅是為了方便我們?nèi)祟?lèi)閱讀、編寫(xiě)源程序程序而起的代號(hào),事實(shí)上,有了EQU指令,家用電腦在把我們編寫(xiě)的源程序“翻譯”成單片機(jī)能夠執(zhí)行的機(jī)器碼的時(shí)候,還徒然增加了編譯的工作量,不利于提高編譯速度。

因此,它也不是十分必須的語(yǔ)句,你如果記憶力好,對(duì)每個(gè)通用寄存器的地址你自己設(shè)計(jì)成什么用途了,都能夠記住,完全可以不必多此一舉的使用什么符號(hào)常數(shù)。話(huà)又說(shuō)回來(lái),誰(shuí)有那么多多余的精力去記憶枯燥的地址數(shù)據(jù)呢。

象這樣不能被單片機(jī)執(zhí)行,僅僅能幫助我們編寫(xiě)閱讀源程序方便、或者僅僅有助于輔助家用電腦編譯源程序而設(shè)立的指令,叫做單片機(jī)的“偽指令”

從理論上來(lái)說(shuō),幾乎所有偽指令都不是必須的,都是可有可無(wú)的,都能夠用我們的35條指令就可以完成任務(wù)的。只是,那樣的話(huà)我們的35條使用起來(lái)比較麻煩和不太方便甚至還需要增加額外的計(jì)算我們的程序所存在的地址等等工作量。

有了這些個(gè)偽指令,我們編寫(xiě)程序就會(huì)省卻許多的麻煩,例如:

此前的例子中用到了許多行 NOP空操作指令,假如某段代碼需要連續(xù)500行NOP語(yǔ)句,即便拷貝也是個(gè)大麻煩,

那么有一款或者兩款偽指令,只需要說(shuō)明你的行編輯重復(fù)次數(shù)以及行編輯重復(fù)的代碼是NOP 就足夠了,

編輯上看上去也就是幾行的樣子,實(shí)際家用電腦在編譯生成單片機(jī)的實(shí)際執(zhí)行碼的時(shí)候,會(huì)自動(dòng)添加500行NOP指令,單片機(jī)里面的程序存儲(chǔ)空間,也是相應(yīng)的增加等量500行代碼的空間,那是一點(diǎn)也不能節(jié)約出來(lái)的。

一句話(huà):偽指令和我們此前講的 單引號(hào) ’ 后面的程序注釋類(lèi)似,共同點(diǎn)是都不被單片機(jī)執(zhí)行,也不會(huì)占用單片機(jī)內(nèi)部的程序存儲(chǔ)資源,都是幫助人們閱讀和編寫(xiě)的方便。不同點(diǎn)是:偽指令要干預(yù)家用電腦對(duì)源程序的編譯,而單引號(hào)則不會(huì)。

由此看,初學(xué)入門(mén)不宜在偽指令上徘徊,老手則是善于運(yùn)用偽指令圖個(gè)編程快捷簡(jiǎn)便。

下面我們編寫(xiě)我們的中斷例子,并且作為文本文件來(lái)處理看待。匯編語(yǔ)言主程序文件的擴(kuò)展名稱(chēng),是匯編系統(tǒng)已經(jīng)規(guī)定好了的,必須使用 *.ASM

例如:可以為: Shan_LED.ASM

用記事本新建一個(gè)文件,文件名稱(chēng)請(qǐng)使用例子 Shan_LED.ASM 文件內(nèi)容如下

BeijiaShu EQU 020H '被加數(shù)

JiaShu EQU 021H '加數(shù)

HE1 EQU 022H '第一算式的和

HE2 EQU 023H '第二算式的和

盡管如此,初學(xué)者,有四個(gè)偽指令需要認(rèn)識(shí),一個(gè)是EQU 已經(jīng)認(rèn)識(shí)過(guò)了。如果需要的 EQU 的行很多,例如我們的主程序中要用到 被加數(shù)、加數(shù)、計(jì)算結(jié)果的和 以及第一個(gè)算式的計(jì)算結(jié)果寄存 以及第二個(gè)算式的計(jì)算結(jié)果暫存:

那么,下一步,就是要核計(jì)整個(gè)程序的結(jié)構(gòu),如果從程序的用途屬性,程序存儲(chǔ)區(qū)域等角度來(lái)看,存儲(chǔ)來(lái)區(qū)分一個(gè)典型的程序結(jié)構(gòu)例子要包含主程序,子程序,中斷子程序,和偽指令說(shuō)明程序。

以往教材,在教導(dǎo)程序結(jié)構(gòu)的時(shí)候不是這么分類(lèi),而是大談特談什么循環(huán)結(jié)構(gòu),分支結(jié)構(gòu),遞歸結(jié)構(gòu),函數(shù)調(diào)用等等,先把學(xué)生搞暈再說(shuō),我認(rèn)為那些屬于程序技巧,是用,是末,理應(yīng)排在以后的技巧升級(jí)后去研究。按照上述分類(lèi)才是程序之本體,是入門(mén)的必然門(mén)徑。

有四個(gè)偽指令需要認(rèn)識(shí)的,我們已經(jīng)學(xué)會(huì)一個(gè) EQU,另外3個(gè)隨著我們講解這個(gè)中斷例子添加。再看看 ORG 偽指令

ORG 00H '這是個(gè)偽指令,強(qiáng)調(diào)以下的源程序代碼在存儲(chǔ)到單片機(jī)的時(shí)候,

'被存儲(chǔ)在單片機(jī)程序存儲(chǔ)器的 00H位置,也就是開(kāi)始的位置

NOP '這個(gè)才是真實(shí)的第一條可執(zhí)行單片機(jī)指令,它被存儲(chǔ)在程序存儲(chǔ)器的 0000H位置

NOP '該指令沒(méi)有用ORG指令規(guī)定位置,只好按照默認(rèn)的順序 被存儲(chǔ)在 0001H

GOTO MAIN '順序存儲(chǔ)位置 002H 無(wú)條件挑轉(zhuǎn)到標(biāo)號(hào) MAIN的地方。

'0003H這個(gè)地方?jīng)]有任何語(yǔ)句,是個(gè)空洞,不被執(zhí)行

'空洞在家用電腦編譯器編譯的時(shí)候,實(shí)際上也會(huì)被給出一個(gè)特定的數(shù)據(jù)存儲(chǔ)到0003H

'這個(gè)特定數(shù)據(jù)是什么是無(wú)所謂的,不同廠家的編譯器會(huì)給不同的特定數(shù)

'特定數(shù)例如:NOP MOVLW等一般為可執(zhí)行數(shù)據(jù),以免萬(wàn)一單片機(jī)誤入空洞,也能工作,不出錯(cuò)

ORG 04H

GOTO INTSRV '由于上鄰的ORG 04H的存在,該句會(huì)被存儲(chǔ)到程序空間 0004H , 無(wú)條件轉(zhuǎn)向標(biāo)號(hào) INTSRV

NOP '按照默認(rèn)順序編譯存儲(chǔ)到 0005H

NOP '按照默認(rèn)順序編譯存儲(chǔ) 直到遇到下一個(gè)ORG命令,才會(huì)打破順序

學(xué)會(huì)ORG命令以后,就可以把整個(gè)源程序安排到單片機(jī)的程序存儲(chǔ)器位置上,我們習(xí)慣叫做程序存儲(chǔ)器地址。PIC12F509的片內(nèi)程序存儲(chǔ)器只有1024個(gè)單元行,地址從 0000H ---- 03FF H 而PIC16C74的片內(nèi)程序存儲(chǔ)器有4096個(gè)單元行。

整個(gè)程序存儲(chǔ)器 有幾個(gè)位置(地址)需要特別介紹,那就是復(fù)位地址0000H 和 中斷入口地址 0004H。

0000H是 PIC單片機(jī)程序存儲(chǔ)器的第一行,通電后首先執(zhí)行這一行的指令。等于是單片機(jī)工作的開(kāi)始位置。

通電后后也許需要單片機(jī)多次重新開(kāi)始工作,例如一臺(tái)電子稱(chēng)通電以后,可能需要稱(chēng)若干次物品的重量,那么,每換一次物品,單片機(jī)就需要重新回到 0000 H這個(gè)指令上來(lái),開(kāi)始新一輪的測(cè)量。只要單片機(jī)的指令,回到了 0000 H, 我們就成為單片機(jī)復(fù)位。

中斷入口地址是怎么回事情呢?

原來(lái)啊,我們的主程序和調(diào)用的子程序已經(jīng)很完美了,如果小孩子不敲門(mén),或者在本例子里 那個(gè)鍵盤(pán)永遠(yuǎn)也不按下的話(huà),是不會(huì)發(fā)生中斷的,我們的程序也就不會(huì)跳出我們事先設(shè)計(jì)的主程序和子程序那些事情。

可是,一旦發(fā)生了按鍵事件,此時(shí)程序會(huì)暫時(shí)記住當(dāng)前位置,轉(zhuǎn)而去進(jìn)行中斷服務(wù),去哪里服務(wù)呢?就是強(qiáng)行把程序指向 0004H 這個(gè)特殊地址,然后從0004 H開(kāi)始進(jìn)行中斷的服務(wù)處理,因此我們?cè)O(shè)計(jì)的中斷撒鹽 或者開(kāi)關(guān)LED燈的一些程序,就必須從0004H這個(gè)位置開(kāi)始。因此 0004H就叫做中斷入口 或者叫中斷入口地址。

不同型號(hào)的單片機(jī)中斷入口地址不一定都是 0004H, 就我們的例子PIC16C74是這樣的,并且就這一個(gè)入口,因此中斷程序較簡(jiǎn)單,而別的型號(hào)則不一定,需要查手冊(cè),如 PIC18F452就有兩個(gè)中斷入口,地址0008 H 以及 0018H

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶(hù)希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱(chēng),數(shù)字世界的話(huà)語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱(chēng)"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉