第2章CPU 2.2.2.1PUSH.S和POP.S影子寄存器 在执行函数调用或中断服务程序(Interrupt Service Routine,lSR)时,UsH.s和pop.s指 令可用于快速的现场保存/恢复。PUSH.S指令会将下列寄存器的值传输到它们各自的影子寄存 器: ·W0W3 ·SR(仅N、OV、Z、C和DC位) POP.S指令会将值从影子寄存器恢复到这些寄存器单元。下面是使用PUSH.S和POP.S指令的 代码示例: MyFunction: PUSH.S Save W registers,MCU status MOV #0x03,W0 load a literal value into Wo 2 ADD RAM100 add Wo to contents of RAM100 BTSC SR,#Z is the result 0? BSET Flags,#IsZero;Yes,set a flag POP.S ;Restore W regs,MCU status RETURN PUSH.S指令会改写先前保存在影子寄存器中的内容。影子寄存器深度只有一级,所以如果多个 软件任务使用影子寄存器,必须小心。 用户必须确保使任何使用影子寄存器的任务均不会被同样使用该影子寄存器且具有更高优先级的 任务中断。如果允许较高优先级的任务中断较低优先级的任务,较低优先级任务保存在影子寄存 器中的内容将被较高优先级任务改写。 2.2.2.2 DO循环影子害存器 当执行D0指令时,下列寄存器的内容将自动保存在影子寄存器中。 ·DOSTART ·DOEND ·DCOUNT DO影子寄存器的深度为一级,允许两个循环自动嵌套。更多详细信息,请参见第2.9.2.2节“D0 循环嵌套”。 2.2.3 未初始化的W寄存器的复位 W寄存器阵列(除W15之外)在发生所有复位时被清零,并且在被写入前视为未经初始化。试 图把未初始化的寄存器用作地址指针将会复位器件。 必须执行字写操作来初始化W寄存器。字节写操作不会影响初始化检测逻辑。 2005 Microchip Technology Inc. DS70049CCN第2-7页
© 2005 Microchip Technology Inc. DS70049C_CN 第 2-7 页 第 2 章 CPU CPU 2 2.2.2.1 PUSH.S 和 POP.S 影子寄存器 在执行函数调用或中断服务程序 (Interrupt Service Routine, ISR)时, PUSH.S 和 POP.S 指 令可用于快速的现场保存 / 恢复。PUSH.S 指令会将下列寄存器的值传输到它们各自的影子寄存 器: • W0……W3 • SR (仅 N、 OV、 Z、 C 和 DC 位) POP.S 指令会将值从影子寄存器恢复到这些寄存器单元。下面是使用 PUSH.S 和 POP.S 指令的 代码示例: MyFunction: PUSH.S ; Save W registers, MCU status MOV #0x03,W0 ; load a literal value into W0 ADD RAM100 ; add W0 to contents of RAM100 BTSC SR,#Z ; is the result 0? BSET Flags,#IsZero ; Yes, set a flag POP.S ; Restore W regs, MCU status RETURN PUSH.S 指令会改写先前保存在影子寄存器中的内容。影子寄存器深度只有一级,所以如果多个 软件任务使用影子寄存器,必须小心。 用户必须确保使任何使用影子寄存器的任务均不会被同样使用该影子寄存器且具有更高优先级的 任务中断。如果允许较高优先级的任务中断较低优先级的任务,较低优先级任务保存在影子寄存 器中的内容将被较高优先级任务改写。 2.2.2.2 DO 循环影子寄存器 当执行 DO 指令时,下列寄存器的内容将自动保存在影子寄存器中。 • DOSTART • DOEND • DCOUNT DO影子寄存器的深度为一级,允许两个循环自动嵌套。更多详细信息,请参见第2.9.2.2节 “DO 循环嵌套”。 2.2.3 未初始化的 W 寄存器的复位 W 寄存器阵列 (除 W15 之外)在发生所有复位时被清零,并且在被写入前视为未经初始化。试 图把未初始化的寄存器用作地址指针将会复位器件。 必须执行字写操作来初始化 W 寄存器。字节写操作不会影响初始化检测逻辑
dsPIC30F系列参考手册 2.3 软件堆栈指针 W15作为专用的软件堆栈指针并被异常处理、子程序调用和返回自动修改。但是,W15可以被 任何指令以与所有其他W寄存器相同的方式引用。这样就简化了对堆栈指针的读、写和控制(例 如,创建堆栈帧)。 注:为了防止偏离的堆栈访问,W15<0>被硬件固定为0。 所有复位均将W15初始化为0x0800。此地址确保在所有dsPIC30F器件中,堆栈指针(SP) 将指向有效的RAM并允许在SP被用户软件初始化前发生的不可屏蔽异常陷阱使用堆栈。在初 始化期间,用户可以将SP重新编程以指向数据空间内的任何单元。 堆栈指针总是指向第一个可用的空字并从低地址到高地址填充软件堆栈。堆栈出栈(读)时,堆 栈指针先减:堆栈进栈(写)时,堆栈指针后加,如图2-3所示。 当PC压入堆栈时,PC<15:0>被压入第一个可用的堆栈字,然后PC<22:16>被压入第二个可用 的堆栈单元。对于任何cALL指令执行期间的PC进栈,进栈前PC的MSB是以零扩展的,如 图2-3所示。例外处理期间,PC的MSB与CPU状态寄存器SR的低8位相连。这样就使SRL 的内容在中断处理期间能被自动保存。 图2-3: CALL指令的堆栈操作 15 0 CALL SUBR PC<15:0 ←W15(CALL之前) B'000000000'PC<22:16> <空字> 要园 4W15(CALL之后) DS70049C_CN第2-8页 2005 Microchip Technology Inc
dsPIC30F 系列参考手册 DS70049C_CN 第 2-8 页 © 2005 Microchip Technology Inc. 2.3 软件堆栈指针 W15 作为专用的软件堆栈指针并被异常处理、子程序调用和返回自动修改。但是, W15 可以被 任何指令以与所有其他 W 寄存器相同的方式引用。这样就简化了对堆栈指针的读、写和控制(例 如,创建堆栈帧)。 所有复位均将 W15 初始化为 0x0800。此地址确保在所有 dsPIC30F 器件中,堆栈指针 (SP) 将指向有效的 RAM 并允许在 SP 被用户软件初始化前发生的不可屏蔽异常陷阱使用堆栈。在初 始化期间,用户可以将 SP 重新编程以指向数据空间内的任何单元。 堆栈指针总是指向第一个可用的空字并从低地址到高地址填充软件堆栈。堆栈出栈(读)时,堆 栈指针先减;堆栈进栈 (写)时,堆栈指针后加,如图 2-3 所示。 当 PC 压入堆栈时,PC<15:0> 被压入第一个可用的堆栈字,然后 PC<22:16> 被压入第二个可用 的堆栈单元。对于任何 CALL 指令执行期间的 PC 进栈,进栈前 PC 的 MSB 是以零扩展的,如 图 2-3 所示。例外处理期间,PC 的 MSB 与 CPU 状态寄存器 SR 的低 8 位相连。这样就使 SRL 的内容在中断处理期间能被自动保存。 图 2-3: CALL 指令的堆栈操作 注: 为了防止偏离的堆栈访问, W15<0> 被硬件固定为 0。 < 空字 > PC<15:0> PC<22:16> 15 0 W15(CALL 之前) W15(CALL 之后) 堆栈往 B'000000000' CALL SUBR 高地址递增
第2章CPU 2.3.1 软件堆栈示例 使用PUSH和POP指令可控制软件堆栈。PUSH和POP指令相当于将WI5用作目标指针的MOV 指令。例如,要把WO的内容压入堆栈,可通过: PUSH WO 此语法相当于: MoVW0,[W15++] 要把栈顶的内容返回WO,可通过: POP WO 此语法相当于: MoV[--W15],W0 2 图2-4到图2-7给出了如何使用软件堆栈的示例。图24所示为器件初始化时的软件堆栈。W15 已经初始化为0x0800。此外,此示例假设0x5A5A和0x3636这两个值己被分别写入W0和 W1。图2-5中堆栈第一次进栈,W0中包含的值被复制到堆栈中。W15自动更新以指向下一个 可用的堆栈单元(0x0802)。在图2-6中,W1的内容被压入堆栈。图2-7中,堆栈出栈并且栈 顶值(先前从W1压入)被写入W3. 图2-4: 器件复位时的堆找指针 0x0000 W15 0x0800 0xFFFE W15=0x0800 WO =0x5A5A W1=0x3636 图2-5: 第一次执行PUSH指令后的堆找指针 0×0000 0x5A5A 0x0800 PUSH WO W15 0x0802 0xFFFE W15=0x0802 WO =0x5A5A W1=0x3636 图2-6: 第二次执行PUSH指令后的堆找指针 0x0000 0x5A52 0x0800 PUSH W1 0x3636 0x0802 W15 0x0804 0xFFFE W15=0x0804 WO =0x5A5A W1=0x3636 2005 Microchip Technology Inc. DS70049CCN第2-9页
© 2005 Microchip Technology Inc. DS70049C_CN 第 2-9 页 第 2 章 CPU CPU 2 2.3.1 软件堆栈示例 使用 PUSH 和 POP 指令可控制软件堆栈。PUSH 和 POP 指令相当于将 W15 用作目标指针的 MOV 指令。例如,要把 W0 的内容压入堆栈,可通过: PUSH W0 此语法相当于: MOV W0,[W15++] 要把栈顶的内容返回 W0,可通过: POP W0 此语法相当于: MOV [--W15],W0 图 2-4到图 2-7给出了如何使用软件堆栈的示例。图 2-4所示为器件初始化时的软件堆栈。 W15 已经初始化为 0x0800。此外,此示例假设 0x5A5A 和 0x3636 这两个值已被分别写入 W0 和 W1。图 2-5 中堆栈第一次进栈, W0 中包含的值被复制到堆栈中。 W15 自动更新以指向下一个 可用的堆栈单元(0x0802)。在图 2-6 中,W1 的内容被压入堆栈。图 2-7 中,堆栈出栈并且栈 顶值 (先前从 W1 压入)被写入 W3。 图 2-4: 器件复位时的堆栈指针 图 2-5: 第一次执行 PUSH 指令后的堆栈指针 图 2-6: 第二次执行 PUSH 指令后的堆栈指针 0x0000 0xFFFE W15 0x0800 W15 = 0x0800 W0 = 0x5A5A W1 = 0x3636 0x0000 0xFFFE 0x5A5A W15 = 0x0802 W0 = 0x5A5A W1 = 0x3636 0x0800 PUSH W0 W15 0x0802 0x0000 0xFFFE 0x5A5A 0x3636 W15 = 0x0804 W0 = 0x5A5A W1 = 0x3636 0x0800 PUSH W1 0x0802 W15 0x0804
dsPIC30F系列参考手册 图2-7: 执行一条POP指令后的堆栈指针 0x0000 0x0800 POP W3 0×05A5A W15 0x03636 0x0802 0xFFFE W15=0x0802 0x3636→W3 2.3.2 W14软件堆栈帧指针 帧是堆栈中用户定义的存储器段,供单个子程序使用。W14是特殊工作寄存器,因为通过使用 LNK(Iink,连接)和ULNK(unlink,不连接)指令可以把它用作堆栈帧指针。当不用作顿指针 时,W14可被指令当作普通的工作寄存器使用。 若要获取将W14用作堆栈帧指针的软件示例,请参见dsPIC30 F Programmer''s Reference Manual (DS70030). 2.3.3 堆栈指针上溢 有一个与堆栈指针相关的堆栈极限寄存器(SPLIM),复位时为0x0000。SPLIM是一个16位 寄存器,但是SPLM<0>被固定为“0”,因为所有的堆栈操作必须字对齐。 直到一个字写入SPLM后才使能堆栈上溢检查,在此之后,只能通过器件复位禁止堆栈上溢检 查。所有将W15用作源或日标寄存器而产生的有效地址将与SPLIM中的值作比较。如果堆栈指 针(W15)的内容比SPLM寄存器的内容大2,并且执行了进栈操作,将不会产生堆栈错误陷 阱(Stack Error Trap)。堆栈错误陷阱将在随后的进栈操作时产生。所以,例如,如果想要在 堆栈指针递增超出RAM中的地址0x2000时,引起堆栈错误陷阱,可将SPLIM初始化为0x1FEE。 注: 堆栈错误陷阱可以由任何使用WI5寄存器的内容来产生有效地址(Effective Address, EA)的指令引起。所以,如果W15的内容比SPLIM寄存器的内容大2,并且执行了 一条CALL指令或发生了中断,那么将产生堆栈错误陷阱。 如果已经使能了堆栈上溢检查,则当W15有效地址计算越过了数据空间的末尾(0 xFFFF)时, 也将产生堆栈错误陷阱。 注:对堆栈指针极限寄存器SPLM的写操作后面不应紧跟一个使用WI5的间接读操作。 更多有关堆栈错误陷阱的信息,请参见第6章“复位中断”。 2.3.4 堆栈指针下溢 发生复位时,堆栈初始化为0x0800。如果堆栈指针地址小于0x0800,堆栈错误陷阱将会产生。 注:一般而言,数据空间中0x0000和0x07FF之间的单元预留给内核和外设的特殊功能 寄存器。 DS70049CCN第2-10页 2005 Microchip Technology Inc
dsPIC30F 系列参考手册 DS70049C_CN 第 2-10 页 © 2005 Microchip Technology Inc. 图 2-7: 执行一条 POP 指令后的堆栈指针 2.3.2 W14 软件堆栈帧指针 帧是堆栈中用户定义的存储器段,供单个子程序使用。 W14 是特殊工作寄存器,因为通过使用 LNK (link,连接)和 ULNK (unlink,不连接)指令可以把它用作堆栈帧指针。当不用作帧指针 时, W14 可被指令当作普通的工作寄存器使用。 若要获取将W14用作堆栈帧指针的软件示例,请参见dsPIC30F Programmer's Reference Manual (DS70030)。 2.3.3 堆栈指针上溢 有一个与堆栈指针相关的堆栈极限寄存器 (SPLIM),复位时为 0x0000。 SPLIM 是一个 16 位 寄存器,但是 SPLIM<0> 被固定为 “0”,因为所有的堆栈操作必须字对齐。 直到一个字写入 SPLIM 后才使能堆栈上溢检查,在此之后,只能通过器件复位禁止堆栈上溢检 查。所有将 W15 用作源或目标寄存器而产生的有效地址将与 SPLIM 中的值作比较。如果堆栈指 针 (W15)的内容比 SPLIM 寄存器的内容大 2,并且执行了进栈操作,将不会产生堆栈错误陷 阱 (Stack Error Trap)。堆栈错误陷阱将在随后的进栈操作时产生。所以,例如,如果想要在 堆栈指针递增超出RAM中的地址0x2000时,引起堆栈错误陷阱,可将SPLIM初始化为0x1FFE。 如果已经使能了堆栈上溢检查,则当 W15 有效地址计算越过了数据空间的末尾 (0xFFFF)时, 也将产生堆栈错误陷阱。 更多有关堆栈错误陷阱的信息,请参见第 6 章 “复位中断”。 2.3.4 堆栈指针下溢 发生复位时,堆栈初始化为 0x0800。如果堆栈指针地址小于 0x0800,堆栈错误陷阱将会产生。 0x0000 0xFFFE 0x05A5A 0x03636 0x3636 → W3 W15 = 0x0802 POP W3 0x0802 0x0800 W15 注: 堆栈错误陷阱可以由任何使用W15寄存器的内容来产生有效地址(Effective Address, EA)的指令引起。所以,如果 W15 的内容比 SPLIM 寄存器的内容大 2,并且执行了 一条 CALL 指令或发生了中断,那么将产生堆栈错误陷阱。 注: 对堆栈指针极限寄存器 SPLIM 的写操作后面不应紧跟一个使用 W15 的间接读操作。 注: 一般而言,数据空间中 0x0000 和 0x07FF 之间的单元预留给内核和外设的特殊功能 寄存器
第2章CPU 2.4 CPU寄存器描述 2.4.1 SR:CPU状态寄存器 dsPIC30F的CPU有一个16位状态寄存器(SR),它的低字节称为低状态寄存器(Lower Status Register,SRL)。SR的高字节称为SRH。寄存器2-1中给出了对SR的详细描述。 SRL包含了所有的MCU ALU操作状态标志,加上CPU中断优先级状态位IPL<2:O>和REPEAT 循环有效状态位RA(SR<4>)。异常处理期间,SRL与PC的MSB相连形成一个完整的字值, 然后将该字值压入堆栈。 SRH包含DSP加法器I减法器状态位、DO循环有效位DA(SR<9>)和辅助进位标志位DC (SR<8>)。 2 SR位可读I写,但以下各位例外: 1.DA位(SR<8>):DA是只读位. 2.RA位(SR<4>):RA是只读位. 3.OA、OB(SR<15:14>)和OAB(SR<11>)位:这些位是只读位而且只能被DSP引擎 硬件修改。 4.SA、SB(SR<13:12>)和SAB(SR<10>)位:这些位是只读只清零的,而且只能被 DSP引擎硬件置1。一旦被置1,它们就保持置位状态直到被用户清零,与任何随后的 DSP操作的结果无关。 注: 清零SAB位的同时将清零SA和SB位。 注: dsPIC30 F Programmer's Reference Manual(DS70030)中提供了对受各条指令影 响的SR位的描述。 2.4.2 CORCON:内核控制寄存器 CORCON寄存器包含控制DSP乘法器和DO循环硬件操作的位。CORCON寄存器还包含IPL3 状态位,它与PL<2:0>(SR<7:5>)相连形成CPU中断优先级。 2005 Microchip Technology Inc. DS70049CCN第2-11页
© 2005 Microchip Technology Inc. DS70049C_CN 第 2-11 页 第 2 章 CPU CPU 2 2.4 CPU 寄存器描述 2.4.1 SR:CPU 状态寄存器 dsPIC30F 的 CPU 有一个 16 位状态寄存器(SR),它的低字节称为低状态寄存器(Lower Status Register, SRL)。 SR 的高字节称为 SRH。寄存器 2-1 中给出了对 SR 的详细描述。 SRL 包含了所有的 MCU ALU 操作状态标志,加上 CPU 中断优先级状态位 IPL<2:0> 和 REPEAT 循环有效状态位 RA(SR<4>)。异常处理期间,SRL 与 PC 的 MSB 相连形成一个完整的字值, 然后将该字值压入堆栈。 SRH 包含 DSP 加法器 / 减法器状态位、 DO 循环有效位 DA (SR<9>)和辅助进位标志位 DC (SR<8>)。 SR 位可读 / 写,但以下各位例外: 1. DA 位 (SR<8>):DA 是只读位。 2. RA 位 (SR<4>):RA 是只读位。 3. OA、 OB (SR<15:14>)和 OAB (SR<11>)位:这些位是只读位而且只能被 DSP 引擎 硬件修改。 4. SA、 SB (SR<13:12>)和 SAB (SR<10>)位:这些位是只读只清零的,而且只能被 DSP 引擎硬件置 1。一旦被置 1,它们就保持置位状态直到被用户清零,与任何随后的 DSP 操作的结果无关。 2.4.2 CORCON:内核控制寄存器 CORCON 寄存器包含控制 DSP 乘法器和 DO 循环硬件操作的位。 CORCON 寄存器还包含 IPL3 状态位,它与 IPL<2:0> (SR<7:5>)相连形成 CPU 中断优先级。 注: 清零 SAB 位的同时将清零 SA 和 SB 位。 注: dsPIC30F Programmer's Reference Manual (DS70030)中提供了对受各条指令影 响的 SR 位的描述