Захотел сделать измерение загрузки CPU.
Основная программа построена на прерываниях и работает с несколькими кнопками, сегментным индикатором и ком-портом.
Идея состоит в том, чтобы при начале любой (более-менее серъезной) процедуры стояло слово ImWorking, и заканчивалась процедура словом ImFinished.
Измеритель по этим словам выставляет тестовый диодик и считает сколько времени этот диодик простоял в высоком уровне (TimeInHighLevel).
Таймер в измерителе выдает прерывание раз в секунду, по которому значение TimeInHighLevel переписывается в буфер, доступный основной программе.
Вроде бы все получилось, но загрузка CPU, измеренная осцилографом, отличается от загрузки, измереной этим модулем.
Без оптимизации по осцилографу получается порядка 23% загрузки, модулем 24%. (вроде бы все нормально, списываем на погрешность)
С оптимизацией по времени выполнения получается: осцилограф - 13%, модуль 4%. (вот тут уже терзают сомнения)
И, так как я начинающий програмист, буду рад критике этого кода.

Код
#include <LPC23xx.h>
#include "SystemMonitor.h"
// диодик
#define Work (1 << 1) // @ 1
#define PCTIM3 0x00800000; // 23
#define PCLK_TIMER3_OFFSET 14 // @ 1
#define INTTIM3 (1 << 27)
void Work_SET() { IOSET1 = Work; }
void Work_CLR() { IOCLR1 = Work; }
short WorkRefs = 0;
unsigned short CPUUsage = 0;
int TimeInHighLevel = 0;
int TimeSetHighLevel = 0;
__irq void Timer3Handler()
{
if (WorkRefs > 0)
TimeInHighLevel += 10000 - TimeSetHighLevel;
CPUUsage = TimeInHighLevel;
TimeInHighLevel = 0;
TimeSetHighLevel = 0;
T3IR = 0x01;
VICVectAddr = 0;
}
void InitSystemMonitor()
{
TimeInHighLevel = 0;
WorkRefs = 0;
/* Initialize Timer 3 */
PCONP |= PCTIM3;
PCLKSEL1 &= ~(3 << PCLK_TIMER3_OFFSET);
PCLKSEL1 |= (1 << PCLK_TIMER3_OFFSET);
T3PR = 6399; // 100 mks
T3MR0 = 9999; // 1 s
T3MCR = 3;
VICIntEnClr = INTTIM3;
VICVectAddr27 = (unsigned long)Timer3Handler;
VICVectPriority27 = 15;
T3TCR = 0x01;
VICIntEnable += INTTIM3;
}
void ImWorking()
{
WorkRefs++;
if (WorkRefs == 1)
{
Work_SET();
TimeSetHighLevel = T3TC;
}
}
void ImFinished()
{
if (WorkRefs > 0)
WorkRefs--;
if (WorkRefs == 0)
{
TimeInHighLevel += T3TC - TimeSetHighLevel;
Work_CLR();
}
}