PDA

View Full Version : Timer interrupt frequency



Samoele
- 17th January 2009, 16:41
Hello,

I use template from DT for my project. I wish to made simple voltage to frequency converter. AD converter measure voltage and show value from 0-1023 o LCD. On output pin become 2Hz pulse. This working ok.
Problem is following:
I don't know where can place routine which will be change internal timer prescaler from 2Hz to 2048Hz. This frequency must be read from AD. (value*2)

Is it possible to made?

routine is here:


'PIC18F252


ADCON1=%10001110
DEFINE OSC 4
DEFINE LCD_DREG PORTC
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTC
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTC
DEFINE LCD_EBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 4
DEFINE LCD_COMMANDUS 4000
DEFINE LCD_DATAUS 255

DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 11

INCLUDE "DT_INTS-18.bas"
INCLUDE "ReEnterPBP-18.bas"

w0 var word
w1 var word
FOUT VAR PORTB.1

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, ReloadTMR1, ASM, no ; MUST be first
INT_Handler TMR1_INT, _T1handler, PBP, yes
endm
INT_CREATE
ENDASM


@Freq = 2'10 ; Frequency of Interrupts in Hz
@Prescaler = 8 ; Timers Prescaler setting
T1CON = $30 ; $30 = Prescaler 1:8, TMR1 OFF
; $00=1:1, $10=1:2, $20=1:4, $30=1:8 -- Must match @Prescaler value

@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
GOSUB StartTimer ; Start the Timer


Main:
ADCIN 0, w1
lcdout $fe,1, #W1, " VAL"
PAUSE 100
GOTO Main


T1handler:


toggle FOUT


@ INT_RETURN


ASM
ReloadInst = 8 ; # of Intructions used to reload timer
if ((Prescaler == 1)||(Prescaler == 2)||(Prescaler == 4)||(Prescaler == 8))
MaxCount = 65536 + (ReloadInst / Prescaler)
TimerReload = MaxCount - (OSC*1000000/4/Prescaler/Freq)
if ((TimerReload < 0) || (TimerReload > (65535-ReloadInst)))
error Invalid Timer Values - check "OSC", "Freq" and "Prescaler"
endif
else
error Invalid Prescaler
endif
ENDASM

@Timer1 = TMR1L ; map timer registers to a word variable
Timer1 VAR WORD EXT
TimerReload CON EXT ; Get the External Constant
TMR1ON VAR T1CON.0 ; Alias the Timers ON/OFF bit


ASM
ReloadTMR1
MOVE?CT 0, T1CON, TMR1ON ; 1 stop timer
MOVLW LOW(TimerReload) ; 1 Add TimerReload to the
ADDWF TMR1L,F ; 1 value in Timer1
BTFSC STATUS,C ; 1/2
INCF TMR1H,F ; 1
MOVLW HIGH(TimerReload) ; 1
ADDWF TMR1H,F ; 1
MOVE?CT 1, T1CON, TMR1ON ; 1 start timer
INT_RETURN
ENDASM

StartTimer:
Timer1 = TimerReload ; Load Timer
TMR1ON = 1 ; start timer
RETURN

StopTimer:
TMR1ON = 0 ; stop timer
RETURN

Darrel Taylor
- 17th January 2009, 23:49
Hi Samoele,

The "Timer Template" was intended for a Fixed Frequency.
There's no easy way to convert it to what you want.

The SSPWM (Slow speed Software PWM) program ...
http://www.pbpgroup.com/modules/wfsection/article.php?articleid=6

does allow you to change either frequency or dutycycle on the fly.
But it only goes down to 16hz, and would need a 20mhz crystal to get your upper frequency.

Sorry,