我编写了处理中断的代码,并添加了一个函数,它将做一些“有用的”(计算下一个素数)并且应该处理中断。中断正在工作,但没有从 while 循环中打印计算出的素数,而如果我不尝试打印素数,它正在打印时间。
我认为putchar
不能使用它,因为 a)它是用于字符的,我想打印一个 int 和 b)putchar 使用中断,所以我必须以其他方式来做。
当我尝试使用printf("%d",next)
它时,它也不起作用,为什么?我应该如何从主循环中打印下一个素数?
该程序是
#include <stddef.h>
#include <stdio.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "sys/alt_alarm.h"
#include "alt_types.h"
#include "alt_irq.h"
extern int initfix_int(void);
extern void puttime(int* timeloc);
extern void puthex(int time);
extern void tick(int* timeloc);
extern void delay(int millisec);
extern int hexasc(int invalue);
#define TRUE 1
#define KEYS4 ( (unsigned int *) 0x840 )
#define TIMER1 ( (unsigned int *) 0x920 )
#define PERIOD (49999)
#define NULL_POINTER ( (void *) 0)
#define NULL ( (void *) 0)
#define PRIME_FALSE 0 /* Constant to help readability. */
#define PRIME_TRUE 1 /* Constant to help readability. */
volatile int timeloc = 0x5957;
volatile int RUN = 1;
volatile int * const de2_pio_keys4_base = (volatile int *) 0x840;
volatile int * const de2_pio_keys4_intmask = (volatile int *) 0x848;
volatile int * const de2_pio_keys4_edgecap = (volatile int *) 0x84c;
volatile int * de2_pio_hex_low28 = (volatile int *) 0x9f0;
const int de2_pio_keys4_intindex = 2;
const int de2_pio_keys4_irqbit = 1 << 2;
/* The alt_alarm must persist for the duration of the alarm. */
static alt_alarm alarm;
/*
* The callback function.
*/
alt_u32 my_alarm_callback(void* context) {
/* This function is called once per second */
if (RUN == 1) {
tick(&timeloc);
puttime(&timeloc);
puthex(timeloc);
}
return alt_ticks_per_second();
}
void n2_fatal_error() {
/* Define the pattern to be sent to the seven-segment display. */
#define N2_FATAL_ERROR_HEX_PATTERN ( 0xcbd7ff )
/* Define error message text to be printed. */
static const char n2_fatal_error_text[] = "FATAL ERROR";
/* Define pointer for pointing into the error message text. */
register const char * cp = n2_fatal_error_text;
/* Send pattern to seven-segment display. */
*de2_pio_hex_low28 = N2_FATAL_ERROR_HEX_PATTERN;
/* Print the error message. */
while (*cp) {
//out_char_uart_0( *cp );
cp = cp + 1;
}
/* Stop and wait forever. */
while (1)
;
}
/*
* Interrupt handler for de2_pio_keys4.
* The parameters are ignored here, but are
* required for correct compilation.
* The type alt_u32 is an Altera-defined
* unsigned integer type.
*/
void irq_handler_keys(void * context, alt_u32 irqnum) {
alt_u32 save_value;
save_value = alt_irq_interruptible(de2_pio_keys4_intindex);
/* Read edge capture register of the de2_pio_keys4 device. */
int edges = *de2_pio_keys4_edgecap;
*de2_pio_keys4_edgecap = 0;
/* If action on KEY0 */
if (edges & 1) {
/* If KEY0 is pressed now */
if ((*de2_pio_keys4_base & 1) == 0) {
if (RUN == 0) {
RUN = 1;
} else {
RUN = 0;
}
}
/* If KEY0 is released now */
else if ((*de2_pio_keys4_base & 1) != 0) {
}
alt_irq_non_interruptible(save_value);
} else if (edges & 2) {
/* If KEY1 is pressed now */
if ((*de2_pio_keys4_base & 2) == 0) {
tick(&timeloc);
puttime(&timeloc);
puthex(timeloc);
}
/* If KEY1 is released now */
else if ((*de2_pio_keys4_base & 2) != 0) {
}
alt_irq_non_interruptible(save_value);
}
else if (edges & 4) {
/* If KEY2 is pressed now */
if ((*de2_pio_keys4_base & 4) == 0) {
timeloc = 0x0;
puttime(&timeloc);
puthex(timeloc);
}
/* If KEY2 is released now */
else if ((*de2_pio_keys4_base & 4) != 0) {
}
alt_irq_non_interruptible(save_value);
}
else if (edges & 8) {
/* If KEY3 is pressed now */
if ((*de2_pio_keys4_base & 8) == 0) {
timeloc = 0x5957;
puttime(&timeloc);
puthex(timeloc);
}
/* If KEY3 is released now */
else if ((*de2_pio_keys4_base & 8) != 0) {
}
alt_irq_non_interruptible(save_value);
}
}
/*
* 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;
/* Allow interrupts */
*de2_pio_keys4_intmask = 15;
/* Set up Altera's interrupt wrapper for
* interrupts from the de2_pio_keys4 device.
* 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_irq_register(de2_pio_keys4_intindex, NULL_POINTER,
irq_handler_keys);
/* If there was an error, terminate the program. */
if (ret_val_check != 0)
n2_fatal_error();
}
/*
* NextPrime
*
* Return the first prime number larger than the integer
* given as a parameter. The integer must be positive.
*/
int nextPrime(int inval) {
int perhapsprime; /* Holds a tentative prime while we check it.
*/
int testfactor; /* Holds various factors for which we test
perhapsprime. */
int found; /* Flag, false until we find a prime. */
if (inval < 3) /* Initial sanity check of parameter. */
{
if (inval <= 0)
return (1); /* Return 1 for zero or negative input. */
if (inval == 1)
return (2); /* Easy special case. */
if (inval == 2)
return (3); /* Easy special case. */
} else {
/* Testing an even number for primeness is pointless, since
* all even numbers are divisible by 2. Therefore, we make sure
* that perhapsprime is larger than the parameter, and odd. */
perhapsprime = (inval + 1) | 1;
}
/* While prime not found, loop. */
for (found = PRIME_FALSE; found != PRIME_TRUE; perhapsprime += 2) {
/* Check factors from 3 up to perhapsprime/2. */
for (testfactor = 3; testfactor <= (perhapsprime >> 1); testfactor +=
1) {
found = PRIME_TRUE; /* Assume we will find a prime. */
if ((perhapsprime % testfactor) == 0) { /* If testfactor divides perhapsprime... */
found = PRIME_FALSE; /* ...then, perhapsprime was non-prime. */
goto check_next_prime;
/* Break the inner loop,
go test a new perhapsprime. */
}
}
check_next_prime: ; /* This label is used to break the inner loop. */
if (found == PRIME_TRUE) /* If the loop ended normally,
we found a prime. */
{
return (perhapsprime); /* Return the prime we found. */
}
}
return (perhapsprime); /* When the loop ends,
perhapsprime is a real prime. */
}
int main() {
int next = 3;
/* Remove unwanted interrupts.
* A nonzero return value indicates failure. */
if (initfix_int() != 0)
n2_fatal_error();
keysinit_int();
if (alt_alarm_start(&alarm, alt_ticks_per_second(), my_alarm_callback, NULL)
< 0) {
printf("No system clock available\n");
}
while( 1 ) /* Loop forever. */
{
next = nextPrime(next);
//printf("%d",next);
//printf("P %d ", next);
}
return 0;
}
int hex7seg(int digit) {
int trantab[] = { 0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00,
0x10, 0x08, 0x03, 0x46, 0x21, 0x06, 0x0e };
register int tmp = digit & 0xf;
return (trantab[tmp]);
}
void puthex(int inval) {
unsigned int hexresult;
hexresult = hex7seg(inval);
hexresult = hexresult | (hex7seg(inval >> 4) << 7);
hexresult = hexresult | (hex7seg(inval >> 8) << 14);
hexresult = hexresult | (hex7seg(inval >> 12) << 21);
IOWR_ALTERA_AVALON_PIO_DATA(DE2_PIO_HEX_LOW28_BASE, hexresult);
}