⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 count_binary.c

📁 二进制计数器的硬件代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************
 * Copyright (c) 2006 Altera Corporation, San Jose, California, USA.      *
 * All rights reserved. All use of this software and documentation is     *
 * subject to the License Agreement located at the end of this file below.*
 *************************************************************************/
/******************************************************************************
 *
 * Description
 * ************* 
 * A simple program which, using an 8 bit variable, counts from 0 to ff, 
 * repeatedly.  Output of this variable is displayed on the LEDs, the Seven
 * Segment Display, and the LCD.  The four "buttons" (SW0-SW3) are used
 * to control output to these devices in the following manner:
 *   Button1 (SW0) => LED is "counting"
 *   Button2 (SW1) => Seven Segment is "counting"
 *   Button3 (SW2) => LCD is "counting"
 *   Button4 (SW3) => All of the peripherals are "counting".
 *
 * Upon completion of "counting", there is a short waiting period during 
 * which button/switch presses will be identified on STDOUT.
 * NOTE:  These buttons have not been de-bounced, so one button press may 
 *        cause multiple notifications to STDOUT.
 * 
 * Requirements
 * **************
 * This program requires the following devices to be configured:
 *   an LED PIO named 'led_pio',
 *   a Seven Segment Display PIO named 'seven_seg_pio',
 *   an LCD Display named 'lcd_display',
 *   a Button PIO named 'button_pio',
 *   a UART (JTAG or standard serial)
 *
 * Peripherals Exercised by SW
 * *****************************
 * LEDs
 * Seven Segment Display
 * LCD
 * Buttons (SW0-SW3)
 * UART (JTAG or serial)

 * Software Files
 * ****************
 * count_binary.c ==>  This file.
 *                     main() is contained here, as is the lion's share of the
 *                     functionality.
 * count_binary.h ==>  Contains some very simple VT100 ESC sequence defines
 *                     for formatting text to the LCD Display.
 * 
 *
 * Useful Functions
 * *****************
 * count_binary.c (this file) has the following useful functions.
 *   static void sevenseg_set_hex( int hex )
 *     - Defines a hexadecimal display map for the seven segment display.
 *   static void handle_button_interrupts( void* context, alt_u32 id)
 *   static void init_button_pio()
 *     - These are useful functions because they demonstrate how to write
 *       and register an interrupt handler with the system library.
 *
 * count_binary.h 
 *   The file defines some useful VT100 escape sequences for use on the LCD
 *   Display.
 */

#include "count_binary.h"

/* A "loop counter" variable. */
static alt_u8 count;
/* A variable to hold the value of the button pio edge capture register. */
volatile int edge_capture;


/* Button pio functions */

/*
  Some simple functions to:
  1.  Define an interrupt handler function.
  2.  Register this handler in the system.
*/

/*******************************************************************
 * static void handle_button_interrupts( void* context, alt_u32 id)*
 *                                                                 *  
 * Handle interrupts from the buttons.                             *
 * This interrupt event is triggered by a button/switch press.     *
 * This handler sets *context to the value read from the button    *
 * edge capture register.  The button edge capture register        *
 * is then cleared and normal program execution resumes.           *
 * The value stored in *context is used to control program flow    *
 * in the rest of this program's routines.                         *
 ******************************************************************/


#ifdef BUTTON_PIO_BASE
static void handle_button_interrupts(void* context, alt_u32 id)
{
    /* Cast context to edge_capture's type. It is important that this be 
     * declared volatile to avoid unwanted compiler optimization.
     */
    volatile int* edge_capture_ptr = (volatile int*) context;
    /* Store the value in the Button's edge capture register in *context. */
    *edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE);
    /* Reset the Button's edge capture register. */
    IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE, 0);
}

/* Initialize the button_pio. */

static void init_button_pio()
{
    /* Recast the edge_capture pointer to match the alt_irq_register() function
     * prototype. */
    void* edge_capture_ptr = (void*) &edge_capture;
    /* Enable all 4 button interrupts. */
    IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTON_PIO_BASE, 0xf);
    /* Reset the edge capture register. */
    IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE, 0x0);
    /* Register the interrupt handler. */
    alt_irq_register( BUTTON_PIO_IRQ, edge_capture_ptr,
                      handle_button_interrupts );
}
#endif

/* Seven Segment Display PIO Functions 
 * sevenseg_set_hex() --  implements a hex digit map.
 */
 
#ifdef SEVEN_SEG_PIO_BASE
static void sevenseg_set_hex(int hex)
{
    static alt_u8 segments[16] = {
        0x81, 0xCF, 0x92, 0x86, 0xCC, 0xA4, 0xA0, 0x8F, 0x80, 0x84, /* 0-9 */
        0x88, 0xE0, 0xF2, 0xC2, 0xB0, 0xB8 };                       /* a-f */

    unsigned int data = segments[hex & 15] | (segments[(hex >> 4) & 15] << 8);

    IOWR_ALTERA_AVALON_PIO_DATA(SEVEN_SEG_PIO_BASE, data);
}
#endif

/* Functions used in main loop
 * lcd_init() -- Writes a simple message to the top line of the LCD.
 * initial_message() -- Writes a message to stdout (usually JTAG_UART).
 * count_<device>() -- Implements the counting on the respective device.
 * handle_button_press() -- Determines what to do when one of the buttons
 * is pressed.
 */
static void lcd_init( FILE *lcd )
{
    /* If the LCD Display exists, write a simple message on the first line. */
    LCD_PRINTF(lcd, "%c%s Counting will be displayed below...", ESC,
               ESC_TOP_LEFT);
}

static void initial_message()
{
    printf("\n\n**************************\n");
    printf("* Hello from Nios II!    *\n");
    printf("* Counting from 00 to ff *\n");
    printf("**************************\n");
}

/********************************************************
 * The following functions write the value of the global*
 * variable 'count' to 3 peripherals, if they exist in  *
 * the system.  Specifically:                           *
 * The LEDs will illuminate, the Seven Segment Display  *
 * will count from 00-ff, and the LCD will display the  *
 * hex value as the program loops.                      *
 * *****************************************************/

/* static void count_led()
 * 
 * Illuminate LEDs with the value of 'count', if they
 * exist in the system
 */

static void count_led()
{
    alt_u8 b = count;
#ifdef LED_PIO_BASE
    /* Logic to make the LEDs count from right-to-left,
     LSB on the right. */
    IOWR_ALTERA_AVALON_PIO_DATA(
        LED_PIO_BASE,
        ((b * 0x0802LU & 0x22110LU) |
         (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16
        );
#endif
}

/* static void count_sevenseg()
 * 
 * Display value of 'count' on the Seven Segment Display
 */

static void count_sevenseg()
{
#ifdef SEVEN_SEG_PIO_BASE
    sevenseg_set_hex(count);
#endif
}

/* static void count_lcd()
 * 
 * Display the value of 'count' on the LCD Display, if it
 * exists in the system.
 * 
 * NOTE:  A HAL character device driver is used, so the LCD
 * is treated as an I/O device (i.e.: using fprintf).  You
 * can read more about HAL drivers <link/reference here>.
 */

static void count_lcd( void* arg )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -