您的位置:首页单片机PIC单片机
内容搜索:
阅读内容
背景:#EDF0F5 #FAFBE6 #FFF2E2 #FDE6E0 #F3FFE1 #DAFAF3 #EAEAEF 默认  

第二章 PIC12C5XX 指令集及程序设计技巧

[日期:2008-01-24 ] [来源:高奇 作者:佚名] [字体: (投递新闻)

§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

 

                               
表2.1   PIC12C5XX 指令集

   注: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.2 特殊指令助记符表   

在后面的例子里,你将看到程序中使用了很多的特殊指令助记符。特殊指令助记符容易记忆。使用它程序可读性也较好。但这取决于每个人的习惯,你可以只使用一部分你认为好记的助记符,甚至只用基本的指令助记符而不用特殊指令助记符来编写程序。  

§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
表2.3  复位地址表   

一般说来,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        ; 调子程序,取表格数据