首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C语言中的中断处理

C语言中的中断处理
EN

Stack Overflow用户
提问于 2015-03-23 22:30:12
回答 1查看 4.4K关注 0票数 0

下面的C代码中有两个中断。

第一种是通过使用Key0,它具有以下属性:一旦按下Key0,就会写入一个"D“。不久之后,一旦程序恢复运行,就会写一个"d“,这是假设我仍然在按住按钮。松开此按钮后,将打印出一个"U“。

如果我没有按住按钮,就会打印出一个"dU“,使代码变成"DdU”。

第二种方法是使用切换键,它具有以下属性:一旦我们切换切换键,程序就会打印一个"S“。不久之后,打印出一个"s“。

现在我的问题如下:在首先使用key0,然后使用togglekey时,Key0能够中断程序,同时togglekey被忽略。所以我们只得到"DdU“,而"S”和"s“都被忽略了。

现在我不明白为什么反之亦然。确实如此,但仅在一定程度上如此。在第一次切换时,"S“被写入,"D”和"d“被跳过。"s“被写出来了,但现在出现了令人困惑的部分=>为什么"U”会写在最后?为什么key0的"D“和"d”被忽略,而它的"U“却不被忽略?

代码语言:javascript
复制
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* Include header file for alt_irq_register() */
#include <sys/alt_irq.h>

/* Define the null pointer */
#define NULL_POINTER ( (void *) 0)

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void out_char_uart_0( int c )
{
  /* Wait until transmitter is ready */
  while( (UART_0[2] & 0x40) == 0 );
  /* Now send character */
  UART_0[1] = c & 0xff;
}

/* This simple subroutine stalls
 * execution for a short while. */
void somedelay( void )
{
  int i = DELAYPARAM;
  while( (i = i - 1) > 0);
}

/* This simple subroutine stalls
 * execution for a long while. */
void bigdelay( void )
{
  int j = BIGDELAYPARAM;
  while( (j = j - 1) > 0) somedelay();
}

void keys_isr( void * context )
{
  /* Read edge capture register of the de2_pio_keys4 device. */
  int edges = *de2_pio_keys4_edgecap;
  /* Clear edge capture register - writing
   * any value clears all bits. */
  *de2_pio_keys4_edgecap = 0;
  /* If action on KEY0 */
  if( edges & 1 )
  {
    /* If KEY0 is pressed now */
    if( (*de2_pio_keys4_base & 1) == 0 )
    {
      /* Turn on green LED LEDG0
       * in software copy of LED bits. */
      myleds = myleds | 1;
      /* Copy software LED bits to actual LEDs. */
      *de2_pio_greenled9 = myleds;

      /* Print an upper-case 'D' using out_char_uart_0. */
      out_char_uart_0( 'D' );

      /* Wait a long while */
      bigdelay();
      /* Print a lower-case 'd' using out_char_uart_0. */
      out_char_uart_0( 'd' );
    }
    /* If KEY0 is released now */
    else if( (*de2_pio_keys4_base & 1) != 0 )
    {
      /* Turn off green LED LEDG0
       * in software copy of LED bits. */
      myleds = myleds & 0xffffe;

      /* Print an 'U' using out_char_uart_0. */
      out_char_uart_0( 'U' );
      /* Copy software LED bits to actual LEDs. */
      *de2_pio_greenled9 = myleds;
    }
  }
}

/*
 * Initialize de2_pio_keys4 for interrupts.
 */
