📄 count_binary.c
字号:
/*************************************************************************
* 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 + -