From: Kris Heidenstrom Newsgroups: comp.os.msdos.djgpp Subject: Re: High speed timing Date: Sun, 01 Feb 1998 14:14:46 +1300 Organization: CLEAR Net, http://www.clear.net.nz/ Lines: 77 Message-ID: <34D3CC86.EC3B0A26@clear.net.nz> References: <34D11CA2 DOT 79CD AT bellsouth DOT net> NNTP-Posting-Host: d3-u33.wgtn.clear.net.nz Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk Lester "Ringo" Davis wrote: > What is the best way to get a time value between events. I'm getting > ready to interface a sonar system to a pc and need to measure time of > flight of the sonar. I don't want to use a simple counter. I'm sure > there is a function that does what I need, any ideas? There may be a function in the library - check the libc reference. As a general answer, you can read the 8254 programmable interval timer (PIT). It counts at 1.19318166666... MHz (resolution is about 0.838 microseconds). It has three channels. You can use channel 0 or channel 2. There are also other timing methods you can use, though this is probably the best for your application. Some simple initialisation is needed as some motherboards (mostly older ones) operate timer channel 0 in mode 3 and it needs to be in mode 2. Channel 2 is used to generate speaker audio, so if you use it for timing, make sure you can't ever generate a beep (may require special handling of the keyboard buffer, as the BIOS generates a beep when the buffer gets full). Running code in a tight loop, it is possible to time any period to within a few microseconds using this technique. How accurate do you need to be? As in any real-time application, you have to be aware of interrupts and their overhead. The timer tick interrupt, int 8, occurs every time timer channel 0 wraps around, i.e. every 65536*0.838 us which is every 54.9254 ms or 18.2065 times per second. The BIOS int 8 handler doesn't do too much, but TSRs often hook the interrupt or int 1Ch which is called by the BIOS int 8 handler, and TSRs are often poorly written. The nett effect is a gap in execution every time a timer tick occurs. Interrupts are also generated by keypresses and releases, and by mouse clicks and movements. All of these interrupts will cause a gap in execution. If you are using an interrupt yourself to start and stop your timing, acceptance of your interrupt could be delayed by these interrupts (the timer tick has the highest priority). With DJGPP (or any protected mode program), there is also the overhead of one or more mode switches. The normal handlers for hardware interrupts like the timer tick, keyboard, mouse etc are real-mode ones, so if the CPU is in protected mode when the interrupt occurs, two mode switches are required. If you use interrupts yourself, more mode switches could be needed. Depending on what other requirements you have for your program, you could consider disabling all interrupt sources during the timing process. I wrote a large document on timing and related stuff, it covers all the things I've mentioned here and a lot of other things that you might find useful if you want to 'cover all the bases' in your programming. The URL is: ftp://ftp.simtel.net/pub/simtel/msdos/pctim003.zip Unfortunately, it is written for real-mode only (all the code is 16-bit real-mode, written for Borland C and TASM). I will update it for DJGPP one day :-) You will need lots of extra information on low-level programming under DJGPP. There are pointers in the excellent DJGPP FAQ under topics like 'writing interrupt handlers', 'accessing hardware directly' and 'inline assembly'. One other idea - look at the Allegro package, it is designed for game programming etc but I'm sure it will have timing stuff, which may be self-contained. Please feel free to email me if you think I can help with anything. This reply sent to Ringo via email and to the newsgroup. Kris -- Kris Heidenstrom Electronic designer, programmer, bass player kheidens AT clear DOT net DOT nz http://home.clear.net.nz/pages/kheidens/