通俗易懂講PIC單片機:從一竅不通到入門(mén)進(jìn)步
單片機入門(mén)不難------談PIC系列(轉自礦石收音機論壇---嶗山)十年前的老帖子,講得通俗易懂,分享之。
本文引用地址:http://dyxdggzs.com/article/201803/376687.htm請看圖1
這個(gè)8條腿的小螃蟹就是我們的第一頓飯,只要把它吃下去,以后的大餐就好辦了。
第1、8條腿接電源 +5V 和 地線(xiàn)。頭兩條腿是螃蟹鉗子,好吃的很。 現在剩下了 6 條腿
第2、3條腿 使用時(shí)外接一個(gè)晶振的東西 我們接一個(gè) 4 MHz的。
第4條腿是復位腳,是一個(gè)信號輸入腳。單片機正常運行時(shí)接高電平。當有一個(gè)低電平脈沖輸入到這個(gè)腳時(shí)單片機就復位。所謂復位就是單片機內部所有的工作部件統統回到規定的狀態(tài),程序也復位到頭一句上開(kāi)始逐條運行。例如,你設計的一個(gè)報警鎖定的 LED紅燈亮后,當需要解除報警時(shí),用一個(gè)按鈕給這個(gè)腳瞬時(shí)接地一下,相當于給它一個(gè)夫脈沖,系統就復位了,led燈就熄滅了,程序從頭開(kāi)始。
以上5個(gè)腳,幾乎所有單片機都有,包括世界上最復雜的,和世界比較簡(jiǎn)單的單片機-----PIC12CE519
輪到底幾條腿啦?奧是第5條腿,這條叫單片機的 I/O 腳。就是輸入輸出腳。你可通過(guò)程序動(dòng)態(tài)地控制它作為輸入或輸出,作為輸出時(shí)可以程序控制它的輸出電平為高1或低0。所以,他的工作狀態(tài)有四種:輸入0,輸入1,輸出0,輸出1
剩下的兩條腿和第5腳功能一個(gè)樣。
上邊我們已經(jīng)把8條腿消化掉了,其實(shí)我們要弄明白的也就3只腿,我們再簡(jiǎn)單一些,先整明白兩條腿,即GP0,GP1.這兩條腿低級一點(diǎn)的用法,可以控制繼電器,LED燈,高級一些的用法可以進(jìn)行I2C總線(xiàn),RS232總線(xiàn)的通信,作為擴展輸入可以模擬出來(lái)A/D轉換器(6--7bit),可以測量一個(gè)電阻的粗略值。作為輸出也可以直接推動(dòng)揚聲器奏出音樂(lè )。這是后話(huà)暫且不提。
現在要控制使用這兩只腿,我這個(gè)三腳貓功夫的說(shuō)書(shū)的不得不講一下軟件了,要想講明白軟件又不得不涉及到單片機的內部結構。那位說(shuō)啦,你可別提這軟件和結構了,以前俺就是讓它們打敗的,現在聽(tīng)到這個(gè)心里就打鼓。嘿嘿,不要緊,果真如你所說(shuō),那你就不妨跟著(zhù)我再失敗一次, 反正嗎多一次失敗又不納稅,嘿嘿。不過(guò)你也要有思想準備,徹底弄明白是個(gè)漸進(jìn)的過(guò)程。
要說(shuō)這程序和單片機內部結構,還真是老大難,不過(guò)蟹黃蟹肉都可都在里面。我現在要是給你說(shuō)PIC單片機是哈佛結構的,51系列是馮-諾伊曼結構的,恐怕你要立馬扎走人了。所以我得用點(diǎn)心思不讓你溜號。
好在PIC系列的制造商(microchip 微芯公司 美國)理解我等苦衷,全部只有35條指令,而且有一些指令我們一般很少使用,常用的也就十幾句,用的時(shí)候查手冊,無(wú)需記憶。就算我們兩天學(xué)習一句,也就兩三個(gè)月時(shí)間,總比到老了還怕它們強啊。廢話(huà)少說(shuō)先看下面的兩個(gè)例語(yǔ):
my_name006: movlw 02h '常數2進(jìn)入w
movwf GPIO 'W 的數進(jìn)入 寄存器GPIO
這就是我們編的程序里的兩個(gè)句子,也叫源程序。有以下特點(diǎn)
每行只能寫(xiě)一句話(huà)
每句話(huà)由四部分組成:
標號: 操作指令 操作數 '程序注釋
下面我結合例子把這四部分解釋一下。
第一部分 my_name006: 叫做標號,它是由字母或數字組成,由冒號結束。標號可有可無(wú),比如第二句就沒(méi)有標號。
第二部分movlw 叫做操作指令。它是必須有的,不能省略。PIC 系列的單片機共有 35 條指令。
第三部分02h 叫做操作數。有的指令沒(méi)有操作數或者操作數是默認的,也不用寫(xiě)。
第四部分是程序注釋?zhuān)仨氁詥我栭_(kāi)頭,主要作用是提醒和備忘。注釋也是可有可無(wú)。
第二個(gè)例句中,省略了標號,當然注釋也可以省略。他的指令是movwf, 操作數是GPIO。操作數不一定是數字,也可能是一個(gè)由字母組成的字符串。
知道了語(yǔ)句格式以后,我們下面就學(xué)習一些常用語(yǔ)句。我們先把這兩個(gè)例句弄清楚。
這兩句話(huà)的作用是把 2 這個(gè)常數寫(xiě)入到 GPIO 這個(gè)寄存器里。
單片機里有一些部件需要我們使用和操作,都是通過(guò)讀寫(xiě)寄存器來(lái)實(shí)現的。每個(gè)部件都對應有操控它的寄存器,例如我們要控制使用的管腳GP0,GP1 這兩個(gè)管腳對應的寄存器就叫做GPIO。對GPIO寄存器讀操作,實(shí)際等效察看管腳電平的高低;對GPIO寄存器相應的位寫(xiě)1操作,實(shí)際等校讓管腳輸出高電平。寫(xiě)0,輸出低電平。
每個(gè)寄存器可以?xún)Υ嬉粋€(gè)八位的二進(jìn)制數。這八個(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è)位對應一個(gè)管腳的電平,例如當GPIO寄存器的D0位等于1時(shí)表示管腳GP0 的電平是高電平。D0位等于0時(shí)表示管腳GP0 的電平是低電平。常數2的八位二進(jìn)制表示是“00000010” 所以,GPIO寄存器存放的8位2進(jìn)制數的每個(gè)位的值以及管腳電平是:
D7對 應于內部總線(xiàn)管腳的電平 D7=0 內部總線(xiàn)管腳輸出低電平
D6對應于內部總線(xiàn)管腳的電平 D6=0 內部總線(xiàn)管腳輸出低電平
D5對應于GP5 管腳的電平 D5=0 GP5 管腳輸出低電平
D4對應于GP4 管腳的電平 D4=0 GP4 管腳輸出低電平
D3對應于GP3 管腳的電平 D3=0 GP3 管腳輸出低電平
D2對應于GP2 管腳的電平 D2=0 GP2 管腳輸出低電平
D1對應于GP1 管腳的電平 D1=1 GP1 管腳輸出低電平
D0對應于GP0 管腳的電平 D0=0 GP0 管腳輸出低電平
GP0---GP5管腳我們可以從上一講的圖1硬件中查出所對應的管腳。d7 d6 對應的內部時(shí)鐘和數據總線(xiàn)我們現在暫且不要管它。以后本事大了在調教它們。在我們的例句中,向GPIO寄存器寫(xiě)入了2,常數2的八位二進(jìn)制表示是“00000010” 因此如果此時(shí)GP0, Gp1等都已經(jīng)被定義成輸出的話(huà),那么GP1輸出高電平(接LED燈亮),GP0 輸出低電平(所接led燈熄) 。
截止到現在,你已經(jīng)學(xué)會(huì )如何控制管腳的電平高低了。盡管還有一些疑問(wèn),比如怎樣定義管腳為輸出腳(以后會(huì )說(shuō)),我得說(shuō)如果事先gp1,gp0這兩個(gè)管腳處于輸入狀態(tài),這兩個(gè)例句無(wú)效,是控制不了電平的。
無(wú)論如何,這一會(huì )兒,你就學(xué)會(huì )了兩個(gè)指令,35條我看也沒(méi)啥難的。
'------------------------------------------------------------------------------
再加深一下對寄存器的認識:
要把一個(gè)常數存儲到,或者說(shuō)寫(xiě)到一個(gè)寄存器中,僅用一條指令是辦不到的,必須通過(guò)一個(gè)特殊的寄存器W,把數據倒過(guò)去. 這就應該使用到兩個(gè)語(yǔ)句。
movlw 02H 指令的意思是把一個(gè)常數存入特殊寄存器W, 這個(gè)常數是3,后面的H是表示十六進(jìn)制
movwf GPIO 指令的意思是把特殊寄存器W的數值存入寄存器. 這個(gè)寄存器的名稱(chēng)是 GPIO
這里涉及到兩個(gè)概念,常數和寄存器.
常數好說(shuō),比如說(shuō)十進(jìn)制數 35, 26 但要注意,在單片機系統里我們一般不用十進(jìn)制,而使用十六進(jìn)制. 有關(guān)數制轉換方面的知識,是計算機的基礎,必須會(huì )熟練地在二進(jìn)制、十六進(jìn)制、十進(jìn)制之間轉換,我就不羅索了.
寄存器也叫單片機的內存。
一個(gè)寄存器可以存儲的數值范圍是0--255,用十六進(jìn)制表示就是 0---FFH.用二進(jìn)制表示就是00000000----11111111.
以后要養成習慣用十六進(jìn)制表示數.
那么,一個(gè)單片機里有多少個(gè)這樣的寄存器哩,pic12ce512里面有1024個(gè)這樣的寄存器可以供你使用,為了使用方便生產(chǎn)商已經(jīng)給它們編上了號碼,第一號碼是000H,往下依照次序為 001H,002H........3FFH.(怎么樣,開(kāi)始用十六進(jìn)制說(shuō)事了吧,如果你不熟悉熟制轉換趕緊補課來(lái)得及)
有了編號就像我們居住的房間有了房間號碼,使用就方便的多了.房間號碼在郵政行業(yè)叫地址,因此我們稱(chēng)這些號碼叫做寄存器地址,或稱(chēng)地址數 例如 名稱(chēng)為 GPIO 的寄存器,他的地址,或地址數是 06H 。所以我們的兩個(gè)例句完全等同于:
my_name006: movlw 02h '常數2進(jìn)入w
movwf 06H 'W 的數進(jìn)入 寄存器GPIO
'-----------------------------------------
有兩個(gè)寄存器比較特殊,它們沒(méi)有地址,一個(gè)名字叫做 W, 另一個(gè)叫做 TRIS. 所以他們兩個(gè)在存儲數據的時(shí)候比較快,一個(gè)指令就可以解決問(wèn)題,例如: movlw 03H 一條指令就把常數3寫(xiě)入到W寄存器了。關(guān)于TRIS寄存器,我們以后用到它再說(shuō).
除了他們兩個(gè)以外的其他所有寄存器,在寫(xiě)入數據時(shí)一般都要用兩條指令進(jìn)行。
今天就扯到這里,雖然只有兩個(gè)指令,但主要目的是要同學(xué)們接觸一下指令,建立寄存器的概念以及他們同硬件部件的聯(lián)系。增強學(xué)習的信心。能有這些體會(huì ),這一節就算過(guò)關(guān)了。
隨著(zhù)以后的深入,你會(huì )發(fā)現小小單片機里面是一個(gè)大世界,興趣也由此而生。
我們上一次講的兩個(gè)指令是是如何控制管腳電平的高低。前提是所有管腳已經(jīng)被定義成輸出了(OUT)如果被定義成了輸入,則上次的指令雖然也能運行,但運行后絲毫不能改變管腳電平高低,因為此時(shí)管腳是輸入狀態(tài),電平取決于外部輸入,指令無(wú)法改變。
在PIC單片機系列中,改變I/O口的輸入輸出依靠寫(xiě)入寄存器TRIS的值,相應位寫(xiě)0,表示對應管腳被定義成了輸出,寫(xiě)1,就是輸入。
現在假如預把GP1、GP2管腳定義成輸出,其他腳全是輸入。那就應該向TRIS 寄存器寫(xiě)入二進(jìn)制數 11111001,換算成十六進(jìn)制就是
F9H.
依照以前我們學(xué)到的知識,在PIC系列單片機里,本來(lái)應該用下列的語(yǔ)句來(lái)完成我們的設定:
movlw 0F9H '常數進(jìn)W 以字母開(kāi)頭的常數前面必須加0
movwf TRISA '把W內的數復制到TRIS
實(shí)際上PIC系列的單片機也都是這么寫(xiě)的,后面加的A,表示第一個(gè)8位的口(有的單片機不僅一個(gè)口,還有好幾個(gè)8位的I/O口如TRISB TRISC TRISD等等) .
但是,記住了, PIC12系列的單片機必須改寫(xiě)成為:
movlw 0F9H '常數進(jìn)W 以字母開(kāi)頭的常數前面必須加0
tris GPIO '把W內的數復制到TRIS 以后凡見(jiàn)到這個(gè)指令一律理解成 movwf TRISA
寫(xiě)法不同,意思是一樣的. 這樣你就又學(xué)了一個(gè)指令TRIS,不過(guò)這個(gè)指令的實(shí)質(zhì)還是你曾經(jīng)學(xué)過(guò)的movwf 只是寫(xiě)法不同罷了.
在PIC12系列里TRIS作為指令, 在其他系列(PIC161718)里把 TRIS 作為普通寄存器看待.
因為我們現在講的就是PIC12CE519,所以我們暫時(shí)用
tris GPIO
這個(gè)格式,等以后進(jìn)入PIC16C877 我們再寫(xiě)成 movwf TRISA , 至于理解按照后者進(jìn)行.
'-----------
如果我們要控制GP1 GP2管腳的輸出電平, 其他管腳作為輸入.并且讓GP1輸出低電平,GP2輸出高電平.完整的程序如下:
movlw 0F9H '常數進(jìn)W
tris GPIO '把W內的數復制到TRIS ,GP1 GP2為輸出,其他為輸入
'此行無(wú)命令,起到的作用是容易讀懂程序
movlw 04H '常數4的二進(jìn)制是 00000100 ,GP1=0 GP2=1
movwf GPIO 'W內的數進(jìn)GPIO 輸出生效,原來(lái)定義成輸入的腳的電平,不會(huì )受該句影響
上面已經(jīng)學(xué)會(huì )了三條指令,但是8位寄存器的概念概念一定要建立起來(lái),程序通過(guò)寫(xiě)入寄存器不同的數據
控制管腳作為輸入使用還是輸出使用,作為輸出時(shí)是輸出高電平還是低電平。
這樣的操作又一個(gè)特點(diǎn),就是每次寫(xiě)入數據,同時(shí)控制的往往不是一個(gè)管腳,而是好幾個(gè)個(gè).最多一次可
以控制8個(gè)管腳.在單片機里往往每8個(gè)腳叫做一個(gè)口,如口A(yíng), 口B,用英文表示就是GPIO PORTA PORTB PORTC 等.
更多的情況是:某個(gè)口內的某一個(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è)管腳的電平就方便多了,你的編程效率大大提高啊.
記?。篜IC所有單片機所有寄存器都是可以位操作的,這在51的單片機上是不能完全實(shí)現的.
不僅如此,PIC所有單片機所有管腳的單腿驅動(dòng)輸出電流可以高達 25mA,所以如果你驅動(dòng)一個(gè) 5到10mA電流的LED發(fā)光二極管,根本不用加三極管,串個(gè)電阻直接掛在單片機上就得了,這在51的單片機上也是不能實(shí)現的,要加驅動(dòng)三極管或驅動(dòng)芯片.
怎么樣,學(xué)PIC有好處吧. 也別急,好處還有那,且聽(tīng)我慢慢地白話(huà)。
一不小心,你已經(jīng)會(huì ) 5 個(gè)指令了,還有30個(gè),加油啊。
繼續
單片機的大部分指令,或者說(shuō)單片機所做的大部分工作,多數在寫(xiě)入或讀出寄存器。關(guān)于寄存器的初步概念我想我們已經(jīng)建立起來(lái)了,它是一個(gè)能夠存儲8位二進(jìn)制數據(最大255 = 0FFH) 的單元 每個(gè)單元都有它的編號,我們叫做它的地址,或地址編碼. 地址編碼也是十六進(jìn)制的. 另外寄存器里的數據掉電就會(huì )丟失。
寄存器的英文是RAM 也要記住.
PIC12CE519 里面共有有48個(gè)寄存器供我們操作使用, 它們每一個(gè)都有固定的地址編碼。
地址編碼并不是連續的號碼,而是分成了兩段:
第一段: 從00H 開(kāi)始, 依次是01H, 02H, 03H ....0AH, 0BH......到1FH 結束. 計32個(gè)寄存器
第二段: 從30H 開(kāi)始, 依次是31H, 32H, ......................到3FH 結束 計16個(gè)寄存器
這種地址不連續編號, 而是要跳過(guò)去一段的做法, 對于我們新手來(lái)說(shuō)很是不習慣. 為了讓我們容易入門(mén), 我們暫時(shí)先不管第二段RAM, 只當它不存在, 所有程序我們只涉及到第一段連續的ram 地址. 等我們熟練的掌握好了ram 的使用,再涉及第二段地址的RAM, 那時(shí),你就會(huì )理解單片機設計者把它們分成兩段的苦心了.
為了規范,我們今后一律把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)由系統分配好了.例如 地址為06H 的名稱(chēng)就做GPIO寄存器的功能,是它的每個(gè)位,都對應到一個(gè)I/O腳的電平.
另一類(lèi) 是通用寄存器,你可以理解成它的功能系統沒(méi)有事先預定,而是由你在編程序的時(shí)候隨機使用.
pic12ce519 的專(zhuān)用寄存器有 7 個(gè), 位置在我們第00葉面的最前面. 這7個(gè)專(zhuān)用寄存器的地址編碼是: 00H,01H, 02H, ----06 H
剩下的所有寄存器包括所有第01頁(yè)面, 全部都是通用寄存器.
例子: 在兩個(gè)通用寄存器 09H, 0AH 內, 寫(xiě)入常數 FC H
movlw 0FCH '常數進(jìn)W
movwf 9H '復制W內的數到通用寄存器09H
movwf 0AH '復制W內的數到通用寄存器0AH 由于此時(shí)W內并沒(méi)有改變,W不用再進(jìn)常數.
'----------------------------------------------
下面是PIC12CE519的 寄存器ram的地址地圖:
圖最上端的 00 01 表示的是頁(yè)面號碼,或叫頁(yè)面地址。
左側 從00 --- 1FH 是00頁(yè)面, 右側是01頁(yè)面。
從00H 到 06H 都已經(jīng)起好了名稱(chēng) ,它們是專(zhuān)用寄存器,用處各有不同。以后我們會(huì )逐個(gè)介紹它們
剩下的都是通用寄存器 或者叫普通寄存器 General Purpose Registers 意思是一般用途的寄存器
地址從20H 到 2FH 也不是“空洞”,也不是不能訪(fǎng)問(wèn),只是讀寫(xiě)它們的時(shí)候等于讀寫(xiě)它們左側對應的00頁(yè)面。這一點(diǎn)我們可能有些迷惑,弄不明白也沒(méi)有關(guān)系,以后隨著(zhù)程序理解的深入,會(huì )搞清楚的。
內存圖譜,不要求記下來(lái),但是應該有個(gè)大體印象,用的時(shí)候會(huì )察看就可以了。等編程時(shí)間一長(cháng)
就那么幾個(gè)字節,自然就記住了。
所謂字節是衡量二進(jìn)制數據長(cháng)度的一個(gè)單位。一個(gè)寄存器剛好能記住一個(gè)字節的數據。如果你要存儲的數據比較大超過(guò)了255,那就要占2個(gè)存儲器甚至更多。描述的時(shí)候通常我們不說(shuō)這個(gè)數值占了多少個(gè)寄存器,而是說(shuō)這個(gè)數據是幾個(gè)字節的。
字節的英文是byte 一個(gè)二進(jìn)制數的一位,叫比特 英文bit 1 byte 包含 8 bit
繼續
下面我們學(xué)習一條新指令,叫做空操作指令
nop '什么事情也不做,但執行這個(gè)指令也要消耗掉一點(diǎn)時(shí)間。它沒(méi)有操作數。
'不要理解成程序停了,實(shí)際上程序仍在正常運行。執行一連串的空操作指令,單片機
'白耗費時(shí)間,什么活也不干,往往用于延時(shí)
如果你需要一個(gè)很短時(shí)間的延時(shí),可以采用一連串的空操作。注意每個(gè) nop 也是占一行, 例如:
movlw 0F9H '常數進(jìn)W
tris GPIO '把W內的數復制到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
...
運行的效果是接在管腳GP1上的LED燈先亮一段時(shí)間,再熄滅一段時(shí)間的閃爍。
這回再說(shuō)一個(gè)程序轉向的語(yǔ)句,goto 指令,學(xué)過(guò)basic 和 c 等語(yǔ)言的對它不陌生。
單片機對程序的執行是逐句自上而下進(jìn)行。當它運行到某個(gè)位置,如果你不希望繼續運行它下面的語(yǔ)句,而是希望它無(wú)條件的強行轉到某一句上,就可以使用goto語(yǔ)句。
我們還是通過(guò)例子來(lái)說(shuō)明goto 的使用方法。
已知外部晶振的頻率為4 MHz, 設計程序從pic12ce512 單片機的GP1管腳上輸出一個(gè)方波信號,信號頻率固定并計算出頻率的值。
movlw 0F9H '常數進(jìn)W
tris GPIO '把W內的數復制到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是標號,某行必須有這個(gè)標號,否則程序通不過(guò)
nop '由于goto的存在,以下語(yǔ)句得不到運行
nop
nop
當程序自上而下運行到goto 語(yǔ)句時(shí), 不再繼續運行它底下的語(yǔ)句, 而是讓程序強行轉向到標號為myWAVE的語(yǔ)句上,并繼續運行.
這樣一來(lái)的結果,程序會(huì )永遠在標號myWAVE的這一句 bsf GPIO,GP1 到goto之間循環(huán), 打轉轉.
評論