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

第一种是通过使用Key0,它具有以下属性:
按下Key0后,将写入“ D”。此后不久,一旦程序恢复自身,就会写入“ d”,并且这假设我仍然按住该按钮。释放此按钮后,将打印出“ U”。

如果我不按住按钮,则会打印出一个“ dU”,使代码变成“ DdU”。

第二种是通过使用切换键实现的,它具有以下属性:
一旦我们切换了切换键,程序就会打印一个“ S”。此后不久,打印出“ s”。

现在我的问题如下:
在先使用key0然后再使用切换键时,Key0可以在忽略切换键的情况下中断程序。因此,我们简单地得到“ DdU”,而“ S”和“ s”都将被忽略。

现在我不明白为什么反之亦然。它只是在一定程度上做到了。首先切换时,“ S”被写入,“ D”和“ d”被跳过。 “ s”被写入,但现在出现了令人困惑的部分=>为什么“ U”最后被写入?为什么key0的“ D”和“ d”被忽略,而其“ U”却不被忽略?



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* 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();
  }
}

最佳答案

难道不只是因为Ss的优先级比Dd高,所以它们被忽略了吗?鉴于没有第三路输出使拨动开关忽略“ U”?

关于c - C语言中的中断处理,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29212874/

10-12 01:55