【摘要】:CPU的主要任务是保证程序的正确执行。图4-17内核结构图为了得到最大程度的性能以及并行性,AVR采用了Harvard结构,具有独立的数据和程序总线。CPU在执行一条指令的同时读取下一条指令。图4-19CPU 32个通用工作寄存器的结构2.通用寄存器寄存器文件针对AVR增强型RISC指令集做了优化。为了获得需要的性能和灵活性,寄存器文件支持以下的输入/输出方案,图4-19所示为CPU 32个通用工作寄存器的结构。
本节从总体上讨论AVR内核的结构,如图4-17所示。CPU的主要任务是保证程序的正确执行。因此它必须能够访问存储器、执行运算、控制外设以及处理中断。
图4-17 内核结构图
为了得到最大程度的性能以及并行性,AVR采用了Harvard结构,具有独立的数据和程序总线。程序存储器的指令通过一级流水线运行。CPU在执行一条指令的同时读取下一条指令(在本文称为预取)。这个概念实现了指令的单时钟周期运行。程序存储器为可以在线编程的Flash。
快速访问寄存器文件包括32个8位通用工作寄存器,访问时间为一个时钟周期,从而可以实现单时钟周期的ALU操作。在典型的ALU操作过程中,两个位于寄存器文件的操作数同时被访问,然后执行相应的运算,结果再送回寄存器文件。整个过程仅需要一个时钟周期。寄存器文件里有6个寄存器可以用作3个16位的间接寻址寄存器指针以寻址数据空间,实现高效的地址运算。其中一个指针还可以作为程序存储器查询表的地址指针。这些附加的功能寄存器即16位的X、Y、Z寄存器。
ALU支持寄存器之间以及寄存器和常数之间的算术与逻辑运算。ALU也可以执行单寄存器操作。运算完成之后状态寄存器的内容将更新以反映操作结果。程序流程通过有/无条件的跳转指令和调用指令来控制,从而直接寻址整个地址空间。大多数指令长度为16位,即每个程序存储器地址都包含一条16位或32位的指令。程序存储器空间分为引导程序区和应用程序区,这两个区都有专门的锁定位以实现读和读/写保护。写应用程序区的SPM指令必须位于引导程序区。
在中断和调用子程序时返回地址的程序计数器(PC)保存于堆栈之中。堆栈位于通用数据SRAM,故此嵌套深度仅受限于SRAM的大小。在复位例程里用户首先要初始化堆栈指针SP,这个指针位于I/O空间,可以进行读写访问。数据SRAM可以通过5种不同的寻址模式进行访问。
AVR存储器为线性的平面结构。AVR具有一个灵活的中断模块。控制寄存器位于I/O空间。状态寄存器里有全局中断使能位。每个中断在中断向量表里都有独立的中断向量。各个中断的优先级与其在中断向量表的位置有关,中断向量地址越低,优先级越高。
I/O存储器空间包含64个可以直接寻址的地址,作为CPU外设的控制寄存器、SPI及其他I/O功能,映射到数据空间,即寄存器文件之后的地址0x20~0x5F。此外,ATmega48/88/168还有位于SRAM地址0x60~0xFF的扩展I/O空间,这些地址只能使用ST/STS/STD和LD/LDS/LDD指令来访问。
AVR ALU与32个通用工作寄存器直接相连。寄存器与寄存器之间、寄存器与立即数之间的ALU运算只需要一个时钟周期。ALU操作分为三类:算术、逻辑和位操作。此外,还提供了支持无/有符号数和分数乘法的乘法器。
1.状态寄存器
状态寄存器包含了最近执行的算术指令的结果信息,这些信息可以用来改变程序流程以实现条件操作,如指令集所述,所有ALU运算都将影响状态寄存器的内容。这样,在许多情况下就不需要专门的比较指令了,从而使系统运行更快速,代码效率更高。在进入中断服务程序时状态寄存器不会自动保存;中断返回时也不会自动恢复,这些工作需要软件来处理。
AVR中断寄存器SREG的定义如图4-18所示。
(1)Bit7-I:全局中断使能。置位时使能全局中断。单独的中断使能由其他独立的控制寄存器控制。如果I清零,则不论单独中断标志置位与否,都不会产生中断。任意一个中断发生后I清零,而执行RETI指令后置位以使能中断。I也可以通过SEI和CLI指令来置位和清零。
图4-18 AVR中断寄存器SREG的定义
(2)Bit6-T:位拷贝存储。位拷贝指令BLD和BST利用T作为目的或源地址。BST把寄存器的某一位拷贝到T,而BLD把T拷贝到寄存器的某一位。
(3)0Bit5-H:半进位标志。半进位标志H表示算术操作发生了半进位,此标志对于BCD运算非常有用。
(4)Bit4-S:符号位,S=N⊕V。S为负数标志N与2的补码溢出标志V的异或。
(5)Bit3-V:2的补码溢出标志,支持2的补码运算。
(6)Bit2-N:负数标志,表明算术或逻辑操作结果为负。
(7)Bit1-Z:零标志,表明算术或逻辑操作结果为零。
(8)Bit0-C:进位标志,表明算术或逻辑操作发生了进位。
图4-19 CPU 32个通用工作寄存器的结构
2.通用寄存器
寄存器文件针对AVR增强型RISC指令集做了优化。为了获得需要的性能和灵活性,寄存器文件支持以下的输入/输出方案,图4-19所示为CPU 32个通用工作寄存器的结构。
(1)输出一个8位位操作数,输入一个8位结果。
(2)输出两个8位位操作数,输入一个8位结果。
(3)输出两个8位位操作数,输入一个16位结果。
(4)输出一个16位位操作数,输入一个16位结果。
大多数操作寄存器文件的指令都可以直接访问所有的寄存器,而且多数这样的指令的执行时间为单时钟周期。如图4-19所示,每个寄存器都有一个数据内存地址将它们直接映射到用户数据空间的头32个地址。虽然寄存器文件的物理实现不是SRAM,这种内存组织方式在访问寄存器方面具有极大的灵活性,因为X、Y、Z寄存器可以设置为指向任意寄存器的指针。
3.X、Y、Z寄存器
寄存器R26~R31除了用作通用寄存器外,还可以作为数据间接寻址用的地址指针。三个间接寻址寄存器如图4-20所示。
图4-20 三个间接寻址寄存器
在不同的寻址模式中,这些地址寄存器可以实现固定偏移量,自动加一和自动减一操作。
4.堆栈指针
堆栈指针主要用来保存临时数据、局部变量和中断/子程序的返回地址。堆栈指针总是指向堆栈的顶部。要注意AVR的堆栈是向下生长的,即新数据推入堆栈时,堆栈指针的数值将减小。堆栈指针指向数据SRAM堆栈区,在此聚集了子程序和中断堆栈。调用子程序和使能中断之前首先要定义堆栈空间,而且堆栈指针必须指向高于0x0100的地址空间,最好为RAMEND。使用PUSH指令将数据推入堆栈时指针减一;而子程序或中断返回地址推入堆栈时指针将减二。使用POP指令将数据弹出堆栈时,堆栈指针加一;而用RET或RETI指令从子程序或中断返回时堆栈指针加二。AVR的堆栈指针由I/O空间中的两个8位寄存器实现,实际使用的位数与具体器件有关。注意到某些AVR器件的数据区太小,用SPL就足够了,此时将不给出SPH寄存器。
5.复位与中断处理
AVR有不同的中断源,如图4-21所示。每个中断和复位在程序空间都有自己独立的中断向量,所有中断事件都有自己的使能位。在使能位置位且状态寄存器的全局中断使能位I也置位的情况下,中断可以发生。根据不同的程序计数器PC数值,在引导(Boot)锁定位BLB02或BLB12被编程的情况下,中断可能自动禁止。这个特性提高了软件的安全性。
图4-21 复位与中断处理
程序存储区的最低地址默认为复位向量和中断向量。
列表也决定了不同中断的优先级。向量所在的地址越低,优先级越高。RESET具有最高的优先级,下一个则为INT0–外部中断请求0。通过置位MCU控制寄存器MCUCR的IVSEL中断向量可以移至引导Flash的起始处。编程熔丝位BOOTRST可以将复位向量也移至引导Flash的起始处。
任一中断发生时全局中断使能位I被清零,所有其他中断都被禁止。用户软件可以通过置位I来实现中断嵌套。此时所有的中断都可以中断当前中断服务程序。执行RETI指令后全局中断使能位I自动置位。
从根本上说有两种类型的中断。第一种由事件触发并置位中断标志。对于这些中断,程序计数器跳转到实际的中断向量以执行中断处理例程,同时硬件将清除相应的中断标志,中断标志也可以通过对其写“1”来清除。当中断发生后,如果相应的中断使能位为“0”,则中断标志位置位,并一直保持到中断执行或者被软件清除。类似地,如果全局中断标志被清零,则所有已发生的中断都不会被执行,直到I置位。然后被挂起的各个中断按中断优先级依次执行。
第二种类型的中断则是只要中断条件满足,就会一直触发。这些中断不需要中断标志。若中断条件在中断使能之前就消失了,中断不会被触发。
AVR退出中断后总是回到主程序并至少执行一条指令才可以去执行其他被挂起的中断。要注意的是,进入中断服务程序时状态寄存器不会自动保存;中断返回时也不会自动恢复,这些工作必须由用户通过软件来完成。使用CLI指令来禁止中断时,中断禁止立即生效。没有中断可以在执行CLI指令后发生,即使它是在执行CLI指令的同时发生的。
6.中断响应时间
AVR中断响应时间最少为4个时钟周期。4个时钟周期后,程序跳转到实际的中断处理例程。在这4个时钟期间,PC自动入栈。在通常情况下,中断向量为一个跳转指令,此跳转要花3个时钟周期。如果中断在一个多时钟周期指令执行期间发生,则在此多周期指令执行完毕后MCU才会执行中断程序。若中断发生时MCU处于休眠模式,中断响应时间还需增加4个时钟周期。此外还要考虑到不同的休眠模式所需要的启动时间,这个时间不包括在前面提到的时钟周期里。中断返回需要4个时钟,在此期间PC(2 B)将被弹出栈,堆栈指针加二,状态寄存器SREG的I置位。
相关推荐