Im planning on using some 16F84A's for quick 'tools' for further USB development and testing. As such i thought i would write a framework for this chip such that it would be very fast for me to jig up another piece of software as i need it.

Since there was questions raised over this topic before, i thought i would share it for all:
; Pic 16F84A Framework by Jaymeson Trudge (NaN) April 23,2004.

list p=16f84a
#include p16f84a.inc

; Surpress annoying bank messages
errorlevel -302
errorlevel -305

; Define any equates used in the program
_PORTA_IO EQU b'11111110' ; A0 = Output
_PORTB_IO EQU b'11111111'
_OPTIONS EQU b'10000001' ; Weak Pullups / Prescale 1:4
_INTCON EQU b'00100000' ; Enable TMR0 Interrupts
_TMR0_INIT EQU .255-.55 ; 55 clocks till interrupt

; Define any data variables used in our program
GP_DATA UDATA
W_SAVE RES 1
STS_SAVE RES 1
TMR0_SET RES 1

EAX RES 1 ; Unimaginative Temp Register Names
EBX RES 1
ECX RES 1
EDX RES 1

; Define the Chip ID
IDLOCS CODE
dw 0x0103
dw 0x0204

; Define the Chip Configuration Params
CONFIG CODE
dw _CP_OFF & _PWRTE_OFF & _WDT_OFF & _HS_OSC

; Set The starup and Interupt Vectors
STARTUP CODE
clrf STATUS ; Set the page select to zero (Bank 1)
goto main
nop
nop
goto ISR_MAIN ; Goto the ISR Dispatch routine


;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; This is the main program startup and operating loop
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
PROG CODE
main
; Initalize Private Data
clrf EAX

; Initialize the Chip for main loop
clrf STATUS
call InitChip

; Set the TMR0 and start Ints
movlw _TMR0_INIT
movwf TMR0_SET
movwf TMR0
bsf INTCON, GIE

main_loop

btfss EAX, 0
goto main_loop

clrf EAX
movlw b'00000001'
xorwf PORTA, f
goto main_loop


; This routine is used to define the Chip features such as IO
; and Interupts
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
InitChip

;OPTION Register Settings
bsf STATUS, RP0
movlw _OPTIONS
movwf OPTION_REG

;Interupt Control Settings
bcf STATUS, RP0
movlw _INTCON
movwf INTCON

;PORT A & B IO Settings
clrf PORTA
clrf PORTB
bsf STATUS, RP0
movlw _PORTA_IO
movwf TRISA
movlw _PORTB_IO
movwf TRISB
bcf STATUS, RP0

; Finished.
return


;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; This is the main ISR Dispatch routine
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ISR_MAIN

; First save any status and W register information
movwf W_SAVE
movf STATUS, w
clrf STATUS
movwf STS_SAVE

; Now evaluate which interrupt happened
;btfsc INTCON, RBIF ; Port B change of state on bits=<4:7>
;call ISR_HandlePortB

;btfsc INTCON, INTF ; External Port A5 interrupt flag
;call ISR_HandlePortA

btfsc INTCON, T0IF ; TMR0 Interrup flag (timer roll over)
call ISR_HandleTMR0

; Now restor the saved registers
movf STS_SAVE, w
movwf STATUS
swapf W_SAVE, f
swapf W_SAVE, w
retfie


; ISR Handling routine for TMR0
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ISR_HandleTMR0
; Add your code here
incf EAX, f

; Reset the interrupt flag
movf TMR0_SET, w
movwf TMR0
bcf INTCON, T0IF
return


; ISR Handling routine for TMR0
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ISR_HandlePortB
; Add your code here

; Reset the interrupt flag
bcf INTCON, RBIF
return


; ISR Handling routine for TMR0
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ISR_HandlePortA
; Add your code here

; Reset the interrupt flag
bcf INTCON, INTF
return

end


You can get the MPASM project in the download below. This example framework prescales the clock to interrupt every [ ClockPeriod * 4 ]*4 seconds. At this point it will raise a bit 1 in the temp register EAX, and reset. In the main loop it polls for EAX to be non-zero. When it finds this condition, it then toggles PORTA bit 0's output. Pretty boring really.. but the structure is ready for what ever you can think of.

If you can use this, enjoy!
:alright:
:NaN:
Posted on 2004-04-22 23:22:50 by NaN
Just currious. I got algorythyms for precision secs using 4MHz. Preparing circuits now to use it to acheive high res pll with motorola MC145170.
Posted on 2004-04-23 09:48:40 by mrgone
I deliberately left this out of the equation. The 16F84A can handle a spectrum of frequencies from 4 Mhz to 20Mhz (IIRC).

That is why i indicated "ClockPeriod". Then first *4 is due to the internal pipeline taking 4 clocks per instruction, the second *4 is the prescaler setting (001 == x4) ~ See the _OPTION settings. You can adjust the prescaler from 1x -> 256x the internal frequency (which again is fclock/4).

Regards,
:NaN:
Posted on 2004-04-23 11:14:02 by NaN
by the way, in the config. of the pic you used _HS_OSC
how you used this osc.?

Why you didn't just used _XT_OSC??

Amr Turk
Posted on 2004-04-29 11:16:00 by amr
The XT option is intended for 32.768kHz (watch crystal) oscillators.
You should use the HS option for other crystals.
Posted on 2004-04-30 16:10:40 by VVV
oh, but I use XT for the 4MHz crystal.
by the way I have read in the datasheet that HS is not a crystal Osc but it depends on external clock generator.

that what I know.

Amr Turk
Posted on 2004-04-30 22:37:18 by amr
I read the sheet a little differntly. Its both, only the LP option is crystal only:
Posted on 2004-05-01 09:39:25 by NaN
:alright:

You gave me the right thing.


good

Amr Turk
Posted on 2004-05-02 12:43:11 by amr
Sorry Amr,

I did not mean to confuse you, it's just that an old goat like me sometimes mixes things up.
Thanks for that, NaN.
Posted on 2004-05-12 11:12:07 by VVV
Yay for the 16f84, but I'm a big kid now.
Posted on 2004-05-27 10:12:11 by Homer