void keysinit_int( void )
{
  /* Declare a temporary for checking return values
   * from system-calls and library functions. */
  register int ret_val_check;

  /* Disable interrupts for de2_pio_keys4,
   * if they were enabled.
   *
   * The function alt_irq_disable returns an int,
   * which always has the value 0.
   * We use a type cast to void to tell the compiler
   * that we really want to ignore the return value. */
  (void) alt_ic_irq_disable( 0, de2_pio_keys4_intindex );

  /* Allow interrupts from KEY0 only. */
  *de2_pio_keys4_intmask = 1;

  /* Set up Altera's interrupt wrapper for
   * interrupts from the de2_pio_keys4 dev-ice.
   * The function alt_irq_register will enable
   * interrupts from de2_pio_keys4.
   * Return value is zero for success,
   * nonzero for failure. */
  ret_val_check = alt_ic_isr_register(0,de2_pio_keys4_intindex,keys_isr,NULL_POINTER,NULL_POINTER );
  /* If there was an error, terminate the program. */
  if( ret_val_check != 0 ) n2_fatal_error();
}
/*
 * Interrupt handler for timer_1.
 * The parameters are ignored here, but are
 * required for correct compilation.
 * The type alt_u32 is an Altera-defined
 * unsigned integer type.
 */
void timer_isr( void * context )
{
  *timer_1_status = 0; /* Acknowledge interrupt */
  tick( &mytime );
  puttime( &mytime );
}

/*
 * Initialize timer_1 for regular interrupts,
 * once every timeout period.
 * The timeout period is defined above,
 * see definition of TIMER_1_TIMEOUT
 */
void timerinit_int( void )
{
  /* Declare a local temporary variable
   * for checking return values
   * from system-calls and library functions. */
  register int ret_val_check;

  /* Disable interrupts for timer_1,
   * if they were enabled.
   *
   * The function alt_irq_disable returns an int,
   * which always has the value 0.
   * We use a type cast to void to tell the compiler
   * that we really want to ignore the return value. */
  (void) alt_ic_irq_disable( 0, timer_1_intindex );

  *timer_1_period_low = TIMER_1_TIMEOUT & 0xffff;
  *timer_1_period_high = TIMER_1_TIMEOUT >> 16;
  *timer_1_control = 7;
  /* START bit (must always be a 1)
   * CONT bit (timer restarts on timeout)
   * ITO bit (interrupt on timeout) */

  /* Set up Altera's interrupt wrapper for
   * interrupts from the timer_1 device.
   * Return value is zero for success,
   * nonzero for failure. */
  ret_val_check = alt_ic_isr_register(0,timer_1_intindex,timer_isr,NULL_POINTER,NULL_POINTER );
  /* If there was an error, terminate the program. */
  if( ret_val_check != 0 ) n2_fatal_error();
}

void irq_handler_toggles(void * context)
{
	/* Acknowledge the interrupt. */
	*de2_pio_toggles18_edgecap = 1;

	/* Light up the LED, print S, wait, turn off the LED and print s. */
	*de2_pio_redled18_base = 1;
	out_char_uart_0('S');
	bigdelay();
	*de2_pio_redled18_base = 0;
	out_char_uart_0('s');

}

void toggles_init()
{
	/* Declare a temporary for checking return values
	 * from system-calls and library functions. */
	  register int ret_val_check;

	  /*
	   * Register the interrupt handler.
	   */
	  ret_val_check = alt_ic_isr_register(0,de2_pio_toggles18_intindex,irq_handler_toggles,NULL_POINTER,NULL_POINTER);

	/* If there was an error, terminate the program. */
	  if( ret_val_check != 0 ) n2_fatal_error();

	 /* Set up the mask for the keys.*/
	*de2_pio_toggles18_intmask = 1;
}


int main()
{
  /* Remove unwanted interrupts.
   * initfix_int is supplied by KTH.
   * A nonzero return value indicates failure. */
  if( intfix() != 0 ) n2_fatal_error();

  /* Initialize de2_pio_keys4 for
   * interrupts. */
  keysinit_int();

  /* Initialize the toggle switches. */
  toggles_init();

  /* Initialize timer_1 for
   * continuous timeout interrupts. */
  timerinit_int();

  /* Loop forever. */
  while( 1 )
  {
    out_char_uart_0('_'); /* print an underscore */

    /* Programmed delay between underscores.
     * Defined earlier in this file. */
    somedelay();
  }
}

EN

回答 1

Stack Overflow用户

发布于 2015-03-24 21:50:55

难道不是因为Ss比Dd具有更高的优先级,因此它们被忽略了吗?而切换开关没有第三个输出来忽略"U"?

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29212874

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档