ATmega16简介(三)ATmega16指令执行时序这一节介绍指令执行过程中的访问时序。AVRCPU由系统时钟clkCPU驱动。此时钟直接来自选定的时钟源。芯片内部不对此时钟进行分频。Figure6说明了由Harvard结构决定的并行取指和指令执行,以及可以进行快速访问的寄存器文件的概念。这是一个基本的流水线概念,性能高达1MIPS/MHz,具有优良的性价比、功能/时钟比、功能/功耗比。Figure7演示的是寄存器文件内部访问时序。在一个时钟周期里,ALU可以同时对两个寄存器操作数进行操作,同时将结果保存到目的寄存器中去。ATmega16复位与中断处理AVR有不同的中断源。每个中断和复位在程序空间都有独立的中断向量。所有的中断事件都有自己的使能位。当使能位置位,且状态寄存器的全局中断使能位I也置位时,中断可以发生。根据程序计数器PC的不同,在引导锁定位BLB02或BLB12被编程的情况下,中断可能被自动禁止。这个特性提高了软件的安全性。详见P247“存储器编程”的描述。程序存储区的最低地址缺省为复位向量和中断向量。完整的向量列表请参见P43“中断”。列表也决定了不同中断的优先级。向量所在的地址越低,优先级越高。RESET具有最高的优先级,第二个为INT0–外部中断请求0。通过置位MCU控制寄存器(MCUCR)的IVSEL,中断向量可以移至引导Flash的起始处。编程熔丝位BOOTRST也可以将复位向量移至引导Flash的起始处。具体参见P234“支持引导装入程序–在写的同时可以读(RWW,Read-While-Write)的自我编程能力”。任一中断发生时全局中断使能位I被清零,从而禁止了所有其他的中断。用户软件可以在中断程序里置位I来实现中断嵌套。此时所有的中断都可以中断当前的中断服务程序。执行RETI指令后I自动置位。从根本上说有两种类型的中断。第一种由事件触发并置位中断标志。对于这些中断,程序计数器跳转到实际的中断向量以执行中断处理程序,同时硬件将清除相应的中断标志。中断标志也可以通过对其写”1”的方式来清除。当中断发生后,如果相应的中断使能位为“0”,则中断标志位置位,并一直保持到中断执行,或者被软件清除。类似的,如果全局中断标志被清零,则所有已发生的中断都不会被执行,直到I置位。然后挂起的各个中断按中断优先级依次执行。第二种类型的中断则是只要中断条件满足,就会一直触发。这些中断不需要中断标志。若中断条件在中断使能之前就消失了,中断不会被触发。AVR退出中断后总是回到主程序并至少执行一条指令才可以去执行其他被挂起的中断。要注意的是,进入中断服务程序时状态寄存器不会自动保存,中断返回时也不会自动恢复。这些工作必须由用户通过软件来完成。使用CLI指令来禁止中断时,中断禁止立即生效。没有中断可以在执行CLI指令后发生,即使它是在执行CLI指令的同时发生的。下面的例子说明了如何在写EEPROM时使用这个指令来防止中断发生以避免对EEPROM内容的可能破坏。汇编代码例程inr16,SREG;保存SREGcli;禁止中断sbiEECR,EEMWE;启动EEPROM写操作sbiEECR,EEWEoutSREG,r16;恢复SREG(I位)C代码例程charcSREG;cSREG=SREG;/*保存SREG*//*禁止中断*/_CLI();EECR|=(1EEMWE);/*启动EEPROM写操作*/EECR|=(1EEWE);SREG=cSREG;/*恢复SREG(I位)*/使用SEI指令使能中断时,紧跟其后的第一条指令在执行任何中断之前一定会首先得到执行。汇编代码例程sei;置位全局中断使能标志sleep;进入休眠模式,等待中断发生;注意:在执行任何被挂起的中断之前MCU将首先进入休眠模式C代码例程_SEI();/*置位全局中断使能标志*/_SLEEP();/*进入休眠模式,等待中断发生*//*注意:在执行任何被挂起的中断之前MCU将首先进入休眠模式*/AVR中断响应时间最少为4个时钟周期。4个时钟周期后,程序跳转到实际的中断处理例程。在这4个时钟期期间PC自动入栈。在通常情况下,中断向量为一个跳转指令,此跳转需要3个时钟周期。如果中断在一个多时钟周期指令执行期间发生,则在此多周期指令执行完毕后MCU才会执行中断程序。若中断发生时MCU处于休眠模式,中断响应时间还需增加4个时钟周期。此外还要考虑到不同的休眠模式所需要的启动时间。这个时间不包括在前面提到的时钟周期里。中断返回需要4个时钟。在此期间PC(两个字节)将被弹出栈,堆栈指针加二,状态寄存器SREG的I置位。ATmega16Flash程序存储器系统内可编程的Flash程序存储器ATmega16具有16K字节的在线编程Flash,用于存放程序指令代码。因为所有的AVR指令为16位或32位,故而Flash组织成8Kx16位的形式。用户程序的安全性要根据Flash程序存储器的两个区:引导(Boot)程序区和应用程序区,分开来考虑。Flash存储器至少可以擦写10,000次。ATmega16的程序计数器(PC)为13位,因此可以寻址8K字的程序存储器空间。引导程序区以及相关的软件安全锁定位请参见P234“支持引导装入程序–在写的同时可以读(RWW,Read-While-Write)的自我编程能力”,而P247“存储器编程”详述了用SPI或JTAG接口实现对Flash的串行下载。常数可以保存于整个程序存储器地址空间(参考LPM加载程序存储器指令的说明)。取指与执行时序图请参见P11“指令执行时序”。ATmega16SRAM数据存储器SRAM数据存储器Figure9给出了ATmega16SRAM空间的组织结构。前1120个数据存储器包括了寄存器文件、I/O存储器及内部数据SRAM。起始的96个地址为寄存器文件与64个I/O存储器,接着是1024字节的内部数据SRAM。数据存储器的寻址方式分为5种:直接寻址、带偏移量的间接寻址、间接寻址、带预减量的间接寻址和带后增量的间接寻址。寄存器文件中的寄存器R26到R31为间接寻址的指针寄存器。直接寻址范围可达整个数据区。带偏移量的间接寻址模式能够寻址到由寄存器Y和Z给定的基址附近的63个地址。在自动预减和后加的间接寻址模式中,寄存器X、Y和Z自动增加或减少。ATmega16的全部32个通用寄存器、64个I/O寄存器及1024个字节的内部数据SRAM可以通过所有上述的寻址模式进行访问。寄存器文件的描述见P9“通用寄存器文件”。SRAM数据存储器访本节说明访问内部存储器的时序。如Figure10所示,内部数据SRAM访问时间为两个clkCPU时钟。ATmega16EEPROM数据存储器ATmega16包含512字节的EEPROM数据存储器。它是作为一个独立的数据空间而存在的,可以按字节读写。EEPROM的寿命至少为100,000次擦除周期。EEPROM的访问由地址寄存器、数据寄存器和控制寄存器决定。通过SPI和JTAG及并行电缆下载EEPROM数据的操作请分别参见P260、P265及P250。EEPROM读/写访问EEPROM读/写访问EEPROM的访问寄存器位于I/O空间。EEPROM的写访问时间由Table1给出。自定时功能可以让用户软件监测何时可以开始写下一字节。用户操作EEPROM需要注意如下问题:在电源滤波时间常数比较大的电路中,上电/下电时VCC上升/下降速度会比较慢。此时CPU可能工作于低于晶振所要求的电源电压。请参见P20“防止EEPROM数据丢失”以避免出现EEPROM数据丢失的问题。为了防止无意识的EEPROM写操作,需要执行一个特定的写时序。具体参看EEPROM控制寄存器的内容。执行EEPROM读操作时,CPU会停止工作4个周期,然后再执行后续指令;执行EEPROM写操作时,CPU会停止工作2个周期,然后再执行后续指令。EEPROM地址寄存器-EEARH和EEARL?Bits15..9–Res:保留保留位,读操作返回值为零。?Bits8..0–EEAR8..0:EEPROM地址EEPROM地址寄存器–EEARH和EEARL指定了512字节的EEPROM空间。EEPROM地址是线性的,从0到511。EEAR的初始值没有定义。在访问EEPROM之前必须为其赋予正确的数据。EEPROM数据寄存器-EEDR?Bits7..0–EEDR7.0:EEPROM数据对于EEPROM写操作,EEDR是需要写到EEAR单元的数据;对于读操作,EEDR是从地址EEAR读取的数据。EEPROM控制寄存器-EECR?Bits7..4–Res:保留保留位,读操作返回值为零。?Bit3–EERIE:使能EEPROM准备好中断若SREG的I为1,则置位EERIE将使能EEPROM准备好中断。清零EERIE则禁止此中断。当EEWE清零时EEPROM准备好中断即可发生。?Bit2–EEMWE:EEPROM主机写使能EEMWE决定了EEWE置位是否可以启动EEPROM写操作。当EEMWE为1时,在4个时钟周期内置位EEWE将把数据写入EEPROM的指定地址;若EEMWE为0“,则操作EEWE不起作用。EEMWE置位后4个周期,硬件对其清零。见EEPROM写过程中对EEWE位的描述。?Bit1–EEWE:EEPROM写使能EEWE为EEPROM写操作的使能信号。当EEPROM数据和地址设置好之后,需置位EEWE以便将数据写入EEPROM。此时EEMWE必须置位,否则EEPROM写操作将不会发生。写时序如下(第3步和第4步的次序并不重要):1.等待EEWE位变为零2.等待SPMCSR中的SPMEN位变为零3.将新的EEPROM地址写入EEAR(可选)4.将新的EEPROM数据写入EEDR(可选)5.对EECR寄存器的EEMWE写1,同时清零EEWE6.在置位EEMWE的4个周期内,置位EEWE在CPU写Flash存储器的时候不能对EEPROM进行编程。在启动EEPROM写操作之前软件必须检查Flash写操作是否已经完成。步骤(2)仅在软件包含引导程序并允许CPU对Flash进行编程时才有用。如果CPU永远都不会写Flash,步骤(2)可省略。请参见P234“支持引导装入程序–在写的同时可以读(RWW,Read-While-Write)的自我编程能力”。注意:如果在步骤5和6之间发生了中断,写操作将失败。因为此时EEPROM写使能操作将超时。如果一个操作EEPROM的中断打断了另一个EEPROM操作,EEAR或EEDR寄存器可能被修改,引起EEPROM操作失败。建议此时关闭全局中断标志I。经过写访问时间之后,EEWE硬件清零。用户可以凭借这一位判断写时序是否已经完成。EEWE置位后,CPU要停止两个时钟周期才会运行下一条指令。?Bit0–EERE:EEPROM读使能EERE为EEPROM读操作的使能信号。当EEPROM地址设置好之后,需置位EERE以便将数据读入EEAR。EEPROM数据的读取只需要一条指令,且无需等待。读取EEPROM后CPU要停止4个时钟周期才可以执行下一条指令。用户在读取EEPROM时应该检测EEWE。如果一个写操作正在进行,就无法读取EEPROM,也无法改变寄存器EEAR。经过校准的片内振荡器用于EEPROM定时。Table1为CPU访问EEPROM的典型时间。下面的代码分别用汇编和C函数说明如何实现EEPROM的写操作。在此假设中断不会在执行这些函数的过程当中发生。同时还假设软件没有BootLoader。若BootLoader存在,则EEPROM写函数还需要等待正在运行的SPM命令的结束。汇编代码例程EEPROM_write:;等待上一次写操作结束sbicEECR,EEWErjmpEEPROM_write;设置地址寄存器(r18:r17)outEEARH,r18outEEARL,r17;将数据写入数据寄存器(r16)outEEDR,r16;置位EEMWEsbiEECR,EEMWE;置位EEWE以启动写操作sbiEECR,EE