/*关闭WDT*/
WDTCR=0x00;
}
ATmega16中断向量
本节描述ATmega16的中断处理。
Table19给出了不同的BOOTRST/IVSEL设置下的复位和中断向量的位置。
如果程序永远不使能中断,中断向量就没有意义。
用户可以在此直接写程序。
同样,如果复位向量位于应用区,而其他中断向量位于Boot区,则复位向量之后可以直接写程序。
反过来亦是如此。
ATmega16典型的复位和中断设置如下:
地址 符号代码说明
$000jmpRESET;复位中断向量
$002jmpEXT_INT0;IRQ0中断向量
$004jmpEXT_INT1;IRQ1中断向量
$006jmpTIM2_COMP;Timer2比较中断向量
$008jmpTIM2_OVF;Timer2溢出中断向量
$00AjmpTIM1_CAPT;Timer1捕捉中断向量
$00CjmpTIM1_COMPA;Timer1比较A中断向量
$00EjmpTIM1_COMPB;Timer1比较B中断向量
$010jmpTIM1_OVF;Timer1溢出中断向量
$012jmpTIM0_OVF;Timer0溢出中断向量
$014jmpSPI_STC;SPI传输结束中断向量
$016jmpUSART_RXC;USARTRX结束中断向量
$018jmpUSART_UDRE;UDR空中断向量
$01AjmpUSART_TXC;USARTTX结束中断向量
$01CjmpADC;ADC转换结束中断向量
$01EjmpEE_RDY;EEPROM就绪中断向量
$020jmpANA_COMP;模拟比较器中断向量
$022jmpTWSI;两线串行接口中断向量
$024jmpEXT_INT2;IRQ2中断向量
$026jmpTIM0_COMP;定时器0比较中断向量
$028jmpSPM_RDY;SPM就绪中断向量
;
$02ARESET:
ldir16,high(RAMEND);主程序
$02BoutSPH,r16;设置堆栈指针为RAM的顶部
$02Cldir16,low(RAMEND)
$02DoutSPL,r16
$02Esei;使能中断
$02Fxxx
.........
当熔丝位BOOTRST未编程,Boot区为2K字节,且寄存器GICR的IVSEL置位时,典
型的复位和中断设置如下:
地址符号代码说明
$000RESET:
ldir16,high(RAMEND);主程序
$001outSPH,r16;设置堆栈指针为RAM的顶部
$002ldir16,low(RAMEND)
$003outSPL,r16
$004sei;使能中断
$005xxx
;
.org$1C02
$1C02jmpEXT_INT0;IRQ0中断向量
$1C04jmpEXT_INT1;IRQ1中断向量
.........;
$1C28jmpSPM_RDY;SPM就绪中断向量
当熔丝位BOOTRST已编程,且Boot区为2K字节时,典型的复位和中断设置如下:
地址符号代码说明
.org$002
$002jmpEXT_INT0;IRQ0中断向量
$004jmpEXT_INT1;IRQ1中断向量
.........;
$028jmpSPM_RDY;SPM就绪中断向量
;
.org$1C00
$1C00RESET:
ldir16,high(RAMEND);主程序
$1C01outSPH,r16;设置堆栈指针为RAM的顶部
$1C02ldir16,low(RAMEND)
$1C03outSPL,r16
$1C04sei;使能中断
$1C05xxx
当熔丝位BOOTRST已编程,Boot区为2K字节,且寄存器GICR的IVSEL置位时,典
型的复位和中断设置如下:
地址符号代码说明
.org$1C00
$1C00jmpRESET;Reset中断向量
$1C02jmpEXT_INT0;IRQ0中断向量
$1C04jmpEXT_INT1;IRQ1中断向量
.........;
$1C28jmpSPM_RDY;SPM就绪中断向量
;
$1C2ARESET:
ldir16,high(RAMEND);主程序
$1C2BoutSPH,r16;设置堆栈指针为RAM的顶部
$1C2Cldir16,low(RAMEND)
$1C2DoutSPL,r16
$1C2Esei;使能中断
$1C2Fxxx
在应用区和Boot区之间移动中断向量
通用中断控制寄存器决定中断向量表的放置地址
通用中断控制寄存器-GICR
?
Bit1–IVSEL:
中断向量选择
当IVSEL为"0“时,中断向量位于Flash存储器的起始地址;当IVSEL为"1“时,中断向量转移到Boot区的起始地址。
实际的Boot区起始地址由熔丝位BOOTSZ确定。
具体请参考P234“支持引导装入程序–在写的同时可以读(RWW,Read-While-Write)的自我编程能力”。
为了防止无意识地改变中断向量表,修改IVSEL时需要遵照如下过程:
1.置位中断向量修改使能位IVCE
2.在紧接的4个时钟周期里将需要的数据写入IVSEL,同时对IVCE写”0”
执行上述序列时中断自动被禁止。
其实,在置位IVCE时中断就被禁止了,并一直保持到写IVSEL操作之后的下一条语句。
如果没有IVSEL写操作,则中断在置位IVCE之后的4个时钟周期保持禁止。
需要注意的是,虽然中断被自动禁止,但状态寄存器的位I的值并不受此操作的影响。
Note:
若中断向量位于Boot区,且Boot锁定位BLB02被编程,则执行应用区的程序时中断被禁止;若中断向量位于应用区,且Boot锁定位BLB12被编程, 则执行Boot区的程序时中断被禁止。
有关Boot锁定位的细节请参见P234“支持引导装入程序–在写的同时可以读
(RWW,Read-While-Write)的自我编程能力”。
?
Bit0–IVCE:
中断向量修改使能
改变IVSEL时IVCE必须置位。
在IVCE或IVSEL写操作之后4个时钟周期,IVCE被硬件清零。
如前面所述,置位IVCE将禁止中断。
代码如下:
汇编代码例程:
Move_interrupts:
;使能中断向量的修改
ldir16,(1<outGICR,r16
;将中断向量转移到boot区
ldir16,(1<outGICR,r16
ret
C代码例程
voidMove_interrupts(void)
{
/*使能中断向量的修改*/
GICR=(1</*将中断向量转移到boot区*/
GICR=(1<}
ATmega16通用中断控制寄存器GICR
?
Bit1–IVSEL:
中断向量选择
当IVSEL为"0“时,中断向量位于Flash存储器的起始地址;当IVSEL为"1“时,中断向量转移到Boot区的起始地址。
实际的Boot区起始地址由熔丝位BOOTSZ确定。
具体请参考P234“支持引导装入程序–在写的同时可以读(RWW,Read-While-Write)的自我编程能力”。
为了防止无意识地改变中断向量表,修改IVSEL时需要遵照如下过程:
1.置位中断向量修改使能位IVCE
2.在紧接的4个时钟周期里将需要的数据写入IVSEL,同时对IVCE写”0”
执行上述序列时中断自动被禁止。
其实,在置位IVCE时中断就被禁止了,并一直保持到写IVSEL操作之后的下一条语句。
如果没有IVSEL写操作,则中断在置位IVCE之后的4个时钟周期保持禁止。
需要注意的是,虽然中断被自动禁止,但状态寄存器的位I的值并不受此操作的影响。
Note:
若中断向量位于Boot区,且Boot锁定位BLB02被编程,则执行应用区的程序时中断被禁止;若中断向量位于应用区,且Boot锁定位BLB12被编程,则执行Boot区的程序时中断被禁止。
有关Boot锁定位的细节请参见P234“支持引导装入程序–在写的同时可以读
(RWW,Read-While-Write)的自我编程能力”。
?
Bit0–IVCE:
中断向量修改使能
改变IVSEL时IVCE必须置位。
在IVCE或IVSEL写操作之后4个时钟周期,IVCE被硬件清零。
如前面所述,置位IVCE将禁止中断。
代码如下:
汇编代码例程:
Move_interrupts:
;使能中断向量的修改
ldir16,(1<outGICR,r16
;将中断向量转移到boot区
ldir16,(1<outGICR,r16
ret
C代码例程
voidMove_interrupts(void)
{
/*使能中断向量的修改*/
GICR=(1</*将中断向量转移到boot区*/
GICR=(1<}