如何在Nios 2中打印整数?

时间:2013-09-13 02:50:33

标签: c interrupt fpga intel-fpga

我编写代码而不是处理中断,我添加了一个函数,它将执行“有用”(计算下一个素数)并应该处理中断。中断正在工作但不能从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);
}

1 个答案:

答案 0 :(得分:3)

基本上你的代码对我很好。唯一的问题是打印,出于某种原因你应该打印一个换行符,如:

printf("start program\n");
  while( 1 )                /* Loop forever. */
  {
    next = nextPrime(next);
    printf("%d",next);

  }