📄 smith.txt
字号:
C/C++ in Embedded Chronographs
by William Smith
Listing 1
// clock.hpp Begin
#ifdef __PALMOS
#include <SystemMgr.h>
#include <TimeMgr.h>
#define CLOCKS_PER_SEC ((clock_t)SysTicksPerSecond())
typedef long clock_t;
#elif defined( __WINDOWS )
#include <windows.h>
#define CLOCKS_PER_SEC 1000
typedef long clock_t;
#else
#include <time.h>
#endif
class cClock
{
public:
cClock( clock_t ClocksPerSec = CLOCKS_PER_SEC );
cClock( clock_t CalPeriod, clock_t CalError,
clock_t ClocksPerSec = CLOCKS_PER_SEC );
~cClock() {};
clock_t StartClock();
clock_t GetClock();
clock_t GetCalClock();
clock_t GetClocksPerSec();
static void SetCalibration( clock_t CalPeriod, clock_t CalCorrection );
static void CalcCalibration( clock_t ActualTime,
clock_t MeasuredTime, clock_t Correction );
private:
static clock_t _mClockStart;
static clock_t _mNumClockCalls;
static clock_t _mDesClockRes;
static clock_t _mDesClocksPerSec;
static clock_t _mNatClockRes;
static clock_t _mCalPeriod;
static clock_t _mCalCorrection;
static void InitClock();
static inline clock_t LoopClock( clock_t Clock1, clock_t *NumCalls );
static void SetClockRes( clock_t ClocksPerSec );
static clock_t RoundToRes( clock_t Clock );
};
// clock.hpp End
Listing 2
// clock.cpp Begin
#include <clock.hpp>
#ifdef __PALMOS
inline clock_t clock();
#elif defined ( __WINDOWS )
inline clock_t clock();
#endif
clock_t cClock::_mClockStart = 0;
clock_t cClock::_mNumClockCalls = 0;
clock_t cClock::_mDesClockRes = 0;
clock_t cClock::_mDesClocksPerSec = 0;
clock_t cClock::_mNatClockRes = 0;
clock_t cClock::_mCalPeriod = 0;
clock_t cClock::_mCalCorrection = 0;
cClock::cClock( clock_t ClocksPerSec )
{
if ( !_mNumClockCalls )
{ // First time through so initialize
InitClock();
SetClockRes( ClocksPerSec );
}
}
cClock::cClock( clock_t CalPeriod, clock_t CalCorrection,
clock_t ClocksPerSec )
{
this->cClock::cClock( ClocksPerSec );
_mCalPeriod = CalPeriod;
_mCalCorrection = CalCorrection;
}
clock_t cClock::StartClock()
{
_mClockStart = 0;
_mClockStart = GetClock();
return ( _mClockStart );
}
clock_t cClock::GetClock()
{
clock_t Clock1, Clock2 = 0, NumCalls = 0;
Clock1 = clock();
if ( _mDesClockRes < _mNatClockRes )
{ // Use number of clock calls to get finer resolution
Clock2 = LoopClock( Clock1, &NumCalls );
if ( NumCalls < _mNumClockCalls )
{ // Get fraction of clock tick res that had transpired
Clock2 = _mNumClockCalls - NumCalls;
Clock2 *= _mNatClockRes;
if ( _mDesClocksPerSec > CLOCKS_PER_SEC )
{ // Covnert clock value to designated units
Clock2 *= _mDesClocksPerSec / CLOCKS_PER_SEC;
}
Clock2 /= _mNumClockCalls;
}
else
{ // clock had just ticked
Clock2 = 0;
}
}
if ( _mDesClocksPerSec > CLOCKS_PER_SEC )
{ // Covnert clock value to designated units
Clock1 *= _mDesClocksPerSec / CLOCKS_PER_SEC;
}
Clock2 += Clock1;
if ( _mDesClocksPerSec < CLOCKS_PER_SEC )
{ // Covnert clock value to designated units
Clock2 = RoundToRes( Clock2 );
}
Clock2 -= _mClockStart; // Get time from start
return ( Clock2 );
}
clock_t cClock::GetCalClock()
{
clock_t Clock = GetClock();
if ( _mCalPeriod && _mClockStart )
{ // Adjust time by the calibration correction
Clock += ( ( _mCalCorrection * Clock ) / _mCalPeriod );
}
return ( Clock );
}
clock_t cClock::GetClocksPerSec()
{
return ( _mDesClocksPerSec );
}
void cClock::SetCalibration( clock_t CalPeriod,
clock_t CalCorrection )
{
_mCalPeriod = CalPeriod;
_mCalCorrection = CalCorrection;
}
void cClock::CalcCalibration( clock_t ActualTime,
clock_t MeasuredTime, clock_t Correction )
{
clock_t Error = ActualTime - MeasuredTime;
clock_t Periods = Error / Correction;
_mCalPeriod = 0;
if ( Periods != 0 )
{
_mCalPeriod = MeasuredTime / Periods;
_mCalCorrection = Correction;
}
}
void cClock::InitClock()
{
clock_t Clock1, Clock2, Clock3;
clock_t Dummy = 0, NumCalls1 = 0, NumCalls2 = 0;
Clock1 = clock();
Clock2 = LoopClock( Clock1, &Dummy ); // Make clock tick
Clock3 = LoopClock( Clock2, &NumCalls1 );
Clock1 = LoopClock( Clock3, &NumCalls2 );
// Average two clock ticks
_mNumClockCalls = ( NumCalls1 + NumCalls2 ) / 2;
_mNatClockRes = ( Clock1 - Clock2 ) / 2;
}
clock_t cClock::LoopClock( clock_t Clock1, clock_t *NumCalls )
{
clock_t Clock2;
do
{ // Call the clock function till it updates (or ticks)
(*NumCalls)++; // Count the number of times called
Clock2 = clock();
}
while ( Clock2 == Clock1 );
return ( Clock2 );
}
void cClock::SetClockRes( clock_t ClocksPerSec )
{
if ( !ClocksPerSec )
{ // Set the designated units to the native value
_mDesClocksPerSec = CLOCKS_PER_SEC;
}
else
{
_mDesClocksPerSec = ClocksPerSec;
}
// Calculate the designated resolution
// A 0 value means the designated units are finer then the native units
_mDesClockRes = CLOCKS_PER_SEC / _mDesClocksPerSec;
}
clock_t cClock::RoundToRes( clock_t Clock )
{
clock_t Remainder =
Clock % ( CLOCKS_PER_SEC / _mDesClocksPerSec );
Clock = ( Clock * _mDesClocksPerSec ) / CLOCKS_PER_SEC;
if ( Remainder >= 5 )
{ // Round the time up by one
Clock++;
}
return ( Clock );
}
#ifdef __PALMOS
inline clock_t clock()
{
return ( (clock_t)TimGetTicks() );
}
#elif defined( __WINDOWS )
inline clock_t clock()
{
return ( (clock_t)GetTickCount() );
}
#endif
// clock.cpp End
1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -