$mod186
name example_80186_family_timer_code
;-------------------------------------------------------------
;FUNCTION: This function sets up the timer and interrupt
; controller to cause the timer to generate an
; interrupt every 10 milliseconds, and to
; service interrupts to implement a real time clock.
;
; Timer 2 is used in this example because no input or
; output signals are required.
;
; SYNTAX: extern void far set_time(hour, minute, second,
; T2Compare);
;
; INPUTS: hour - hour to set time to.
; minute - minute to set time to.
; second - second to set time to.
; T2Compare - T2CMPA value (see note below)
;
; OUTPUTS: None
;
; NOTE: Parameters are passed on the stack as required by
; high-level languages
;
; For a CLKOUT of 16Mhz,
;
; f(timer2) = 16Mhz/4
; = 4Mhz
; = 0.25us for T2CMPA = 1
;
; T2CMPA(10ms) = 10ms/0.25us
; = 10e-3/0.25e-6
; = 40000
; (Works for 80C186EX family of microcontrollers)
;-------------------------------------------------------------
; ;substitute register offsets
T2CONreg_T2CON equ xxxxh ;Timer 2 Control register
T2CMPA equ xxxxh ;Timer 2 Compare register
T2CNT equ xxxxh ;Timer 2 Counter register
TCUCON equ xxxxh ;Int. Control register
EOI equ xxxxh ;End Of Interrupt register
INTSTS equ xxxxh ;Interrupt Status register
timer_2_int equ 19 ;timer 2:vector type 19
data segment public 'data'
public _hour, _minute, _second, _msec
_hour db ?
_minute db ?
_second db ?
_msec db ?
data ends
lib_80186 segment public 'code'
assume cs:lib_80186, ds:data
public _set_time
_set_time proc far
push bp ;save caller's bp
mov bp, sp ;get current top of stack
hour equ word ptr[bp+6] ;get parameters off stack
minute equ word ptr[bp+8]
second equ word ptr[bp+10]
T2Compare equ word ptr[bp+12]
push ax ;save registers used
push DX
push si
push ds
xor ax, ax ;set interrupt vector
mov ds, ax
mov si, 4*timer_2_int
mov word ptr ds:[si], offset
timer_2_interrupt_routine
inc si
inc si
mov ds:[si], cs
pop ds
mov ax, hour ;set time
mov _hour, al
mov ax, minute
mov _minute, al
mov ax, second
mov _second, al
mov _msec, 0
mov DX, T2CNT ;clear Count register
xor ax, ax
out DX, ax
mov DX, T2CMPA ;set maximum count value
mov ax, T2Compare ;see note in header above
out DX, ax
mov DX, T2CON ;set up the control word:
mov ax, 0E001H ;enable counting, generate
out DX, ax ;interrupt on MC,
;continuous counting
mov DX, TCUCON ;set up interrupt controller
xor ax, ax ;unmask highest
out DX, ax ;priority interrupt
sti ;enable interrupts
pop si ;restore saved registers
pop DX
pop ax
pop bp ;restore caller's bp
ret
_set_time endp
timer_2_interrupt_routine proc far
push ax ;save registers used
push DX
cmp _msec, 99 ;has 1 sec passed?
jae bump_second ;if above or equal...
inc _msec
jmp short reset_int_ctl
bump_second:mov _msec, 0 ;reset millisecond
cmp _minute, 59 ;has 1 minute passed?
jae bump_minute
inc _second
jmp short reset_int_ctl
bump_minute:mov _second, 0 ;reset second
cmp _minute, 59 ;has 1 hour passed?
jae bump_hour
inc _minute
jmp short reset_int_ctl
bump_hour: mov _minute, 0 ;reset minute
cmp _hour, 12 ;have 12 hours passed?
jae reset_hour
inc _hour
jmp reset_int_ctl
reset_hour: mov _hour, 1 ;reset hour
reset_int_ctl:mov DX, EOI
mov ax, 8000h ;non-specific end of interrupt
out DX, ax
pop DX
pop ax
iret
timer_2_interrupt_routine endp
lib_80186 ends
end
Legal Stuff © 1997 Intel Corporation