讓我們來從pic的指令結構上來分析一下為什麼pic中要有bank和page的設定吧。先來看一下為什麼pic中要把ram區劃分多個bank。
仔細觀察pic組合語言指令的格式,一條完整的組合語言指令語句通常是這樣的:標號 操作碼助記符 運算元1,運算元2;注釋。其中,主體部分是『操作碼助記符 運算元1,運算元2』。
例如:指令:movf 33,1
操作碼助記符:movf ;
運算元1:33 ;
運算元2:1 ;
而在程式被編譯時指令語句的主體部分會被轉換為**的形式,通常是:指令** 運算元2 運算元1。
例如在指令位數為14位的中檔pic微控制器中:
指令:movf 33,1
轉換後**:00 1000 1 011 0011
其中指令**為:00 1000(movf f,d=00 1000 dfff ffff);
運算元2:1 (d = 1);
運算元1:011 0011 (f = 33h) ;
可以看到,由於指令**占用了6位,再加上運算元2占用的1位,分配給運算元1的只有7位了。也就是說運算元1最大只能是『111 1111』(7fh),因此『movf』直接的定址範圍只能是00h~7fh之間。其它的對暫存器操作的指令情況基本相同,因此指令位數為14位的pic 微控制器將每125個(00h~7fh,80h~ffh……依此類推)暫存器劃分為乙個bank,並且將status暫存器的rp1、rp0為定為bank 設定位。在編寫程式時,要對某個暫存器進行操作就首先要對bank的設定位進行設定,從而切換到該暫存器所在的bank。
例如pic16f877的eecon1暫存器(位址18ch)就要通過設定bank的形式來定址了,這時定址的位址資料是這樣組成的『bank值+運算元1』,其中『bank值』=『rp1 rp0』。
舉個例子來說:
指令:bsf eecon1,1 ;
指令轉換後**:0101 001 000 1100 ;
這時如果『bank值』=3,定址的位址資料就會是『11 +000 1110』(18ch);而此時如果bank值為0,則定址的位址資料就會是『00 +000 1110』(0ch),這樣就出現了錯誤。
用同樣的方法我們可以分析pic的page的設定。舉個例子,pic16c5x的乙個頁面是512條指令。它的『goto』指令是這樣的:『101 k kkkk kkkk』(『goto』指令沒有運算元2)。我們看到該指令的運算元1最大只能是『1 1111 1111』(1ffh),因此在指令位數為12位的pic16c5x 晶元中『goto』指令只能在512條指令(000h~1ffh,200h~3ffh,……)的範圍內直接跳轉。同樣的理由,pic16c5x的 『call』指令(『1011 kkkk kkkk』)只能呼叫256條指令(000h~0ffh,200h~2ffh,……)範圍內的子程式,因此在進行pic16c5x的程式設計時要將供呼叫子程式的入口放在前半頁面。
而在指令位數為14位的pic16f87x微控制器中『goto』指令**是『101 kkk kkkk kkkk』,而『call』的指令**是『100 kkk kkkk kkkk』,它們的定址範圍都是『111 1111 1111』(3ffh)。因此在pic16f87x微控制器中,乙個頁面長度就是3ffh=2048條指令(2k)。而且在使用中,使用『call』指令時就不需要將子程式入口放在上半頁面了。
微控制器 關於標頭檔案
開始寫微控制器的程式之後對於標頭檔案的使用一直沒能透徹理解,這裡歸納一些自己收集到的東西 標頭檔案裡常用的一些語句 1 ifdef 識別符號2 程式段1 3 else4 程式段2 5 endif 它的作用是 當識別符號已經被定義過 一般是用 define命令定義 則對程式段1進行編譯,否則編譯程式段...
關於PIC微控制器SLEEP指令
之前一直沒有真正理解sleep指令,最近在做智慧型水表的產品的時候,用了一款8位的微控制器pic16f690,當看到程式中的sleep指令時以為執行後cpu還會工作,導致一些認識上的錯誤,在網上搜尋了一下,找到了一篇關於sleep的詳細說明文章,現收集下來以便以後查詢!在執行sleep指令後進入睡眠...
學習微控制器關於轉換進製的問題
作為乙個新手,在學習微控制器中會遇到各種問題。比如說進製的轉換,在開發板上做依次點亮led燈時,就要對埠進行操作。然後利用一些函式和迴圈實現依次閃爍。可電腦並不會識別二進位制,必須化為十六進製制。例如,1111 1101 對應的十六進製制是多少?如果用手算,能算出來,但很麻煩。這是就要借用外力 計算...