?? timer0.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.
*/
/* 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. *
******************************************************************/
#include "system.h"
#include "alt_types.h"
#include "altera_avalon_pio_regs.h"
#include "sys/alt_irq.h"
#include <stdio.h>
#include <unistd.h>
#include "altera_avalon_timer.h"
#include "altera_avalon_uart.h"
#include "altera_avalon_timer_regs.h"
#include "io.h"
//全局變量
//static np_timer* timer=na_timer1;//定時器指針
const long nTimerPeriod=50000000;//定時周期1s
static int nTimerCount=0;//秒時間計數值,每次定時中斷變化
static int nTimerDir=1;//計時方向,0為暫停,1為正向,-1為反向
//LED分鐘數顯示
void show_led(int secCount)
{
//np_pio *pio=na_led_pio;//得到LED指針
//如果secCount計數值超出范圍,最多顯示8min
if (secCount>=60*9)
secCount=60*8;
//用LED所亮個數來表示計時分鐘數
IOWR_ALTERA_AVALON_PIO_DATA(LEDPIO_BASE,(1<<(secCount/60))-1);//pio->np_piodata=(1<<(secCount/60))-1;
}
//數碼管BCD碼顯示
void show_seg_bcd(int code)
{
//np_pio* seg_pio=na_seven_seg_pio;//得到數碼管指針
//將顯示數據轉為BCD碼顯示
if (code>=0 && code<10000)
{
IOWR_ALTERA_AVALON_PIO_DATA(SEVENSEGPIO_BASE,(((code/1000)%10)<<12)+(((code/100)%10)<<8)+(((code/10)%10)<<4)+(code%10));//seg_pio->np_piodata=
}
}
//數碼管秒鐘數顯示
void show_decimal(int secCount)
{
//如果secCount計數已滿9min,顯示60s
if (secCount==60*9)
show_seg_bcd(60);
else
{secCount %=60;//取計時數值的秒鐘數
show_seg_bcd(secCount);
}
}
//啟動定時器
void start_timer(void)
{
//定時器控制寄存器stop位清零,start位寫1
IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER1_BASE,~ ALTERA_AVALON_TIMER_CONTROL_STOP_MSK);
IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER1_BASE,ALTERA_AVALON_TIMER_CONTROL_START_MSK);
}
//暫停定時器
void pause_timer(void)
{
//定時器控制寄存器start位清零,stop位寫1
IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER1_BASE,~ALTERA_AVALON_TIMER_CONTROL_START_MSK);
IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER1_BASE,ALTERA_AVALON_TIMER_CONTROL_STOP_MSK);
}
//定時器中斷服務子程序
void my_timer_isr(int context)
{
//np_timer *timerT=(np_timer *)context;//得到定時器指針
//根據計時方向(正向計時或倒計時),計時數值加1或減1
if (nTimerDir==-1&&nTimerCount>0)
nTimerCount--;
else if (nTimerDir>0&&nTimerCount<60*9)
nTimerCount++;
//判斷計時是否完成
if ((nTimerDir>0&&nTimerCount==60*9)||(nTimerDir<0 && nTimerCount==0))
{nTimerDir=0;//暫停計時
//計時完成,停止計時
pause_timer();
}
//在串口終端上顯示計時時間
printf("%d'%d\"\t",nTimerCount/60,nTimerCount%60);
if (nTimerCount%10==0)
printf("\n");
//LED分鐘數顯示
show_led(nTimerCount);
//數碼管秒鐘數顯示
show_decimal(nTimerCount);
//清除定時器中斷狀態
IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER1_BASE,0x0);
}
//定時器初始化
void init_timer(void)
{
//設置定時周期1s
IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER1_BASE,(short)(nTimerPeriod&0x0000ffff));
IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER1_BASE,(short)((nTimerPeriod>>16)&0x0000ffff));
//安裝定時器中斷服務子程序
alt_irq_register(TIMER1_IRQ,0, my_timer_isr); //nr_installuserisr(na_timer1_irq,my_timer_isr,(long)timer);
//設置定時器循環工作,定時器允許中斷
IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER1_BASE,ALTERA_AVALON_TIMER_CONTROL_CONT_MSK+ALTERA_AVALON_TIMER_CONTROL_ITO_MSK);
}
//main主程序
int main(void)
{
//按鍵變量
int buttons,buttonsLast=0x000F;
IOWR_ALTERA_AVALON_PIO_DATA(BUTTONPIO_BASE,0X0);
//按鍵指針
//np_pio *pio=buttonpio;
//設置按鍵端口全為輸入端口
//pio->np_piodirection=0;
//初始化定時器設置
init_timer();
//開啟定時器
start_timer();
//循環檢測串口輸入是否位Esc鍵的鍵值
while (1)
{
//讀取按鍵數據端口輸入碼
buttons=IORD_ALTERA_AVALON_PIO_DATA(BUTTONPIO_BASE);//buttons=pio->np_piodata;
//判斷是否有按鍵按下
if (buttons!=buttonsLast&&buttonsLast==0x000F)
{
switch(buttons&0x000F)
{
case 0x000E://SW0,定時器清零或置數
pause_timer();//暫停
//按一次清零,再按則置數
if (nTimerCount>0)
nTimerCount=0;
else
nTimerCount=60*9;
//刷新LED和數碼管顯示內容
show_led(nTimerCount);
show_decimal(nTimerCount);
break;
case 0x000D://SW1,置數
//每按一次SW1置數時間加60s,超出則清零
if (nTimerCount==60*9)
nTimerCount=0;
else if(nTimerCount>60*8)
nTimerCount=60*9;
//刷新LED和數碼管顯示內容
show_led(nTimerCount);
show_decimal(nTimerCount);
break;
case 0x000B://SW2,向上計時或暫停
if(nTimerDir!=0)
{
pause_timer();//暫停
nTimerDir=0;
}
else
{
//向上計時開始
start_timer();
nTimerDir=1;
}
break;
case 0x0007://SW3,倒計時或暫停
if (nTimerDir!=0)
{
pause_timer();//暫停
nTimerDir=0;
}
else
{
//倒計時開始
start_timer();
nTimerDir=-1;
}
break;
case 0x000F://沒有按鍵按下
buttons=buttonsLast=0x000F;
break;
default:
break;
}
}
//保存當前按鍵鍵值到buttonLast變量
buttonsLast=buttons;
}
//卸載定時器中斷服務子程序,關閉定時器中斷
alt_irq_register(TIMER1_IRQ,0,0);
IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER1_BASE,~ALTERA_AVALON_TIMER_CONTROL_ITO_MSK);
//顯示程序退出信息,\004即Ctrl-D,表示程序已結束
printf("\nExit mytimer.\n\004");
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -