There are two important key parts to consider at this version of program. The interrupt service routine and the Timer2 initialization routine.
The interrupt service routine itself consists of three parts. At beginning, it saves the W and STATUS registers so that those can be used at interrupt without distrupting the main program. I have selected unbanked RAM (at 0x70-0x7f) for storage cause those ram locations are always available. Also it's essential that these same registers are restored before returning from the interrupt handler.
Middle part of the routine looks quite a simple for now. There is just increment of the multibyte millisecond counter and reset of timer interrupt flag. This code will grow at the future depending what applications I'll make with this micro controller.
Next likely parts will be implementing interrupt based software serial port, transmitting for debug purposes. Most likely I'll use 9600bps and try to keep the code minimal. After that the next possible direction is to make test routines for the A/D converters.
After those.. I hope I'll have all the parts for an application I've been wanting to make for some time now, the parts are in Slow-mail coming from another side of the earth so there is no telling when they manage to appear.
--- Cut here.. Code follows
; V2 with Timer2 interrupt
; Uses Timer2 to generate 1ms timer interrupt
;PortC pins:
; RC:0 = digital out, led active high
#include p16f616.inc
__config _INTOSCIO & _WDT_OFF ; 8 Mhz int-osc with IO:s
; define Data memory
inner equ 0x20
outer equ 0x21
; Bank shared memory (0x70-0x7f) used for Interrupt
; Interrupt backup registers
int_w equ 0x70
int_status equ 0x71
int_pclath equ 0x72 ; not yet used at interrupts
int_indf equ 0x73 ; not yet used at interrupts
; Debug serial port (Note.. buffer location not yet determined
ser_tx equ 0x74 ; Zeroes reg after send
ser_rx equ 0x75 ; 0 = no data
ser_status equ 0x76 ; Todo! ; Define modes/error codes
; 24-bit ms tick counter (allocation for 32-bit int)
ms_32 equ 0x7c
ms_high equ 0x7d
ms_med equ 0x7e
ms_low equ 0x7f
; Start from reset vector
org 0x00 ; obvious, but just in case.
goto Main ; Skip over interrupt vector
org 0x04 ; Interrupt vector
Intserver
; Save W, STATUS (3 cycles)
movwf int_w
swapf STATUS,W ; only way to move status without affecting the Z-flag
movwf int_status
; Real interrupt routine (remember to clear the interrupt)
; note: We have no idea about status flags (including RP0)
; Since this interrupt happens every 2000:th cpu clock, we'll just
; increment the ms-counters
movlw 0x01
addwf ms_low, F
btfsc STATUS, C ; if carry not happen skip increment
addwf ms_med, F
btfsc STATUS, C ; if carry not happen skip increment
addwf ms_high, F
bcf PIR1, TMR2IF ; Clear interrupt
Intserver_end
; Restore W, STATUS and return from int (6 cycles)
swapf int_status, W
movwf STATUS
swapf int_w, F
swapf int_w, W ; return W without messing with Status flags
retfie ; return with interrupts enabled.
org 0x100 ; main program
Main
; Init IO ports
BCF STATUS,RP0 ;Bank 0
CLRF PORTC ;Init PORTC
BSF STATUS,RP0 ;Bank 1
CLRF ANSEL ;digital I/O (disable Analog Inputs)
MOVLW 0xFE ;Set RC<5:1> as input
MOVWF TRISC ;and set RC<0> as outputs
BCF STATUS,RP0 ;Bank 0
; Init Timer2 and real time clocks
movlw 0x00
movwf ms_high
movwf ms_med
movwf ms_low
; Sample of Timer2 settings for various interrupts at 8MHz xtal.
; Values in decimal.
; Clk PR2 Pre post Usage
; 2000 125 16 1 1ms timer for real time system clock
; 208 208 1 1 9600 bps Tx async debug serial
; 69 69 1 1 9600 bps Rx async debug serial (3* subsample)
; Last one will tax system badly
clrf TMR2
bcf PIR1, TMR2IF ; Clear interrupt (should be anyhow)
bsf STATUS, RP0 ; Bank1
movlw 0x7d ; 125 decmal
movwf PR2
bsf PIE1, TMR2IE ; Allow timer2 interrupt.
bcf STATUS, RP0 ; bank0
movlw 0x06 ; Prescaler *16 + OscOn.
movwf T2CON ; Set t2 scalers + start the timer
bsf INTCON, PEIE ; Enable periferal int
bsf INTCON, GIE ; Global interrupt enable
Loop
movf ms_med,W
movwf PORTC ; Blink period of 512 ms
goto Loop ;Do this repeatedly
end ;All things must end someday