
Help!: problem with fast timing for real-time application on PC
Hello there,
A friend of mine has a programming problem, which he hopes someone can
suggest a solution for. Since he does not have Internet access, I am posting
this message on for him. Here is the problem:
He wants to make on his PC a real-time application for
which quite accurate timing is needed. The normal speed of the system timer
(= 1/18.2 sec) is not fast enough so he decided to speed it up. This works
fine but it has some unwanted side effects, for instance the screen blanker
is activated every 18 seconds.
The solution he thought of is to redirect the interrupt to his own handler,
which forwards the interrupt only once every x times that the interrupt is
called. The effect would be that the rest of the handlers think the timer
operates at normal speed. The problem, however, is that if you don't forward
the interrupt the computer crashes. The code works well on interrupt 1Ch
(= the software timer interrupt) so that can't cause the trouble. In sum,
my friend has no clue as to what goes wrong.
Enclosed below is the program he made. It is written in Borland C++.
Any solution to this problem would be greatly appreciated by my friend. If
someone knows another way to get a more accurate timing he'll be happy too,
as long as it doesn't include any hardware modifications. Please e-mail
any suggestions to me.
Greetings,
Stefan Brands
----------------------------TIMER.HPP-----------------------------------
/*
TIMER :
This library speeds up the timer by a factor of 'TIME_ACC'.
You initialize the timer through 'set_timer()'. Use 'clear_timer()'
to reset it to its original value. ALWAYS do this because if you
don't the computer will crash. 'get_timer()' gives you the number
of clock ticks since you started the timer and with 'ticks_2_sec()'
you can convert these ticks to seconds.
WARNING: The program does not register an overflow of the clock
ticks. So after (2^32)/(18.2 * TIME_ACC) seconds the clock
returns to zero.
*/
#ifndef __TIMER__
#define __TIMER__
#include <dos.h>
/* This defines the multiplyer of the timer.
The value must be a divisor of 65536 */
#define TIME_ACC 16
void set_timer(void);
void clear_timer(void);
long int get_timer(void);
float ticks_2_sec(long int clicks);
#endif
--------------------------TIMER.CPP-----------------------------------
#include "timer.hpp"
/* The clock tick interrupt */
#define INTR 0x08
#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif
long int no_ticks;
int counter;
void interrupt ( *oldhandler)(__CPPARGS);
void interrupt handler(__CPPARGS)
{
no_ticks++;
counter--;
if (counter == 0)
{
oldhandler();
counter = TIME_ACC;
}
Quote:
}
void set_timer(void)
{
unsigned int counter_div = 65536l / TIME_ACC;
no_ticks = 0;
counter = TIME_ACC;
/* get the address of the current clock tick interrupt */
oldhandler = getvect(INTR);
/* install the new interrupt handler */
setvect(INTR, handler);
/* set counter 0 (= system timer) to read/write */
outp(0x43, 0x36);
/* write the counter divisor */
outp(0x40,(unsigned char)(counter_div & 255));
outp(0x40,(unsigned char)(counter_div >> 8));
Quote:
}
void clear_timer(void)
{
/* set counter 0 (= system timer) to read/write */
outp(0x43, 0x36);
/* set counter divisor to the normal value*/
outp(0x40,0);
outp(0x40,0);
/* restore interrupt vector */
setvect(INTR, oldhandler);
Quote:
}
long int get_timer(void)
{
return no_ticks;
Quote:
}
float ticks_2_sec(long int ticks)
{
float div = 18.2;
return ((float)ticks)/(div * TIME_ACC);
Quote:
}
--
Stefan Brands,
------------------------------------------------------
CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands