📄 timer.h
字号:
//++
//timer.h - declarations for timer.c module
//
// Copyright (C) 2005 by Spare Time Gizmos. All rights reserved.
//
// This file is part of the Spare Time Gizmos' MP3 Player firmware.
//
// This firmware is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the Free Software Foundation, Inc., 59 Temple
// Place, Suite 330, Boston, MA 02111-1307 USA
//
//REVISION HISTORY:
// dd-mmm-yy who description
// 30-May-05 RLA New file.
// 12-Oct-05 RLA Add TimerInterrupt() prototype for SDCC.
//--
#ifndef _timer_h_
#define _timer_h_
// Timer specific constants...
#define HERTZ 50 // number of ticks per second
// We need an __nop__ intrinsic (to generate a real 8051 NOP instruction)
// for the DELAYUS() macro. In SDCC we just use the inline assembler...
#define _nop_() _asm nop _endasm;
// This macro generates a MOV and a DJNZ instruction, plus whatever NOPs we
// choose to add. The MOV executes only once and so we'll ignore its effect
// on the timing. Each DJNZ requires two machine cycles, and every NOP that we
// insert in the loop adds one more cycle. On a traditional 8051 CPU each
// machine cycle takes 12 clocks, but on the high speed Philips parts a
// machine cycle is only 6 clocks (that's why it's faster :-). To generate a
// delay of, say, 125us with a 11.0592Mhz crystal we need to execute 115
// cycles on a 12 clock processor or 230 cycles on a 6 clock CPU.
//
// For the 12 clock CPU, we use a loop with just the DJNZ, so 115 cycles
// require 58 iterations. For the 6 clock CPU, we add two NOPs to the loop
// so again, 230 cycles will require 58 interations.
//
// By the way, with a 11.0592Mhz crystal, the maximum possible delay is
// somewhere around 500us with either processor. With higher or lower
// crystal frequencies the maximum delay will scale accordingly...
//
// One other little footnote - the SDCC compiler apparently isn't smart
// enough to generate a DJNZ for this loop - instead, it generates a
// MOV, a CJNE, a SJMP (to the next statement after the loop), a DEC,
// and another SJMP (back to the CJNE at the top of the loop). This only
// makes the delay longer than expected!
#if (CPU_CLOCKS_PER_CYCLE == 12)
#define DELAYUS(n) {BYTE i; for (i = (BYTE) (((n)*CPU_CLOCK+11999999L)/(12000000L)); i != 0; --i) ; }
#elif (CPU_CLOCKS_PER_CYCLE == 6)
#define DELAYUS(n) {BYTE i; for (i = (BYTE) (((n)*CPU_CLOCK+11999999L)/(12000000L)); i != 0; --i) {_nop_(); _nop_();} }
#else
#error FIX DELAYUS MACRO - UNRECOGNIZED CPU_CLOCKS_PER_CYCLE
#endif
// Methods...
extern void InitializeTimer (void);
extern void DelayMS (WORD wDelay);
// Public member variables...
extern volatile WORD g_wSecondsTimer;
extern bit g_fTimerRunning, g_fTimerChanged;
// These macros manipulate the seconds counter that runs in g_wSecondsTimer.
// This timer/counter is used only to implement a display of the elapsed
// running time for the current MP3 file, so it's pretty simple... Note that
// these particular macros intentionally look like subroutines (note the use
// of mixed case names, for example) so that they could be converted to
// actual subroutines at some time in the future...
#define ResetElapsedTime() \
{ET2 = 0; g_fTimerRunning = g_fTimerChanged = FALSE; g_wSecondsTimer = 0; ET2 = 1;}
#define StopElapsedTimer() {g_fTimerRunning = FALSE;}
#define StartElapsedTimer() {g_fTimerRunning = TRUE;}
#define GetElapsedTime(x) \
{ET2 = 0; (x) = g_wSecondsTimer; g_fTimerChanged = FALSE; ET2 = 1;}
#define IsTimerChanged() (g_fTimerChanged)
// SDCC requires that any interrupt function be declared in the main
// program file (i.e. the file which contains the main() procedure) so that
// SDCC can correctly set the interrupt vector.
extern void TimerInterrupt (void) interrupt TIMER2_VECTOR;
#endif // _timer_h_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -