下面的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/