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

📄 timer.cpp

📁 LCD using AVR controller
💻 CPP
字号:
/*	Timer.cpp
*
*	Accurate timing.
*
*	#define one of the following values to select the appropriate code
*	based on your microcontroller and desired Timer/Counter (T/C) usage.
*
*		define      T/C
*		---------   ---
*		TIMER_0      0
*		TIMER_2      2
*
*	Valid combinations:
*
*		ATmega   CLOCK_    T/C
*		------   -------   ----
*		8        8M, 16M      2
*		16, 32   8M        0, 2
*		             16M      2
*		644      8M        0, 2
*		             16M      2
*		128      8M        0, 2
*		             16M   0
*
*	Revisions:
*		07-28-06	vectComp name change
*		07-13-06	included in LCDSample project
*		07-05-06	version 1 in master library
*
*	Written by Cathy Saxton
*	robotics@idleloop.com
*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include "Util.h"
#include "Timer.h"

/*	Timer settings
*
*	WGM (waveform generation mode) = CTC (Clear Timer on Compare Match)
*	CS (clock select)
*		choose prescale to result in 125 kHz
*		8 Mhz / 64
*		16 MHz / 128
*	OCR (top/clear value) = 125 for match every 1 ms
*/

/* value to use for CS depends on uC, Timer/Counter, and uC clock speed */
#ifdef __AVR_ATmega8__
	#ifdef TIMER_2
		#ifdef CLOCK_8M
			#define csTimer		0x04	// 100
		#elif defined CLOCK_16M
			#define csTimer		0x05	// 101
		#endif // CLOCK
	#endif // TIMER
#elif defined __AVR_ATmega16__ || defined __AVR_ATmega32__
	#ifdef TIMER_0
		#ifdef CLOCK_8M
			#define csTimer		0x03	// 011
		#endif // CLOCK
	#elif defined TIMER_2
		#ifdef CLOCK_8M
			#define csTimer		0x04	// 100
		#elif defined CLOCK_16M
			#define csTimer		0x05	// 101
		#endif // CLOCK
	#endif // TIMER
#elif defined __AVR_ATmega644__
	#ifdef TIMER_0
		#ifdef CLOCK_8M
			#define csTimer		0x03	// 011
		#endif // CLOCK
	#elif defined TIMER_2
		#ifdef CLOCK_8M
			#define csTimer		0x04	// 100
		#elif defined CLOCK_16M
			#define csTimer		0x05	// 101
		#endif // CLOCK
	#endif // TIMER
#elif defined __AVR_ATmega128__
	#ifdef TIMER_0
		#ifdef CLOCK_8M
			#define csTimer		0x04	// 100
		#elif defined CLOCK_16M
			#define csTimer		0x05	// 101
		#endif // CLOCK
	#elif defined TIMER_2
		#ifdef CLOCK_8M
			#define csTimer		0x03	// 011
		#endif // CLOCK
	#endif // TIMER
#endif

#ifndef csTimer
#error "unsupported configuration for Timer"
#endif


#ifdef TIMER_0

#ifdef __AVR_ATmega644__
/*
*	Timer/Counter 0 (compare A)
*
*	WGM (CTC) = 010
*/
#define regTCNT			TCNT0			// Timer/Counter register
#define regTIMSK		TIMSK0			// interrupt mask register
#define bitOCIE			OCIE0A			// interrupt enable bit
#define vectComp		TIMER0_COMPA_vect	// interrupt vector for compare match
inline void Init2()
{
	TCCR0A = 0x02;	// 00 00 xx 10 (COMA, COMB, low 2 bits WGM)
	TCCR0B = 0x00 | csTimer; // 00 xx 0 *** (misc, high bit WGM, CS)
	OCR0A = 125;
}

#else // !mega644
/*
*	Timer/Counter 0
*
*	WGM (CTC) = 10
*/
#define regTCNT			TCNT0			// Timer/Counter register
#define regTIMSK		TIMSK			// interrupt mask register
#define bitOCIE			OCIE0			// interrupt enable bit
#define vectComp		TIMER0_COMP_vect	// interrupt vector for compare match
inline void Init2()
{
	OCR0 = 125;
	TCCR0 = 0x08 | csTimer; // 0 0 00 1 *** (FOC, WGM low, COM, WGM high, CS)
}
#endif // uC selection

#elif defined TIMER_2

#ifdef __AVR_ATmega644__
/*
*	Timer/Counter 2 (compare A)
*
*	WGM (CTC) = 010
*/
#define regTCNT			TCNT2			// Timer/Counter register
#define regTIMSK		TIMSK2			// interrupt mask register
#define bitOCIE			OCIE2A			// interrupt enable bit
#define vectComp		TIMER2_COMPA_vect	// interrupt vector for compare match
inline void Init2()
{
	TCCR2A = 0x02;	// 00 00 xx 10 (COMA, COMB, low 2 bits WGM)
	TCCR2B = 0x00 | csTimer; // 00 xx 0 *** (misc, high bit WGM, CS)
	OCR2A = 125;
}

#else // !mega644
/*
*	Timer/Counter 2
*
*	WGM (CTC) = 10
*/
#define regTCNT			TCNT2			// Timer/Counter register
#define regTIMSK		TIMSK			// interrupt mask register
#define bitOCIE			OCIE2			// interrupt enable bit
#define vectComp		TIMER2_COMP_vect	// interrupt vector for compare match
inline void Init2()
{
	TCCR2 = 0x08 | csTimer; // 0 0 00 1 *** (FOC, WGM low, COM, WGM high, CS)
	OCR2 = 125;
}
#endif // uC selection

#else
#error "unrecognized TIMER_* definition (see header comment)"
#endif


bool TIMER::s_fInit = fFalse;

/* this counts the number of milliseconds since Timer/Counter
   was initialized (volatile to make sure loops work!) */
static volatile ulong s_msTimer = 0;

TIMER::TIMER()
{
	if (!s_fInit)
		Init();
}

/* sets up Timer/Counter (using defines above) */
void TIMER::Init()
{
	s_fInit = fTrue;

	/* start counting at 0 */
	regTCNT = 0;

	Init2();

	/* set Compare Match Interrupt Enable */
	SetBit(regTIMSK, bitOCIE);

	/* set I-bit in SREG (global enable for interrupts) */
	sei();
}

/* returns number of ms since Timer initialized */
ulong TIMER::MsCur() const
{
	char sregSav;
	ulong ms;

	/* disable (delay) interrupts while we read
	   s_msTimer since it's 4 bytes and we don't
	   want it changing during the read! */
	sregSav = SREG;	// cache register holding Global Interrupt Flag
	cli();			// clear Global Interrupt Flag
	ms = s_msTimer;
	SREG = sregSav;	// restore register holding Global Interrupt Flag

	return ms;
}

/* returns true if the specified number of milliseconds
   has passed since the start time */
bool TIMER::FElapsed(ulong msStart, ulong msWait) const
{
	return MsCur() - msStart > msWait;
}

/* waits (pauses) for the specified number of milliseconds */
void TIMER::WaitMs(uint ms) const
{
	ulong msStart;

	msStart = MsCur();
	while (!FElapsed(msStart, ms))
		;
}

/* this interrupt happens every ms, when the counter (TCNTn)
   reaches the specified OCRn value */
ISR(vectComp)
{
	++s_msTimer;
}

⌨️ 快捷键说明

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