Hades logoHades applet banner
PIC16C84 interrupt-driven counter

applet icon

The image above shows a thumbnail of the interactive Java applet embedded into this page. Unfortunately, your browser is not Java-aware or Java is disabled in the browser preferences. To start the applet, please enable Java and reload this page. (You might have to restart the browser.)

Circuit Description

This applet demonstrates an interrupt-based counter realized with the PIC16C84 microcontroller. In the default settings, the clock generator for the PIC16C84 runs at 1 KHz only, in order to save host CPU time. The second clock generator component is used to generate the pulses we want to count. Naturally, you could use any other data source.

The microcontroller program is very simple. It first initializes the counter register and enables interrupts on port B0. Afterwards, it enters an endless loop that does nothing. The interrupt routine in turn increments the counter variable, outputs the lower 4 bits of the counter value to ports B7..B4, re-enables interrupts, and returns:

	TITLE           "16-Bit-Zaehler: PIC16C84"
	SUBTITLE        "Zaehlimpulse von RB0/INT"

;***********************************************************************
; A simple interrupt-driven counter program. It counts rising-edge
; events on port B0 and outputs the lower 4 bits of the counter value
; on ports B7...B4.
; Note that the watchdog timer WDT needs to be disabled to run this
; program, because WDT interrupts are not handled.
;***********************************************************************

		Processor       16C84
		Radix   DEC
		EXPAND

		include         "p16c84.inc"

_ResetVector	set	0x00
_IntVector	set	0x04
Zaehler 	set 	0x20


	ORG     _ResetVector	; the program starts here
	call    Init		; initialize ports, counter, and interrupts

InfiniteLoop:
	goto    InfiniteLoop	; idle loop

	ORG     _IntVector	; interrupt-address
	goto    Interrupt	; handle interrupt

;***********************************************************************
; enable B3..B0 as inputs and B7..B4 as outputs.
; enable interrupts for RB0/INT and reset the counter variable.
;***********************************************************************

Init:
	bsf	STATUS, RP0	; select bank 1
	movlw	0xC0		; rising edge sensitive, no pullup for
	movwf	OPTION		; RB0/INT-PIN 
	movlw	0x10		; only enable RB0/INT interrupt
	movwf	INTCON		; INTCON is in both banks
	movlw	0x0F		; set B3..B0 as inputs, B7..B4 as outputs
	movwf   TRISB		; move into the direction control register
	bcf	STATUS, RP0	; select bank 0 
	clrf	Zaehler		; clear counter value
	retfie			; RETURN and enable interrupts

;***********************************************************************
; very simple interrupt handler.
; We do not even need to save and restore the work register or status bits.
; Increment the counter and output the lower 4 bits on port B.
;***********************************************************************

Interrupt:
	incf	Zaehler		; increment counter values
	swapf	Zaehler,W	; swap nibbles of counter, result in W
	movwf	PORTB		; write W to port B
	bsf	STATUS, RP0	; select bank 1
	movlw	0x10		; select RB0/INT interrupts only
	movwf	INTCON		; move to interrupt control register
	bcf	STATUS, RP0	; select bank 0
	retfie			; return from interrupt handler

Print version | Run this demo in the Hades editor (via Java WebStart)
Usage | FAQ | About | License | Feedback | Tutorial (PDF) | Referenzkarte (PDF, in German)
Impressum http://tams-www.informatik.uni-hamburg.de/applets/hades/webdemos/72-pic/08-counter/count.html