Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

!!!counter!!!

Hi,

The problem is this:
I just want to measure the time between a START and a STOP signal!
I give the START signal with a switch (HIGH or "1"), a code will be transmitted (by RF) and when the code is received, an output on the receiver-IC becomes HIGH or "1" (This is the STOP signal).

The time must be displayed on my PC-screen.


greetings,

Yoni

Comments

  • blipblip Member Posts: 756
    UNTESTED, UNREVISED, written in a hurry so please excuse any mistakes or laziness on my part

    I don't know how you plan to connect your output to a computer (what port?) and how you want it done (polling or interrupt-driven) so I will give you some information so you can put it all together.

    There is a programmable timing chip in nearly every PC that is pretty easy to set up called the PIT or Programmable Interval Timer. Its port addresses range from 40h to 43h, with 43h being a control port. You send it a byte specifying what counter (0-2) you want to work with at the moment along with a bunch of other options. For maximum compatibility, you should assume counter 1 is unavailable for RAM refresh as it was in older computers (mind you, some people continue to use them). This leaves counters 0 and 2 free for your use, although they also have their own system functions, but not nearly as potentially fatal to the session.

    An important point to keep in mind is that these counters count DOWN from a maximum count of 65536 and a minimum of 1. Their input clock is 1193182 Hz (1234DE hex, easy to remember that way), so they can time in multiples of that interval. Counter 0 is typically reserved for the system clock, although the RTC (Real Time Clock) actually keeps track of the time and date. It can be used to generate periodic interrupts (IRQ 0, int 8 in DOS or DOS box), though it is advisable to hand control over to the old handler when yours is done. Counter 2 is used primarily for the internal speaker frequency generator, with two bits in the PPI (Programmable Peripheral Interface) specifying whether the counter can count and the other whether the speaker is on or not. For timing purposes, turn on the timer but keep the speaker off or the user will notice :-P.

    Be careful with the PPI at port 61h because it controls some other system functions. To turn off the speaker and turn on counter 2, read the value at the port, AND it with 0FDh, OR it with 01h, and write it back. When you're done playing with it, AND its value with 0FCh to turn off both, or alternatively write back the value you initially read from it.

    Port 43h specifies, among other things, which counter to program and whether or not to automatically reload the counter and restart again. Mostly you want it to automatically restart rather that reloading it manually every time, if not, you can easily kill, ignore, or reprogram it anyway. The most common mode of operation is to program the PIT to do the above and the have the computer send/receive the appropriate counter values in first LSB (Least Significant Byte) first, then MSB (Most Significant Byte) order. When you read the counter value, it is usually desireable to be able to read the current value rather than the last programmed one, especially when timing. With all this down, I can give you the bytes to send to port 43h to do what you want: 36h to port 43h for counter 0 or 0B6h for counter 2, then program the counter value to the appropriate port (40h for counter 0, 42h for counter 2) and read/write TWO bytes ALWAYS or you risk framing errors during subsequent reads. By the way, you can't program in a value of 0 an expect to have nothing occur because the PIT interprets it as 65536.

    I suppose I'd better gives examples as I'm sure you're well confused now ;-)

    [code]
    ; Using counter 2 for a delay of 1234DEh / 1234h = 256 microsec:
    CountValue equ 1234h

    in al,61h
    push ax ; Save value for later restoration
    or al,1 ; Enable counter 2
    and al,0FDh ; Disable the speaker
    out 61h,al

    mov al,0B6h
    out 43h,al
    mov al,CountValue AND 0FFh ; LSB first
    out 42,al
    mov al,CountValue SHR 8 ; Then MSB
    out 42h,al

    Loopy:
    in al,42h
    mov bl,al
    in al,42h
    mov bh,al
    test bx,bx ; BX == 0 ?
    jz DoneDelaying ; If so then quit polling
    cmp bx,CountValue ; BX > CountValue (rollover from too much time passed) ?
    jna Loopy ; If not, keep waiting

    DoneDelaying:
    pop ax
    out 61h,al ; Retore old value
    [/code]

    Printing out the time requires some division to convert the number to decimal and then digit->ASCII convertion ready for display. Search around for such a routine if you cannot figure out how to do it on your own.
Sign In or Register to comment.