[MCU] 中断函数是如何被识别的

[复制链接]
2085|6
 楼主| pkuzhx 发表于 2015-7-9 10:03 | 显示全部楼层 |阅读模式
例如,在如下一段代码中:
  1. /* 1 second interval when assuming 1 MHz clock frequency and 1024x prescaling */
  2. #define TOP (1000000/1024)

  3. /**************************************************************************//**
  4. * [url=home.php?mod=space&uid=247401]@brief[/url] Initialize TIMER0 in Up/Down Count mode and to give interrupts when
  5. * turning from counting up to down (overflow) and from down to up (underflow)
  6. *****************************************************************************/
  7. void initTimer()
  8. {  
  9.   TIMER_Init_TypeDef initValues = TIMER_INIT_DEFAULT;
  10.   
  11.   /* Enable clock for TIMER0 */
  12.   CMU_ClockEnable(cmuClock_TIMER0, true);
  13.   
  14.   /* Enable underflow and overflow interrupt for TIMER0*/
  15.   TIMER_IntEnable(TIMER0, TIMER_IF_OF);
  16.   TIMER_IntEnable(TIMER0, TIMER_IF_UF);
  17.   
  18.   /* Enable TIMER0 interrupt vector in NVIC */
  19.   NVIC_EnableIRQ(TIMER0_IRQn);
  20.   
  21.   /* Set TIMER0 Top value */
  22.   TIMER_TopSet(TIMER0, TOP);
  23.   
  24.   /* Initialize TIMER0 in Up/Down mode with 1024x prescaling */
  25.   initValues.prescale = timerPrescale1024;
  26.   initValues.mode     = timerModeUpDown;
  27.   TIMER_Init(TIMER0, &initValues);
  28.   
  29.   /* Start TIMER0 */
  30.   TIMER0->CMD = TIMER_CMD_START;
  31. }


  32. /**************************************************************************//**
  33. * @brief TIMER0 Interrupt Handler. Writes status to LCD display
  34. *****************************************************************************/
  35. void TIMER0_IRQHandler(void)
  36. {

  37.   /* Store the interrupt flags before clearing */
  38.   uint16_t intFlags = TIMER_IntGet(TIMER0);
  39.   
  40.   /* Clear the interrupt flags. Only clear the flags that were stored in */
  41.   /* intFlags in case other flags have been set since then */
  42.   TIMER_IntClear(TIMER0, intFlags);

  43.   /* Overflow interrupt occured */
  44.   if(intFlags & TIMER_IF_OF)
  45.   {
  46.     SegmentLCD_Write("OVER");
  47.   }
  48.   
  49.   /* Underflow interrupt occured */
  50.   if(intFlags & TIMER_IF_UF)
  51.   {
  52.     SegmentLCD_Write("UNDER");
  53.   }
  54. }


  55. /**************************************************************************//**
  56. * @brief Main function
  57. *****************************************************************************/
  58. int main(void)
  59. {  
  60.   /* Chip revision alignment and errata fixes */
  61.   CHIP_Init();
  62.   
  63.   /* Set system frequency to 1 MHz */
  64.   CMU_HFRCOBandSet(cmuHFRCOBand_1MHz);
  65.   
  66.   /* Initialize LCD */
  67.   SegmentLCD_Init(false);

  68.   /* Initialize TIMER0 */
  69.   initTimer();
  70.   
  71.   /* Go to EM1 when not servicing interrupts */
  72.   while(1)
  73.   {
  74.     EMU_EnterEM1();
  75.   }
  76. }


当产生中断时,系统如何知道要去调用TIMER0_IRQHandler函数,而不是其他函数?
又是一个新手问题,烦请各位高手指点。
dirtwillfly 发表于 2015-7-9 11:19 | 显示全部楼层
有中断向量表。发生中断,就会转到相应的中断向量表,向量表里有中断服务程序的入口地址。
南宫云明 发表于 2015-7-9 11:20 | 显示全部楼层
TIMER0_IRQHandler这个函数应该在启动文件里声明了吧,绑定了一个中断向量号的。。。。
 楼主| pkuzhx 发表于 2015-7-9 11:45 | 显示全部楼层
南宫云明 发表于 2015-7-9 11:20
TIMER0_IRQHandler这个函数应该在启动文件里声明了吧,绑定了一个中断向量号的。。。。 ...

我看到有gpio中断的函数,在中断产生的函数里就指明了发生中断时调用哪个函数。
timer中断没有说明,我就有点费解了。你这么说我有点明白了,就是在某个文件里声明了当timer0中断时,就调用TIMER0_IRQHandler这个函数。
 楼主| pkuzhx 发表于 2015-7-9 11:46 | 显示全部楼层
dirtwillfly 发表于 2015-7-9 11:19
有中断向量表。发生中断,就会转到相应的中断向量表,向量表里有中断服务程序的入口地址。 ...

第一次用中断,对中断的理解太浅了。
ningling_21 发表于 2015-7-9 11:57 | 显示全部楼层
pkuzhx 发表于 2015-7-9 11:46
第一次用中断,对中断的理解太浅了。

用多了就熟悉了
ff8zgs 发表于 2015-7-11 15:41 | 显示全部楼层
单片机每一个中断都有一个中断向量,51实际就是一个固定的地址,当硬件发生中断后,MCU自动跳转到这个固定地址。而这个地址只是一个长跳转指令,跳转到中断服务函数。MCU执行完中断服务函数再回到中断前的地方。(当然所有的跳转都有现场的保护)
您需要登录后才可以回帖 登录 | 注册

本版积分规则

45

主题

730

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部