单片机中断

**在51单片机中,中断向量表的地址是如何被设置的?**

在51单片机中,中断向量表的设置是中断系统的核心部分,它定义了中断服务程序的入口地址。以下是中断向量表的设置方法:

  1. 中断向量表的位置:51单片机的中断向量表通常位于程序存储器的起始位置,即地址 0x00000x000F(对于双字节的中断向量,实际占用 0x00000x001F)。这些地址是固定的,由单片机的硬件设计决定。

  2. 中断向量的分配:每个中断源都有一个与之对应的中断向量。例如,外部中断0的中断向量地址是 0x0003,定时器0的中断向量地址是 0x000B,以此类推。这些向量地址对应于中断服务程序的入口点。

  3. 中断服务程序的编写:在编写中断服务程序时,需要使用特定的语法来指定中断源和中断服务程序。例如,使用 interrupt 关键字来声明一个中断服务程序,并指定中断号。

  4. 中断向量表的初始化:在程序的初始化阶段,需要将中断向量表中的每个中断向量地址设置为相应中断服务程序的入口地址。这通常通过编写汇编指令或在C代码中使用特定的函数来完成。

  5. 中断优先级的设置:51单片机支持中断优先级,可以通过设置IP寄存器来配置不同中断源的优先级。

  6. 中断使能:在程序中,还需要通过设置IE寄存器来使能或禁用特定的中断源。

  7. 中断向量表的偏移:在某些情况下,可能需要将中断向量表放置在非起始位置,这可以通过编程改变中断向量表的基地址来实现。

以上步骤确保了当中断事件发生时,51单片机能够正确地跳转到相应的中断服务程序进行处理。在实际应用中,这些步骤需要根据具体的硬件设计和程序需求进行适当的调整。


**请问中断服务函数的代码存放在哪里呢**

在51单片机中,中断服务函数(Interrupt Service Routine, ISR)的代码存放位置通常由以下几个方面决定:

  1. 中断向量表:中断服务函数的入口地址通常在中断向量表中被指定。当中断发生时,单片机会自动从对应的中断向量地址读取指令指针(Instruction Pointer, IP)或程序计数器(Program Counter, PC)的值,跳转到相应的中断服务函数执行。

  2. 代码段(Code Section):中断服务函数的代码通常存放在代码段中,这是程序存储器(Flash)的一部分。在编程时,开发者需要确保中断服务函数的代码放在正确的位置,以便中断向量表可以正确地引用。

  3. 编程语言和编译器:如果你是使用C语言或汇编语言编写程序,编译器会负责将中断服务函数的代码放置在适当的位置。在C语言中,通常会使用特定的语法来声明中断服务函数,例如使用 interrupt 关键字。

  4. 链接脚本(Linker Script):在更复杂的嵌入式系统中,链接脚本可以用来指定代码段的位置,包括中断服务函数。链接脚本告诉编译器和链接器如何将代码和数据映射到内存中。

  5. 内存映射:在某些情况下,开发者可能会通过内存映射来手动指定中断服务函数的存储位置,尤其是在需要优化内存使用或处理特定硬件要求时。

例如,如果你使用Keil C51编译器编写51单片机的程序,中断服务函数可能会像下面这样定义:

void ExternalInterrupt0_ISR(void) interrupt 0 {
    // 外部中断0的中断服务代码
}

void Timer0_ISR(void) interrupt 1 {
    // 定时器0的中断服务代码
}

在上面的例子中,interrupt 0interrupt 1 分别告诉编译器这些函数是外部中断0和定时器0的中断服务函数。编译器会自动将这些函数的地址放置在中断向量表中正确的位置。

在汇编语言中,中断服务函数的代码会直接写在中断向量地址指向的地方,或者通过跳转指令(如LJMP)指向实际的中断服务代码位置。

总之,中断服务函数的代码存放位置是由中断向量表的配置、编程语言、编译器以及可能的链接脚本共同决定的。开发者需要确保这些元素正确配置,以确保中断能够被正确地处理。


**是不是中断向量表只是存储了,不同中断在flash 中的内存地址,而中断服务函数的代码并非存放在中断向量表所在的位置**

是的,您的理解是正确的。在51单片机中,中断向量表的作用是提供一个跳转地址,当中断发生时,单片机会通过这些地址跳转到相应的中断服务函数(ISR)去执行。这些跳转地址通常存储的是中断服务函数的入口地址,而不是中断服务函数的代码本身。

具体来说:

  1. 中断向量表:这个表位于Flash的起始地址区域(通常是0x0000开始的位置),每个条目包含一个或多个字节,指示相应中断服务程序的起始地址。例如,外部中断0的向量可能指向地址0x0003,定时器0中断的向量可能指向地址0x000B,等等。

  2. 中断服务函数(ISR):这些函数的代码存放在Flash的其他位置,具体位置由程序员在编写程序时安排,或者是通过编译器和链接器自动放置的。ISR的代码包含了实际处理中断的逻辑。

  3. 跳转机制:当中断发生时,单片机会自动查找对应的中断向量,获取中断服务函数的地址,然后跳转到该地址执行代码。这个过程是自动的,不需要程序员在代码中显式编写跳转指令。

  4. 编译器的作用:在编写程序时,程序员会使用特定的语法(如C语言中的interrupt关键字)来声明ISR。编译器在编译程序时,会将这些ISR的地址写入到中断向量表中相应的位置。

  5. 链接器的作用:链接器负责将程序的不同部分(代码、数据、堆栈等)映射到内存中的正确位置。它会根据程序员的代码和编译器生成的信息,将ISR的代码放置在Flash中适当的位置。

