Hi, This program is supposed to use TMR1 interrupts to oscillate at a user defined frequency. The idea is that it will be integrated with a serial program so that the frequency can be set via a PC. I think the following makes sense, from what I have read / been told, but if anyone has a chance t have a quick glance that would be brilliant. Either, have a good New Years!

Cheers,


Ben


'***************************************
'* Name : OSCILLATOR_1
'* Author : Ben Barker
'* Notice : Copyright (c) 2004 Ben Barker
'* : All Rights Reserved
'* Date : 31/12/2004
'* Version : 1.0
'* PIC in use : 16F876
'***************************************


'Control Lines:
'---------------

ClockOut var portB.0
TRISB = TRISB = %00000000 'Set portB to outputs

'Software Defines:
'-----------------

TimerReload VAR WORD 'Reload value for TMR1
dummy VAR WORD 'dummy variable used to deal with 32 bit operations
DesiredFreq VAR WORD 'Desired frequency in mHz
postscaler VAR BYTE 'Postscaler software counter - TMR1 has no hardware postscaler


'Initialization routine:
'------------------------

init:
ADCON1 = 7 'Disable ADC
CMCON = 7 'Set PORTA to digital for future use


postscaler = 0 'This variable is incremented at each timer interrupt, then reset when it reaches 2 to give a 1:2 postscaler

''''''''''''''''''''''''''''''''''''''''''''
'This section sets the output frequency, and works as follows:
'
'We have set the postscaler to 1:2 and the postscaler to 1:8
'This, our TIMER1 frequency with a 4Mhz XT is 4000000/4/8/2 = 62500Hz
'This means it steps through 62500 steps per second.
'If we preload the timer so that there are only, for example, 6250 steps
'before overflowing again, then it will overflow every 0.1 sec - giving a 10Hz
'output. We define a reload value as the nmber of steps away from
'overflow we reset the timer to after each interrupt is triggered.
'
'62500/reload_value = freq_in_Hz
'
'Thus (62500*100)/reload_value = freq_in_mHz
'
'Now, TMR1 is a 16bit counter, so has 2^16 = 65536 steps available. TMR1 counts
'up from zero, so to get our actual reload value we need to calculate:
'65536-reload_value
'
'However, due to variable rollover, 65536-reload_value is equal to 0-reload_value
'(The sign is neglected, magnitude is the same)
'''''''''''''''''''''''''''''''''''''''''''''

DesiredFreq = 1000 'Set desired output frequency to 10Hz (specified in mHz)

Dummy = 62500
Dummy = Dummy * 1000
TMR1Reload = DIV32 DesiredFreq
TMR1Reload = 0 - TMR1Reload

ON INTERRUPT GOTO timer

PIE1.0=1 'Enable TMR1 interrupts
INTCON.6=1 'Enables Peripheral Interrupts
INTCON.7=1 'Enable Global interrupts
T1CKPS1 = 1 'Set up TMR1 prescaler to 1:8 (see data sheet)
T1CKPS0 = 1


'Main function:
'---------------

main:
'Loop forever here waiting for interrupts to occur
goto main

'Interrupt Service Routine (ISR):
'---------------------------------

timer:
DISABLE 'Disable interrupts during ISR (shouldn't be needed - if it is, program is taking too long anyway)

postscaler=postscaler+1 'increment postscaler
if postscaler=2 then 'check new postscaler value, and respond
postscaler=0
TOGGLE CLOCKOUT 'toggle clock output pin
endif

'This output is not entirely accurate, as the ISR takes finite time. Rather than TMR1
'overflowing and then immediately sarting from preloaded value, it overflows, starts
'counting, and is then reloaded. This introduces a small error - could be ironed out
'by quantifying latency and adjusting reload value accordingly.

TMR1L = TMR1Reload.lowbyte 'Reload timer with value to give needed frequency
TMR1H = TMR1Reload.highbyte
PIR1.0= 0 'Reset interrupt flag

ENABLE 'Re-enable interrupts

RESUME 'Return to main program loop