| PIC12C5XX 指令集及程序设计技巧 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
§2.1 PIC12C5XX 指令概述 PIC12C5XX每条指令长12位,指令由操作码和操作数组成。PIC12C5XX共有33条指令,按操作分成三大类: 全部指令如表2.1所示。
注:1、除GOTO指令外,任何有关写PC(F2)的指令(例如 CALL、MOVWF 2)都将会把PC寄存器的第9位清零。 2、若对I/O口寄存器进行操作,如“SUBWF 6,1”,则使用的F6的值是当前GP口上的状态值,而非GP口输出锁存器里的值。 3、指令“TRIS 6”将W寄存器中的内容写入GP的I/O口控制寄存器中:“1”关断对应端口的输出缓冲器,使其为输入(高阻)状态,“0”则使其为输出态。 4、当预分频器(Prescaler)分配给TIMER0后,任何对TMR0寄存器(F1)写操作的指令都将使预分频器清零。 §2.2 PIC12C5XX 指令寻址方式 PIC12C5XX单片机寻址方式根据操作数的来源,可分为寄存器间接寻址、立即数寻址、直接寻址和位寻址四种。 一、寄存器间接寻址 这种寻址方式通过寄存器F0(INDF)、F4(FSR)来实现。实际的寄存器地址放在FSR中,通过INDF来进行间接寻址。 例: 上面这段程序把55H送入F5寄存器。间址寻址方式主要用于编写查表、写表程序,非常方便。请参考§2.7程序设计技巧。 二、立即数寻址 这种方式就是操作数为立即数,可直接从指令中获取。 例: MOVLW 16H ; 16H →W 三、直接寻址 这种方式是对任何一寄存器直接寻址访问。对PIC12C508,寄存器地址(5位)直接包括在指令中,对PIC12C509,寄存器地址中最高1位由FSR(F4)寄存器中的bit5决定,即体选位。 例: MOVWF 8 ; W→F8寄存器 MOVF 8,W ; F8→W 四、位寻址 这种寻址方式是对寄存器中的任一位(bit)进行操作。 例: BSF 11,0 ; 把F11的第0位置为“1”。 §2.3 面向字节操作类指令 这类指令共有18条,包括有数据传送、算术和逻辑运算、数据移位和交换等操作。它们的操作都是在W数据寄存器f之间进行,其指令码结构为:
高6位是指令操作码。第6位d是方向位。d=1,则操作结果存入f(数据寄存器),d=0,则操作结果存入W。低5位是数据寄存器地址,可选中32个寄存器。对于PIC12C509,则还要参考寄存器体选择器FSR的bit5选择存入哪一个寄存器体(bank0或bank1)。 1、寄存器加法指令 格式: ADDWF f,d
指令周期: 1 ───────────────────────────────── 2、寄存器与指令 格式: ANDWF f,d
指令周期: 1 ───────────────────────────────── 3、寄存器清零指令 格式: CLRF f
指令周期: 1 ───────────────────────────────── 4、W清零指令 格式: CLRW
指令周期: 1 ───────────────────────────────── 5、寄存器取反指令 格式: COMF f,d
指令周期: 1 ───────────────────────────────── 6、寄存器减1指令 格式: DECF f,d
指令周期: 1 ───────────────────────────────── 7、寄存器减1,结果为零则跳指令 格式: DECFSZ f,d
指令周期: 1或2(产生跳转时为2) 操作: f-1→d; 结果为零则跳(PC+1→PC) 影响状态位: 无 说明: 将f寄存器内容减1存入f(d=1)或W(d=0)。如果结果为0,则跳过 下一条指令不执行。否则顺序执行下一条指令。 例: ┌───DECFSZ 10,1 ; F10-1→F10,如果F10为0 F10=0 │ MOVLW 55H ; 则跳过MOVLW 55H指令 └──→MOVF 12,0 ───────────────────────────────── 8、寄存器加1指令 格式: INCF f,d
指令周期: 1 操作: f+1→d 影响状态位: C,DC,Z 说明: f寄存器加1,结果存入f(d=1)或W(d=0)。 例: INCF 10,0 ; F10+1→W INCF 10,1 ; F10+1→F10 ───────────────────────────────── 9、寄存器加1,结果为零则跳指令 格式: INCFSZ f,d
指令周期: 1或2(产生跳转时为2) 操作: f+1→d,结果为零则跳(PC+1→PC) 影响状态位: 无 说明: 将f寄存器内容加1存入f(d=1)或W(d=0),如果结果为零则PC值 加1跳过下一条指令。 例: L00P ┌─INCFSZ 8,1 ; 将F8寄存器加1,结果存入F8, │ GOTO LOOP ; 加1后结果为零则跳到MOVWFF9指令 F8=0 └→MOVWF 9 ───────────────────────────────── 10、寄存器或指令 格式: IORWF f,d
指令周期: 1 操作: W∨f→d 影响状态位: Z 说明: 将f寄存器内容和W内容做逻辑或运算,结果存入f(d=1)或W(d=0)。 例: IORWF 18,1 ; F18∨W→F18 IORWF 18,0 ; F18∨W→W ───────────────────────────────── 11、f寄存器传送指令 格式: MOVF f,d
指令周期: 1 操作: f→d 影响状态位: Z 说明: 将f寄存器内容传送至W(d=0)或自己本身f(d=1)。如果是传给 自己,一般是用来影响状态位Z,即可判断f是否为零。 例: MOVF 10,1 ; F10→F10 BTFSS 3,2 ; 判断F3的第二位,即Z状态位。如果F10=0,则Z=1。 ───────────────────────────────── 12、W寄存器传送指令 格式: MOVWF f
指令周期: 1 操作: W→f 影响状态位: 无 说明: 将W内容传给f寄存器。 例: MOVWF 6 ; W→F6(B口) ───────────────────────────────── 13、空操作指令 格式: NOP
指令周期: 1 操作: 无任何操作 影响状态位: 无 说明: 不做任何操作,只有使PC加1。 ───────────────────────────────── 14、带进位位左移指令 格式: RLF f,d
指令周期: 1 操作: f(n)→d(n+1),f(7)→c,c→d(0) 影响状态位: C 说明: 将f寄存器左移,结果存入f(d=1)或W(d=0)。f左移时,其最高 位(bit7)移入状态位C(进位位),如下图: 进位位 ┌──┐ ┌──┬──┬──┬──┬──┬──┬──┬──┐ ┌─┤ C │← │D7 │ D6 │D5 │ D4 │D3 │ D 2│ D1 │ D0│ ←─┐ │ └──┘ └──┴──┴──┴──┴──┴──┴──┴──┘ │ └──────────────────────────────────┘ 例: RLF 8,1 ; F8左移→F8 RLF 8,0 ; F8左移→W ───────────────────────────────── 15、带进位位右移指令 格式: RRF f,d
指令周期: 1 操作: f(n)→d(n-1),f(0)→c,c→d(7) 影响状态位: C 说明: 将f寄存器右移,结果存入f(d=1)或W(d=0)。f右移时,其最低 位(bito)移入状态位C,而原来的状态位C移入f最高位(bit7), 如下图: ┌────────────────────────────┐ │进位位 │ │ ┌─┐ ┌──┬─┬──┬─┬──┬─┬──┬─┐│ └─→│C │→│D7 │D6│D5 │D4│D3 │D2│ D1 │D0│─┘ └─┘ └──┴─┴──┴─┴──┴─┴──┴─┘ 例: RRF 8 ,1 ;F8右移→F8 RRF 8,0 ;F8右移→W ───────────────────────────────── 16、寄存器减法指令 格式: SUBWF f,d
指令周期: 1 操作: f-w→d 影响状态位: C,DC,2 说明: 将f寄存器内容减去W内容,结果存入f(d=1)或W(d=0)。 例: CLRF 20 ;F20=0 MOVLW 1 ; W=1 SUBWF 20,1 ; F20-W=0-1=-1→F20 ; C=0,运算结果为负。 ───────────────────────────────── 17、寄存器交换指令 格式: SWAPF f,d
指令周期: 1 操作: f(0-3)→d(4-7),f(4-7)→d(0-3) 影响状态位: 无 说明: 将f寄存器内容的高4位(bit7-bit4)和低4位(bit3-bit0)交换 结果存入f(d=1)或W(d=0)。 例: MOVLW 56H MOVWF 8 ; F8=56H SWAPF 8,1 ; F8交换,结果存入F8,则F8=65H。 ───────────────────────────────── 18、寄存器异或运算指令 格式: XORWF f,d
指令周期: 1 操作: W○f→d 影响状态位: Z 说明: 将f寄存器和W进行异或运算,结果存入f(d=1)或W(f=0)。 例: XORWF 5,1 ; F5○W→F5(A口) XORWF 5,0 ; F5○W→W §2.4 面向位操作类指令 这类指令共有4条,指令码基本结构为:
高4位是操作码。bit5-bit7是位地址(可寻址8个位),bito-bit4是寄存器地址。 19、位清零指令 格式: BCF f,b
指令周期: 1 操作: 0→f(b) 影响状态位: 无 说明: 将f寄存器的b位清为0。 例: BCF 8,2 ; 将F8的第2位(bif2)清为0。 ───────────────────────────────── 20、位置1指令 格式: BSF f,b
指令周期: 1 操作: 1→f(b) 影响状态位: 无 说明: 将f寄存器的b位置为1。 例: BSF 8,2 ; 将F8的第2位(bif2)清为1。 ───────────────────────────────── 21、位测试,为零则跳指令 格式: BTFSC f,b
指令周期: 1或2(产生跳转则为2) 操作: 如果f(b)=0则跳(PC+1→PC) 影响状态位: 无 说明: 测试f寄位器的第b位,如果位b为零则跳过下一条指令,否则顺 序执行下去 。 例: ┌──BTFSC 8,2 ; 测试F8的bit2,如果为0 bit2=0 │ MOVF 5,0 ; 则跳到INCF9,1执行。 └─→INCF 9,1 ; ───────────────────────────────── 22、位测试,为1则跳指令 格式: BTFSS f,b
指令周期: 1或(产生跳转则为2) 操作: 如果f(b)=1则跳(PC+1→PC) 影响状态位: 无 说明: 测试f寄有器的有第b位,如果位b为1则跳过下一条指令,否则顺 序执行下去。 例: ┌─BTFSS 8,2 ; 测试F8的bit2,如果为1 bit2=1 ┤ MOVF 5,0 ; 则跳到INCF9,1 └→INCF 9,1 §2.5 常数和控制操作类指令
这类指令共有11条,其指令码结构为:
高4位是操作码,低8位是常数K。
23、常数与指令 格式: ANDLW K
指令周期: 1 操作: W∧K→W 影响状态位: Z 说明: 将W寄存器和常数K做逻辑与运算,结果存入W。 例: ANDLW 55H,0 ; W∧55H→W ───────────────────────────────── 24、子程序调周指令 格式: CALL K
指令周期: 2 操作: PC+1→堆栈; K→PC(0-7);‘0’→PC(8);PA1,PA0→PC(10-9)。 影响状态位: 无 说明: 将程序计数器PC加1后推入堆栈、将常数K(程序地址的低8位) 置入PC,同时还把PC的第9位清为0。对于PIC12C509来论,STATUS 的PA0位(页面地址)还将被置入PC的最高位(bit9)。所以子程序 可以放在二个页面的任何一个中, 但必须放在每页的上半部(低 址区),因为执行CALL指令将PC的第9位(bit8)清为"0"。 例: CALL DELAY ; 调用子程序DELAY : : DELAY MOVLW 80H ──┐ : │ : │ ; 子程序其第一条指令须放在每页面的上半区。 RETLW 0 ──┘ 注:有关子程序调用的一些问题,请参考§2.7程序设计技巧。 ───────────────────────────────── 25、看门狗计数器清零指令 格式: CLRWDT
指令周期: 1 操作: 0→WDT ,0→WDT预设倍数 影响状态位: 1→TO,1→PD 说明: 清除WDT,使之不能计时溢出。 ───────────────────────────────── 26、无条件跳转指令 格式: GOTO K
指令周期: 2 操作: K→PC(8-0),PA1,PA0→PC(10-9) 影响状态位: 无 说明: 常数K(地址)置入PC低9位。对于PIC12C509,STATUS中 的PA0位(页面地址位)将同时置入PC的最高位(bit9)。 所以GOTO指令可跳到程序区的任何地方去执行。 例: GOTO LOOP ; 跳转到LOOP : : LOOP MOVLW 10 ; 注: 关于跨页面跳转的问题,请参阅§2.7程序设计技巧。 ───────────────────────────────── 27、常数或指令 格式: IORLW K
指令周期: 1 操作: W∨K→W 影响状态位: 2 说明: 将W和常数K做逻辑或操作,结果存回W。 例: IORLW 80H ; W∨80H→W ───────────────────────────────── 28、常数传送指令 格式: MOVLW K
指令周期: 1 操作: K→W 影响状态位: 无 说明: 把常数K置入W寄存器。注意这条指令并不影响任何状态位。 例: MOVLW 0 ; 0→W,注意状态位Z不因之 MOVLW 88H ; 而变化。 ───────────────────────────────── 29、写OPTION寄存器指令 格式: OPTION
指令周期: 1 操作: W→OPTION寄存器 影响状态位: 无 说明: 将W内容置入OPTION寄存器 例: MOVLW 07H ;7→W OPTION ; OPTION=W=F ───────────────────────────────── 30、子程序返回指令 格式: RETLW K
指令周期: 2 操作: K→W ,堆栈→PC 影响状态位: 无 说明: 由子程序带参数K返回。返回参数存在W中。 例: RETLW 0 ; 返回,0→W ───────────────────────────────── 31、由入低功耗状态指令 格式: SLEEP
指令周期: 1 操作: 0→PD,1→TO; 0→WDT ,0→WDT的预分频器 影响状态位: PD,TO 说明: 停止芯片振荡,使PIC进入低功耗睡眠模式。这条指令还会 清零WDT和预分频器(如果预分频器分配给WDT的话),并将 STATUS的PD位清零,TO位置1。进入低功耗模式后,I/O状 态保持不变,WDT清零后重新计时,一但计时溢出即将把PIC 从SLEEP模式中唤醒(通过RESET)。 ───────────────────────────────── 32、设置I/O控制寄存器指令 格式: TRIS f
指令周期: 1 操作: W→I/O控制寄存器TRISf(f=6) 影响状态位: 无 说明: 将W寄存器内容置入GP口控制寄存器,以设定GP口的输入/输 出方向。f=6,对应于GP口。 例: MOVLW 0FH ; W=OFH TRIS 6 ; TRISB=OFH RB5 RB4 RB3 RB2 RB1 RB0 TRISB=OFH │ │ │ │ │ │ └──┬──┘ └──┴┬─┴──┘ │ │ 输出 输入 ───────────────────────────────── 33、常数异或指令 格式: XORLW k
指令周期: W○K→W 影响状态位: Z 说明: 将W和常数K逻辑异或运算,结果存入W。 例: XORLW 33H ; W○33H→W §2.6 特殊指令助记符 PIC12C5XX的一些指令还可以用容易记忆的助记符来表示。PIC12C5XX的汇编MPASM可以认识这些助记符,在汇编时会将其转译成相应的PIC12C5XX基本指令。 例如指令“BCF 3,0”(清零C)也可以写成CLRC,“BSF 3,0”(置C=1)也可写成SETC等。 表2.2列出了这些助记符及其相对应的PIC12C5XX指令。
在后面的例子里,你将看到程序中使用了很多的特殊指令助记符。特殊指令助记符容易记忆。使用它程序可读性也较好。但这取决于每个人的习惯,你可以只使用一部分你认为好记的助记符,甚至只用基本的指令助记符而不用特殊指令助记符来编写程序。 §2.7 PIC12C5XX 程序设计基础 上面我们已经详细介绍了PIC12C5XX的每条指令。现在我们来总结一下它们的几个特点: 1、各寄存器的每一个位都可单独地被置位、清零或测试,无须通过间接比较,可节省执行时间和程序地址空间。 2、特殊功能寄存器的使用方法和通用寄存器的方法完全一样,即和通用寄存器一样看待。这样使程序执行和地址空间都简化很多。 3、对于PIC12C509跨页面的CALL和GOTO操作,要事先设置STATUS中的页面地址位PA0,对于CALL来论,子程序返回后还要将STATUS中的PA0恢复到本页面地址。 §2.7.1 程序的基本格式 先介绍二条伪指令: (a) EQU──标号赋值伪指令 (b) ORG──地址定义伪指令 PIC12C5XX一旦复位后指令计数器PC被置为全“1”,所以PIC12C5XX 几种型号芯片的复位地址为:
一般说来,PIC12C5XX的源程序并没有要求统一的格式,大家可以根据自己的风格来编写。但这里我们推荐一种清晰明了的格式供参考。 TITLE This is..... ; 程序标题 ;------------------ ;名称定义和变量定义 ;------------------ INDF EQU 0 TMR0 EQU 1 PC EQU 2 STATUS EQU 3 FSR EQU 4 GP EQU 6 ;-------------------------------- ORG 0 ; 从000H开始存放程序 GOTO MAIN ;-------------------------------- ;子程序区 ;-------------------------------- DELAY MOVLW 255 ┊ RETLW 0 ;-------------------------------- ;主程序区 ;-------------------------------- MAIN CLRW TRIS GP ; GP已由伪指令定义为6。 CALLL DELAY ┊ END ; The End of Program 注: MAIN标号一定要处在0页面内。 另一些指令书写注意事项请参阅第五章“汇编程序”。 §2.7.2 程序设计基础 一、设置I/O口的输入/输出方向 PIC12C5XX的I/O口皆为双向可编程,即每一根I/O 端线都可分别单独地由程序设置为输入或输出。这个过程由写I/O控制寄存器TRISf来实现,写入值为“1”,则为输入;写入值为“0”, 则为输出。 MOVLW 0FH ; 00 1111 (0FH) ↑ ↑ │ └──输入 └────输出 TRIS 6 ; W中的0FH写入GP口控制器,GP口高2位为输出, 低4位为输入 。 二、检查寄存器是否为零 如果要判断一个寄存器内容是否为零,很简单: MOVF 10,1 ; F10→F10,结果影响状态位Z ┌─ SKPZ ; F10为零则跳(Z=1否) Z=1 │ GOTO NZ ; F10不为零 (F10=0)└─→: : : NZ MOVLW 55H : : 三、比较二个寄存器的大小 要比较二个寄存器的大小,可以将它们做减法运算,然后根据状态位C来判断。注意,相减的结果放入W,则不会影响二寄存器原有的值。 例如F8和F9二个寄存器要比较大小: MOVF 8, 0 ; F8→W SUBWF 9, 0 ; F9-F8→W SKPNZ ; 判断Z=1否(即F9=F8否) GOTO F8=F9 ; F9=F8 SKPNC ; C=0则跳 GOTO F9>F8 ; C=1,相减1结果为正,F9>F8 GOTO F8>F9 ; C=0,相减结果为负,F8>F9 : : 四、循环n次的程序 如果要使某段程序循环执行n次,可以用一个寄存器作计数器。下例以F10做计数器,使程序循环8次。 COUNT EQU 10 ; 定义F10名称为COUNT(计数器) : : MOVLW 8 ; 循环次数→COUNT MOVWF COUNT ┌─→LOOP CLRW ; 循环体 │ : │ : │ ┌──DECFSZ COUNT,1 ; COUNT减1,结果为零则跳 └──┼──GOTO LOOP ; 结果不为零,继续循环 └─→ : ; 结果为零,跳出循环 : 五、 "IF......THEN......"格式的程序 下面以"IF X=Y THEN GOTO NEXT"格式为例。
X EQU ×× Y EQU ×× ;X,Y值由用户定义(变量) : : MOVLW X MOVWF 10 ;X→F10 MOVLW Y ;Y→W SUBWF 10,0 ;X-Y→W ┌─ SKPNZ ;X=Y否 X≠Y │ GOTO NEXT ;X=Y,跳到NEXT去执行。 └→ : :
六、"FOR......NEXT"格式的程序 "FOR......NEXT"程序使循环在某个范围内进行。下例是"FOR X=0 TO 5"格式的程序。F10放X的初值,F11放X的终值。 START EQU 10 END' EQU 11 : : MOVLW 0 MOVWF START ;0→START(F10) MOVLW 5 MOVWF END' ;5→END'(F11) ┌─→LOOP : ;循环体 │ : │ INCF START,1 ;START值加1 │ MOVF START,O │ SUBWF END',0 ;START=END'?(X=5否) │ X=5┌─ SKPZ └──┼─ GOTO LOOP ;X<5,继续循环 └→ : ;X=5,结束循环 :
七、“DO WHILE.........END”格式的程序 “DO WHILE.........END”程序是在符合条件下执行循环。下例是“DO WHILE X=1”格式的程序。F10放X的值。
X EQU 10 : : MOVLW 1 MOVWF X ;1→X(F10),作为初值 ┌─→LOOP : │ : │ MOVLW 1 │ SUBWF X,0 │X≠1┌─ SKPNZ ;X=1否? └──┼─ GOTO LOOP ;X=1 继续循环 └→ : ;X≠1,跳出循环 : 八、查表程序 查表是程序中经常用到的一种操作。 PIC的查表程序可以利用子程序带值返回的特点来实现。具体是在主程序中先取表数据地址放入W,接着调用子程序。子程序的第一条指令将W置入PC,则程序跳到数据地址的地方,再由“RETLW”指令将数据放入W返回到主程序。 下面程序以F10放表头地址。 MOVLW TABLE ; 表头地址→F10 MOVWF 10 : : MOVLW 1 ; 1→W,准备取表格中的数据。 ADDWF 10,1 ; F10+W=表中第二个数据的地址。 CALL CONVERT MOVWF 6 ; 送到GP口上。 : : CONVERT MOVWF 2 ; W→PC TABLE RETLW C0H RETLW F9H : : RETLW 90H 九、“READ......DATA,RESTORE”格式程序 “READ......DATA”程序是每次读取数据表的一个数据,然后将数据指针加1,准备下一次取下一个数据。下例程序中以F10被数据表起始地址,F11做数据指针。 POINTER EQU 11 ; 定义F11名称为POINTER : : MOVLW DATA MOVWF 10 ; 数据表头地址→F10 CLRF POINTER ; 数据指针清零 : : MOVF POINTER,0 ADDWF 10,0 ; W=F10+POINTER : : INCF POINTER,1 ; 指针加1 CALL CONVERT ; 调子程序,取表格数据 : : CONVERT MOVWF 2 ; 数据地址→PC DATA RETLW 20H ; 数据 : RETLW 15H ; 数据 如果要执行“RESTORE”,只要执行一条“CLRF POINTER”即可。 十、延时程序 如果延时时间较短,可以让程序简单地连续执行几条空操作指令“NOP”。如果延时时间长,可以用循环来实现。下例以F10计算,使循环重复执行100次。 MOVLW 100 MOVWF 10 ┌─→LOOP┌── DECFSZ 10,1 ;F10-1→F10,结果为零则跳 └────┼── GOTO LOOP └─→ : : 延时程序中计算指令执行的时间和即为延时时间。如果使用4MHz振荡,则每个指令周期为1uS。所以单周期指令执行时间为1uS,双周期指令为2uS。 在上例的LOOP循环延时时间即为(1+2)*100+2=302(uS)。在循环中插入空操作指令即可延长延时时间:
MOVLW 100 MOVWF 10 ┌─→ LOOP NOP │ NOP │ NOP │ ┌── DECFWZ 10,1 └──┼─ GOTO LOOP └─→ : : 延时时间=(1+1+1+1+2)*100+2=602(US)。 用几个循环嵌套的方式可以大大延长延时时间。如下例用2个循环来做延时。 MOVLW 100 MOVLW 10 ;第一计数值(100)→F10 ┌→LOOP MOVLW 16 │ MOVLW 11 ;第二计数值(16)→F11 │┌→LOOP1 DECFSZ 11,1 │└────── GOTO LOOP1 │ ┌── DECFSZ 10,1 └────┼── GOTO LOOP2 └──→: : 延时时间= [(1+2)*6+2+]+1+2+1+1 +*100+2=5502(US) 十一、TIMER0计数器的使用 TIMER0是一个脉冲计数器,它的计数脉冲有二个来源,一个是从T0CKI引脚输入的外部信号,一个是内部的指令时钟信号。可以用程序来选择其中一个信号源做为输入。TIMER0可被程序用作计时之用:程序读取TMR0寄存器值以计算时间。 下例程序以TIMER0做延时。 TMR0 EQU 1 : : CLRF TMR0 ; TMR0清O MOVLW 07H OPTION ; 选择预设倍数1:256→RTCC ┌─→LOOP MOVLW 255 ; TMR0计数终位值 │ SUBWF | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||