因此,中断向量表和中断服务函数的代码是分开存储的,中断向量表只是存储了跳转到ISR的地址,而ISR的代码则存放在Flash的其他位置。


给出某个单片机的中断向量表在内存中的模型图

在51单片机中,中断向量表是存储在程序存储器(通常是ROM或Flash)中的一个特殊区域,它包含了中断服务程序(ISR)的入口地址。当中断发生时,单片机通过查找中断向量表来获取ISR的地址,并跳转到相应的中断服务程序执行。

中断向量表的地址通常是固定的,对于标准的51单片机,中断向量区域从地址0x0000开始,一直到0x001F。每个中断源都有一个唯一的中断向量地址,例如:

  • 外部中断0的中断向量地址是0x0003
  • 定时器0的中断向量地址是0x000B
  • 定时器1的中断向量地址是0x0013
  • 串口中断的中断向量地址是0x001B

这些地址在单片机的硬件设计中是预设的,不可改变。中断服务程序的代码并不存放在中断向量表所在的位置,而是存放在程序存储器的其他位置。中断向量表中存储的只是指向这些中断服务程序的指针。

在实际编程中,开发者需要在这些预设的中断向量地址处放置正确的跳转指令,通常是一条跳转指令(如LJMP),指向实际的中断服务程序代码。例如,对于外部中断0,开发者会在地址0x0003处放置一条跳转到外部中断0服务程序的LJMP指令。

在C语言编程中,中断服务程序通常通过特定的语法定义,编译器会负责将这些中断服务程序的地址放置到正确的中断向量表位置。例如:

void ext_int0_isr(void) interrupt 0 {
    // 外部中断0的服务程序
}

在这个例子中,interrupt 0告诉编译器这是一个外部中断0的中断服务程序,编译器会自动将这个函数的地址放到外部中断0的中断向量地址处。

总的来说,51单片机的中断向量表模型图大致如下:

地址      中断源         描述
0x0000    复位            单片机复位后的起始地址
0x0003    外部中断0      跳转到外部中断0的服务程序
0x000B    定时器0        跳转到定时器0的服务程序
0x0013    定时器1        跳转到定时器1的服务程序
0x001B    串口中断      跳转到串口中断的服务程序
...       ...            ...

每个中断向量地址都对应一个中断源,存储着跳转到相应中断服务程序的指令。开发者在编写程序时,需要确保正确地设置了这些跳转指令,以便单片机能够正确响应中断。


·怎么没看到中断服务函数的地址·

在51单片机中,中断服务函数(ISR)的地址不是直接存放在中断向量表中的,而是通过中断向量表中的跳转指令间接指向的。中断向量表中的每个条目通常包含一个跳转指令(例如LJMP),这条指令会跳转到实际的中断服务函数的地址。

这里是一个简化的模型图,展示了51单片机中断向量表和中断服务函数地址的关系:

中断向量地址      内容                跳转到的中断服务函数地址
---------------------------------------------
0x0000            LJMP addr1        复位中断处理函数
0x0003            LJMP addr2        外部中断0处理函数
0x000B            LJMP addr3        定时器0中断处理函数
0x0013            LJMP addr4        定时器1中断处理函数
...              ...               ...

在上面的模型图中,addr1addr2addr3addr4 等代表中断服务函数在程序存储器中的实际地址。当中断发生时,单片机会执行中断向量地址处的跳转指令,跳转到对应的中断服务函数执行。

例如,如果外部中断0发生,单片机会自动跳转到地址0x0003处执行,那里会有一个LJMP指令,这条指令会跳转到实际编写的外部中断0的中断服务函数的地址。这个地址是开发者在编写程序时通过编程工具(如编译器或汇编器)设置的。

在实际编程中,开发者通常会使用C语言或汇编语言来编写中断服务函数,并在函数声明时使用特定的语法来告诉编译器这是一个中断服务函数。编译器在编译程序时会自动处理这些函数,将它们的地址正确地放置到中断向量表中。例如,在Keil C51编译器中,可以这样编写外部中断0的中断服务函数:

void ExternalInterrupt0_ISR(void) interrupt 0 {
    // 外部中断0的中断服务代码
}

在这个例子中,interrupt 0 关键字告诉编译器这个函数是外部中断0的中断服务函数。编译器会确保这个函数的地址被放置到外部中断0的中断向量表条目中(通常是0x0003),但不是直接放置函数代码,而是放置一个跳转到这个函数的跳转指令。

你可能感兴趣的:(STM32单片机,原理解析篇,单片机,嵌入式硬件)