首要想从CALL和GOTO指令的机器码讲起。PIC16是14位的长字指令,操作码和操作数放到同一个指令字里,也便是所谓单字指令。
CALL 指令(14位的指令字长)
——————————————-
| 1| 0| 0| k| k| k| k| k| k| k| k| k| k| k|
——————————————-
100是CALL指令的操作码,GOTO指令相似上面,仅仅操作码为101.后边11位的k,便是所要CALL或许GOTO的地址。明显,11位的地址只能拜访2K的地址规模,为了实现在8K规模内调用和跳转,所以引入了Page的概念。Page其实便是实践要调用或跳转到的地址的高两位。PC的高两位在产生GOTO或CALL指令时从PCLATH寄存器的4:3位装入(如下图)
PCLATH 5bits
—————-
|4|3| |
—————-
|
V
—————- ———————
|x|x| | | | (实践PC)
—————- ———————
PCH 5bits PCL 8bits
PC 13bit地址,可寻址8K字程序空间。
所以,在CALL或许GOTO指令履行前,要设定好PCLATH的4:3位,也便是设置好Page.PC的高位字节PCH是不可由程序直接写入的,它有必要是在PC改动时经过它的锁存器PCLATH装入。PCLATH始终是作为装载PCH用的一个锁存器,它自己的值不会跟着PCH的改动而改动。一个很简单的比如,程序假定次序履行从00一向到8K结尾,这样PCH的最高两位也就从00一向变成11,但PCLATH的高两位,假如你没有人为改动,本来是什么仍是什么。当CALL子程序时,CALL指令当时PC+1的13位PC地址压入仓库(由于硬件仓库是和PC等宽的)。所以RETURN时能从仓库弹出整个13位PC的回来地址,就不再需瓒≒CLATH了。可是,要记住,不设定并不代表它自己会改动。假定你CALL之前设定到Page1了,Return之后回到Page0了,但此刻,PCLATH里的4:3位仍是0:1。当产生直接修正PC时,也便是直接改写PCL,如addwf PCL,F
此刻,在改写PCL的一起,作为PCH锁存器的PCLATH会把整个5位的值瞬间传递给PCH,如下图
PCLATH 5bits
—————-
| 4| 3| 2| 1| 0|
—————- 程序修正PC低位字节
| |
V V
—————- ———————
| x| x| x| x| x| | | (实践PC)
—————- ———————
PCH 5bits PCL 8bits
PCLATH是个很重要的寄存器,你对它稍不留意,它就会让你跑飞.