§2.1 PIC12C5XX 指令概述
PIC12C5XX每条指令长12位,指令由操作码和操作数组成。PIC12C5XX共有33条指令,按操作分成三大类:
1、面向字节操作类
2、面向位操作类
3、常数操作和控制操作类。
全部指令如表2.1所示。
|
面向字节操作类指令 |
(11-6) |
(5) |
(4-0) |
| |||||||||||
| OPCODE | d | f(FILE#) |
| ||||||||||||
|
|
|
|
| ||||||||||||
|
二进制代码 HEX 名称 助记符,操作数 操作 |
|
|
状态影响 |
注 | |||||||||||
|
0000 0000 0000 |
000 |
空操作 |
NOP |
|
|
|
无 |
| |||||||
|
0000 001f ffff |
02f |
W送到f |
MOVWF f |
W→f |
|
|
无 |
1,4 | |||||||
|
0000 0100 0000 |
040 |
W清零 |
CLRW - |
0→W |
|
|
Z |
| |||||||
|
0000 011f ffff |
06f |
f清零 |
CLRF f |
0→f |
|
|
Z |
4 | |||||||
|
0000 10df ffff |
08f |
f减去W |
SUBWF f,d |
f-W→d |
|
|
C,DC,Z |
1,2,4 | |||||||
|
0000 11df ffff |
0Cf |
f递减 |
DECF f,d |
f-1→d |
|
|
Z |
2,4 | |||||||
|
0001 00df ffff |
10f |
W和f做或运算 |
IORWF f,d |
W∨f→d |
|
|
Z |
2,4 | |||||||
|
0001 01df ffff |
14f |
W和f做与运算 |
ANDWF f,d |
W∧f→d |
|
|
Z |
2,4 | |||||||
|
0001 10df ffff |
18f |
W和f做异或运算 |
XORWF f,d |
W〇f→d |
|
|
Z |
2,4 | |||||||
|
0001 11df ffff |
1Cf |
W加f |
ADDWF f,d |
W+f→d |
|
|
C,DC,Z |
1,2,4 | |||||||
|
0010 00df ffff |
20f |
传送f到d |
MOVF f,d |
f→d |
|
|
Z |
2,4 | |||||||
|
0010 01df ffff |
24f |
f取补 |
COMF f,d |
f→d |
|
|
Z |
2,4 | |||||||
|
0010 10df ffff |
28f |
f递增 |
INCF f,d |
f+1→d |
|
|
Z |
2,4 | |||||||
|
0010 11df ffff |
2Cf |
f递减,为0则跳 |
DECFSZ f,d |
f-1→d,skip if zero |
Z |
2,4 | |||||||||
|
0011 00df ffff |
30f |
f循环右移 |
RRF f,d |
f(n)→d(n-1),f(0)→C,C→d(7) |
C |
2,4 | |||||||||
|
0011 01df ffff |
34f |
f循环左移 |
RLF f,d |
f(n)→d(n+1),f(7)→C,C→d(0) |
C |
2,4 | |||||||||
|
0011 10df ffff |
38f |
f半字节交换 |
SWAPF f,d |
f(0.3)←→f(4-7)→d |
Z |
2,4 | |||||||||
|
0011 11df ffff |
3Cf |
f递增,为0则跳 |
INCFSZ f,d |
f+1→d,skip if zero |
Z |
2,4 | |||||||||
|
|
|
|
|
| |||||||||||
|
面向位操作类指令 |
(11-8) |
(7-5) |
(4-0) |
| |||||||||||
| OPCODE | b(BIT#) | f(FILE#) |
| ||||||||||||
|
|
|
|
| ||||||||||||
|
二进制代码 HEX 名称 助记符,操作数 操作 |
|
|
状态影响 |
注 | |||||||||||
|
0100 bbbf ffff |
4bf |
清除f的位b |
BCF f,b |
0→f(b) |
Z |
2,4 | |||||||||
|
0101 bbbf ffff |
5bf |
设置f的位b |
BSF f,b |
1→f(b) |
Z |
2,4 | |||||||||
|
0110 bbbf ffff |
6bf |
测试f的位b,为0则跳 |
BTFSC f,b |
Test bit(b) in file(f):Skip if clear |
Z |
| |||||||||
|
0111 bbbf ffff |
7bf |
测试f的位b,为0则跳 |
BTFSS f,b |
Test bit(b) in file(f):Skip if clear |
Z |
| |||||||||
|
|
|
| |||||||||||||
|
常数操作和控制操作类指令 |
(11-8) |
(7-0) |
| ||||||||||||
| OPCODE | k(LITERAL) |
| |||||||||||||
|
|
|
|
| ||||||||||||
|
二进制代码 HEX 名称 助记符,操作数 操作 |
|
|
状态影响 |
注 | |||||||||||
|
0000 0000 0010 |
002 |
写OPTION寄存器 |
OPTION - |
W→OPTION register |
无 |
| |||||||||
|
0000 0000 0011 |
003 |
进入睡眠状态 |
SLEEP - |
0→WDT,stop oscillator |
TO,PD |
| |||||||||
|
0000 0000 0100 |
004 |
清除WDT计时器 |
CLRWDT - |
0→WDT(and prescaler,if assigned) |
TO,PD |
| |||||||||
|
0000 0000 0fff |
00f |
设置I/O状态 |
TRIS f |
W→I/O control register f |
无 |
3 | |||||||||
|
1000 kkkk kkkk |
8kk |
子程序带参数返回 |
RETLW k |
k→W,Stack→PC |
无 |
| |||||||||
|
1001 kkkk kkkk |
9kk |
调用子程序 |
CALL k |
PC+1→Stack,K→PC |
无 |
1 | |||||||||
|
101k kkkk kkkk |
Akk |
跳转(K为9位) |
GOTO k |
k→PC(9 bits) |
无 |
| |||||||||
|
1100 kkkk kkkk |
Ckk |
常数置入W |
MOVLW k |
k→W |
Z |
| |||||||||
|
1101 kkkk kkkk |
Dkk |
常数和W做或运算 |
IORLW k |
k∨W→W |
Z |
| |||||||||
|
1110 kkkk kkkk |
Ekk |
常数和W做与运算 |
ANDLW k |
k∧W→W |
Z |
| |||||||||
|
1111 kkkk kkkk |
Fkk |
常数和W做异或运算 |
XORLW k |
k○W→W |
Z |
| |||||||||
注: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来进行间接寻址。
例:
FSR EQU 4
INDF EQU 0
MOVLW 05H ; W=5
MOVWF FSR ; W(=5)→F4
MOVLW 55H ; W=55H
MOVWF INDF ; W(=55H)→F5
上面这段程序把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之间进行,其指令码结构为:
| (11—6) | (5) | (4—0) |
| OPCODE | d | f(File#) |
高6位是指令操作码。第6位d是方向位。d=1,则操作结果存入f(数据寄存器),d=0,则操作结果存入W。低5位是数据寄存器地址,可选中32个寄存器。对于PIC12C509,则还要参考寄存器体选择器FSR的bit5选择存入哪一个寄存器体(bank0或bank1)。
1、寄存器加法指令
格式: ADDWF f,d
| 指令码: | 000111 | d | fffff |
指令周期: 1
操作: W+f→d
影响状态位: C,DC,Z
说明: 将f寄存器和w相加,结果存入f(d=1)或W(d=0)。
例: ADDWF 8,0 ; F8+W→W
─────────────────────────────────
2、寄存器与指令
格式: ANDWF f,d
| 指令码: | 000101 | d | fffff |
指令周期: 1
操作: W∧f→d
影响状态位: Z
说明: 将f寄存器和w做逻辑与运算,结果存入f(d=1)或W(d=0)。
例: ANDWF 10,0 ; F10∧W→W
ANDWF 10,1 ; F10∧W→F10
─────────────────────────────────
3、寄存器清零指令
格式: CLRF f
| 指令码: | 0000011 | fffff |
指令周期: 1
操作: 0→f ,1→z
影响状态位:z
说明: 将f寄存器清零,状态位Z将被置为1。
例: CLRF 8 ; F8清为零(0→F8)
─────────────────────────────────
4、W清零指令
格式: CLRW
| 指令码: | 000001 | 0 | 00000 |
指令周期: 1
操作: 0→W,1→Z
影响状态位: Z
说明: 将W寄存器清零,状态位Z将被置为1。
例: CLRW ;W清为零,Z置为1
─────────────────────────────────
5、寄存器取反指令
格式: COMF f,d
| 指令码: | 00 | d | fffff |
指令周期: 1
操作: f→d
影响状态位: Z
说明: 将f寄存器内容做逻辑求反运算,结果存入f(d=1)或W(d=0)。
例: COMF 12,0 ; F12取反→F12
COMF 12,1 ; F12取反→W
─────────────────────────────────
6、寄存器减1指令
格式: DECF f,d
| 指令码: | 000011 | d | fffff |
指令周期: 1
操作: f-1→d
影响状态位: C,DC,Z
说明: f寄存器内容减1存入f(d=1)或W(d=0)。
例: DECF 15,1 ; F15-1→F15
DECF 15,0 ; F15-1→W
─────────────────────────────────
7、寄存器减1,结果为零则跳指令
格式: DECFSZ f,d
| 指令码: | 0010 | 11df | ffff |
指令周期: 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
| 指令码: | 001010 | d | fffff |
指令周期: 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
| 指令码: | 001111 | d | fffff |
指令周期: 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
| 指令码: | 000100 | d | fffff |
指令周期: 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
| 指令码: | 001000 | d | fffff |
指令周期: 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
| 指令码: | 000000 | 1 | fffff |
指令周期: 1
操作: W→f
影响状态位: 无
说明: 将W内容传给f寄存器。
例: MOVWF 6 ; W→F6(B口)
─────────────────────────────────
13、空操作指令
格式: NOP
| 指令码: | 000000 | 000000 |
指令周期: 1
操作: 无任何操作
影响状态位: 无
说明: 不做任何操作,只有使PC加1。
─────────────────────────────────
14、带进位位左移指令
格式: RLF f,d
| 指令码: | 001101 | d | fffff |
指令周期: 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
| 指令码: | 001100 | d | fffff |
指令周期: 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
| 指令码: | 000010 | d | fffff |
指令周期: 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
| 指令码: | 001110 | d | fffff |
指令周期: 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
| 指令码: | 00010 | d | fffff |
指令周期: 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条,指令码基本结构为:
| (11—8) | (7—5) | (4—0) |
| OPCODE | bbb | file# |
高4位是操作码。bit5-bit7是位地址(可寻址8个位),bito-bit4是寄存器地址。
19、位清零指令
格式: BCF f,b
| 指令码: | 0100 | bbb | fffff |
指令周期: 1
操作: 0→f(b)
影响状态位: 无
说明: 将f寄存器的b位清为0。
例: BCF 8,2 ; 将F8的第2位(bif2)清为0。
─────────────────────────────────
20、位置1指令
格式: BSF f,b
| 指令码: | 0101 | bbb | fffff |
指令周期: 1
操作: 1→f(b)
影响状态位: 无
说明: 将f寄存器的b位置为1。
例: BSF 8,2 ; 将F8的第2位(bif2)清为1。
─────────────────────────────────
21、位测试,为零则跳指令
格式: BTFSC f,b
| 指令码: | 0110 | bbb | fffff |
指令周期: 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
| 指令码: | 0 | 11 | bbb | fffff |
指令周期: 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条,其指令码结构为:
| (11—8) | (7—0) |
| OPCODE | K |
高4位是操作码,低8位是常数K。
23、常数与指令
格式: ANDLW K
| 指令码: | 1110 | KKKKKKKK |
指令周期: 1
操作: W∧K→W
影响状态位: Z
说明: 将W寄存器和常数K做逻辑与运算,结果存入W。
例: ANDLW 55H,0 ; W∧55H→W
─────────────────────────────────
24、子程序调周指令
格式: CALL K
| 指令码: | 1001 | KKKKKKKK |
指令周期: 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
| 指令码: | 0000 | 0000 | 0100 |
指令周期: 1
操作: 0→WDT ,0→WDT预设倍数
影响状态位: 1→TO,1→PD
说明: 清除WDT,使之不能计时溢出。
─────────────────────────────────
26、无条件跳转指令
格式: GOTO K
| 指令码: | 101 | KKKKKKKKK |
指令周期: 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
| 指令码: | 1101 | KKKKKKKK |
指令周期: 1
操作: W∨K→W
影响状态位: 2
说明: 将W和常数K做逻辑或操作,结果存回W。
例: IORLW 80H ; W∨80H→W
─────────────────────────────────
28、常数传送指令
格式: MOVLW K
| 指令码: | 1100 | KKKKKKKK |
指令周期: 1
操作: K→W
影响状态位: 无
说明: 把常数K置入W寄存器。注意这条指令并不影响任何状态位。
例: MOVLW 0 ; 0→W,注意状态位Z不因之
MOVLW 88H ; 而变化。
─────────────────────────────────
29、写OPTION寄存器指令
格式: OPTION
| 指令码: | 0000 | 000000 | 0 |
指令周期: 1
操作: W→OPTION寄存器
影响状态位: 无
说明: 将W内容置入OPTION寄存器
例: MOVLW 07H ;7→W
OPTION ; OPTION=W=F
─────────────────────────────────
30、子程序返回指令
格式: RETLW K
| 指令码: | 1000 | KKKKKKKK |
指令周期: 2
操作: K→W ,堆栈→PC
影响状态位: 无
说明: 由子程序带参数K返回。返回参数存在W中。
例: RETLW 0 ; 返回,0→W
─────────────────────────────────
31、由入低功耗状态指令
格式: SLEEP
| 指令码: | 0000 | 0000 | 0011 |
指令周期: 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
| 指令码: | 0000 | 00000 | fff |
指令周期: 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
| 指令码: | 1111 | KKKKKKKK |
指令周期: 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指令。
| 二进制指令代码(Hex) | 名称 | 助记符号 | 相对运算 | 状态影响 |
|
0100 0000 0011(403) |
清除C标号 |
CLRC |
BCF 3,0 |
- |
|
0101 0000 0011(503) |
设置C标号 |
SETC |
BSF 3,0 |
- |
|
0100 0010 0011(423) |
清除辅助进位标号 |
CLRDC |
BCF 3,1 |
- |
|
0101 0010 0011(523) |
设置辅助进位标号 |
SETDC |
BSF 3,1 |
- |
|
0100 0100 0011(443) |
清除0标号 |
CLRZ |
BCF 3,2 |
- |
|
0101 0100 0011(543) |
设置0标号 |
SETZ |
BSF 3,2 |
- |
|
0111 0000 0011(703) |
进位则跳 |
SKPC |
BTFSS 3,0 |
- |
|
0110 0000 0011(603) |
无进位则跳 |
SKPNC |
BTFSC 3,0 |
- |
|
0111 0010 0011(723) |
辅助进位为1则跳 |
SKPDC |
BTFSS 3,1 |
- |
|
0110 0010 0011(623) |
辅助进位为0则跳 |
SKPNDC |
BTFSC 3,1 |
- |
|
0111 0100 0011(743) |
为0则跳 |
SKPZ |
BTFSS 3,2 |
- |
|
0110 0100 0011(643) |
不为0则跳 |
SKPNZ |
BTFSC 3,2 |
- |
|
0010 001f ffff(22f) |
测试寄存器 |
TSTF f |
MOVF f,1 |
Z |
|
0010 000f ffff(20f) |
搬移寄存器到W |
MOVFW f |
MOVF f,0 |
Z |
|
0010 011f ffff(26f) |
寄存器取补码 |
NEGF f,d |
COMF f,1 |
Z |
|
0010 10df ffff(28f) |
|
|
INCF f,d |
|
|
|
|
|
|
|
|
0110 0000 0011(603) |
加进位到寄存器 |
ADDCF f,d |
BTFSC 3,0 |
Z |
|
0010 10df ffff(28f) |
|
|
INCF f,d |
|
|
|
|
|
|
|
|
0110 0000 0011(603) |
寄存器减进位 |
SUBCF f,d |
BTFSC 3,0 |
Z |
|
0000 11df ffff(0cf) |
|
|
DECF f,d |
|
|
|
|
|
|
|
|
0110 0010 0011(623) |
加辅助进位到寄存器 |
ADDDCF f,d |
BTFSC 3,1 |
Z |
|
0010 10df ffff(28f) |
|
INCF f,d |
||
|
|
|
|
|
|
|
0110 0010 0011(623) |
从寄存器减辅助进位 |
SUBD CF f,d |
BTFSC 3,1 |
Z |
|
0000 11df ffff(0cf) |
|
|
||
|
|
|
|
|
|
|
101k kkkk kkkk(akk) |
分支 |
B k |
GOTO k |
- |
|
|
|
|
|
|
|
0110 0000 0011(603) |
依进位分支 |
BC k |
BTFSC 3,0 |
- |
|
101k kkkk kkkk(akk) |
|
|
GOTO k |
|
|
|
|
|
|
|
|
0111 0000 0011(703) |
不进位分支 |
BMC k |
BTFSS 3,0 |
- |
|
101k kkkk kkkk(akk) |
|
|
GOTO k |
|
|
|
|
|
|
|
|
0111 0000 0011(703) |
辅助进位为1分支 |
BDC k |
BTFSC 3,1 |
- |
|
101k kkkk kkkk(akk) |
|
|
GOTO k |
|
|
|
|
|
|
|
|
0110 0100 0011(643) |
辅助进位为0分支 |
BNDC k |
BTFSS 3,1 |
- |
|
101k kkkk kkkk(akk) |
|
|
GOTO k |
|
|
|
|
|
|
|
|
0111 0100 0011(743) |
0分支 |
BZ k |
BTFSC 3,2 |
- |
|
101k kkkk kkkk(akk) |
|
|
GOTO k |
|
|
|
|
|
|
|
|
0111 0100 0011(743) |
不为0分支 |
BNZ k |
BTFSS 3,2 |
- |
|
101k kkkk kkkk(akk) |
|
|
GOTO k |
在后面的例子里,你将看到程序中使用了很多的特殊指令助记符。特殊指令助记符容易记忆。使用它程序可读性也较好。但这取决于每个人的习惯,你可以只使用一部分你认为好记的助记符,甚至只用基本的指令助记符而不用特殊指令助记符来编写程序。
§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 几种型号芯片的复位地址为:
| 型 号 | RESET 地址 |
| PIC12C508 | 1FFh |
| PIC12C509 | 3FFh |
一般说来,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 ; 调子程序,取表格数据