PIC1684A interrupt map.
Fig. 1 PIC1684A interrupt map.


Programming PIC16F84A-PIC16F628A TMR0 Interrupts

by Lewis Loflin


We utilize TMR0 interrupts to increment a counter, then when reaching a select number the program toggles the state of a LED on PB0. this is very easy to program and we will walk through the steps.


;=======================================
;	CLOCK: External 4MHz (instruction execution time: 1usec)
;	This is a basic start template for PIC16F84A
;	Includes delay routines 
;	Date: 6-16-2023
;	Author: Lewis Loflin
;	MPLAB v7.50	compiler.
;	Tutor example file: 16F84lewisXOR.ASM
;	Use TMR0 interrupts to toggle ON/OFF LED RB1 at 500 Hz.       
;	Actual TMR0 delay is 1mSec.
;	LED on RB2 measured 5 Hz using software DELAY.
;	Both should work together, software delay effected by TMR0
;	The ISR saves and restores W and STATUS register.
;	LED RB1 toggle ON/OFF at 5Hz using softeware delay.
;	Both outputs were measured with a frequency counter.
;======================================
	list      p=16F84A      
	#include <p16F84A.inc>  
	errorlevel  -302   

	__CONFIG  _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC 

;*****[ Data Storage Reg's ]*****
	CBLOCK  0x0C  ; Assign each reg. from Bank 0 RAM area.
	CNT1  ;Timer 1, Used for general delay.		
	CNT2  ;Timer 2, used for delay !
	CNT3  ;Timer 2, used for delay !
	TEMP  ;Used to store pattern
	w_temp       ; variable used for context saving 
	status_temp  ; variable used for context saving		
	ENDC         ; Conclude Bank 0 RAM assignments.

	ORG	0			; Reset vector PIC16F84
	GOTO	setup	;Jump to setup

	ORG 0x04  ; interrupt
	MOVWF   w_temp            ; save off current W register contents
	MOVFW	STATUS         ; move status register into W register
	MOVWF	status_temp       ; save contents of STATUS register
	MOVLW   0x02  ; a ONE in any bit position will toggle bit(s)
	XORWF   PORTB, F ; store back in portb
	BCF     INTCON, T0IF ; bit 2
	MOVLW   D'9'
	MOVWF   TMR0
	MOVF    status_temp, W  ; retrieve copy of STATUS
	MOVWF	STATUS          ; restore pre-isr STATUS 
	SWAPF w_temp,F ;Swap W_Temp
	SWAPF w_temp,W ;Swap W_Temp into W
	RETFIE   ; return from interrupt
	
		
;		**************************
;       main routine:

setup	;Program starts here !!!		
		
	; BSF	STATUS,RP0	
	BANKSEL TRISB	
	MOVLW	B'11110000'		;Config PORTB, RB1-3 OUTPUT, RB0, RA4-7 INPUT
	MOVWF	TRISB			;Set I/O configuration for PORTB
	MOVLW   B'00000001'     ; Enable TMR0, prescale 1:4
	MOVWF   OPTION_REG    
	; BCF	STATUS,RP0		    ;Jump back to bank 0 of PIC.
	BANKSEL INTCON
	MOVLW   0xA0     ; setup interrupts for TMR0
	MOVWF   INTCON
	CLRF	PORTB 	;Clear all I/O's of PORTB
	BCF     INTCON, 2 ; CLR TMR0 IRQ flag
	MOVLW   D'9' ; 
	MOVWF   TMR0 ; write TMR0 count begins.	    
       
;Loop starts here !!!

LOOP    

	MOVLW   0x01  ; toggle 2X for 500Hz.
	XORWF   PORTB, F ; F = 1 for file, W = 0 W register
	CALL DELAY_100ms

GOTO    LOOP

;		**************************	;Delay routine.
; Calculating a 1mSec delay. 4mHz is divided by 4 internally to
; 1,000,000. Take reciprocal divide 1mSec by 1uSec = 1000.
; GOTO uses 2 cycles DECFSZ 1 cycle = 3 cycles or 3uSec.
; 3 * 82 * 4 =~ 1000uSec. or 1mSec.
; if CNT1 = 40 then 10 mSEC. delay, 200 is 50 mSec. delay.

DELAY_1ms
	; 4 mHz crystal
	MOVLW D'4'
	MOVWF CNT1
	MOVLW D'82'
	MOVWF CNT2
	DECFSZ CNT2, F
	GOTO $-1 
	DECFSZ CNT1, F
	GOTO $-5 
	RETLW 0

DELAY_100ms
	MOVLW D'100' ; value * DELAY_1ms
	MOVWF CNT3
	CALL DELAY_1ms
	DECFSZ CNT3, F
	GOTO $-2 
	RETLW 0

END    ;End of source code.

The code is self-explanatory and is a combination of earlier coding. When TMR0 overflows the interrupt decrement CNT until it reaches zero. Otherwise most of the code is skipped (GOTO $+7), except the TMR0 interrupt flag is always cleared to 0. See the following:

PIC16F84A Test Circuit



Web site Copyright Lewis Loflin, All rights reserved.
If using this material on another site, please provide a link back to my site.