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

📄 timer.h

📁 这项工程将让您把自己的MP3播放器平台
💻 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 + -