EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Pic Timer0 problem

Started by allenbv_99 March 23, 2005

Hi, I am writing an IRDA application. This is my first time using a
PIC. I am having trouble trying to figure out how to set up the
TIMER0 properly.

Using a PIC18f1320
My crystal is 7.3728 Mhz
I want a 100 mS interrupt or close to it.

The interrupt is working but it takes 9 seconds to cycle each time
through and I am not sure what I am doing wrong.

I have included the pertinent parts of the code below. I am running
another interrupt INT0 and it works ok. I included all of the code
for both interrupts. Right now I am reloading the interrupt because I
do not understand how to make it a free running timer.

If someone could show me the formula for getting the interrupt timer
to work correctly I would be grateful. Thanks
; some initialization is here

;******************************************
; Initialize RB0/INT0 interrupt
;******************************************
; INT2IP=high,INT1IP=high,INT2IE=disable,INT1IE=disable,
; INT2IF=clear INT1IF=clear
movlw b'11000000'
movwf INTCON3

; PortB pullups on, INT0=rising edge, INT1ling edge
; INT2ling edge, TMR0IP=high, RBIP=high
movlw b'11000101'
movwf INTCON2

; GIE=disable, PEI=disable, TMR0IE=enable, INT0IE=enable, RBIE=disable
; TMR0IF=clear, INT0IF=clear, RBIF=clear
movlw b'00110000'
movwf INTCON

; Initialize Timer0 interrupt
movlw 0x02
movwf TMR0H
movlw 0xCC
movwf TMR0L

; enable timer0, 16 bit timer, internal clock,
; use PSA, prescale = 256
movlw 0x87
movwf T0CON

; enable interrupts
bsf INTCON,GIE

; a bunch of code is here

; Timer0 interrupt handler
int_timerzero
bcf INTCON,TMR0IF
movwf W_TEMP
movff STATUS,STATUS_TEMP
movff BSR,BSR_TEMP
movlw 0x02
movwf TMR0H
movlw 0xCC
movwf TMR0L

; enable timer0, 16 bit timer, internal clock,
; use PSA, prescale = 256
movlw 0x87
movwf T0CON

; TEST CODE START
; Toggle line to find out the timer interval
movlw 0x01
xorwf PORTA,F
; TEST CODE END

; this code specific to my application
btfsc dsr
bra tmrfin
decsleep
movf sleepcontrol,F
btfss STATUS,Z
decf sleepcontrol,F
tmrfin
movff BSR_TEMP,BSR
movff STATUS_TEMP,STATUS
movf W_TEMP,W
retfie

; Sensor interrupt handler
int_sensor
bcf INTCON,INT0IF
incf MASTERCNT,F
retfie

; high priority interrupts.
HighPriority
btfsc INTCON,INT0IF ; RB0 interrupt?
bra int_sensor
btfsc INTCON,TMR0IF ; Timer0 interrupt?
bra int_timerzero

; catch other interrupts here and ignore them
; why do other interrupts happen when I have them turned off?

retfie



--- In piclist@picl..., "allenbv_99" <allenbv_99@y...> wrote:
>
> Hi, I am writing an IRDA application. This is my first time using a
> PIC. I am having trouble trying to figure out how to set up the
> TIMER0 properly.
>
> Using a PIC18f1320
> My crystal is 7.3728 Mhz
> I want a 100 mS interrupt or close to it.
>
> The interrupt is working but it takes 9 seconds to cycle each time
> through and I am not sure what I am doing wrong.
>
> I have included the pertinent parts of the code below. I am running
> another interrupt INT0 and it works ok. I included all of the code
> for both interrupts. Right now I am reloading the interrupt because
I
> do not understand how to make it a free running timer.
>
> If someone could show me the formula for getting the interrupt
timer
> to work correctly I would be grateful. Thanks
>

By using the ICD2 and checking the registers I have found that TMR0H
is not being loaded. Below is the code that I am using but it does
not work. > movlw 0x02
> movwf TMR0H
> movlw 0xCC
> movwf TMR0L
>

any help would be appreciated.


> By using the ICD2 and checking the registers I have found that TMR0H
> is not being loaded.

How do you know for sure? If you read TMR0H just after it was written,
does it show 'not change'? After starting again, does it also show no
change after writing TMR0L? The RMR0L/TMR0H logic is a bit complex, I
can imagine some erroneaous interaction with the ICD2/MPLAB (does the
debugger know that reading TMR0L will change TMR0H?).

Wouter van Ooijen

-- -------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu



--- In piclist@picl..., "allenbv_99" <allenbv_99@y...> wrote:
>
> --- In piclist@picl..., "allenbv_99" <allenbv_99@y...>
wrote:
> >
> > Hi, I am writing an IRDA application. This is my first time
using a
> > PIC. I am having trouble trying to figure out how to set up the
> > TIMER0 properly.
> >
> > Using a PIC18f1320
> > My crystal is 7.3728 Mhz
> > I want a 100 mS interrupt or close to it.
> >
> > The interrupt is working but it takes 9 seconds to cycle each
time
> > through and I am not sure what I am doing wrong.
> >
> > I have included the pertinent parts of the code below. I am
running
> > another interrupt INT0 and it works ok. I included all of the
code
> > for both interrupts. Right now I am reloading the interrupt
because
> I
> > do not understand how to make it a free running timer.
> >
> > If someone could show me the formula for getting the interrupt
> timer
> > to work correctly I would be grateful. Thanks
> >
>
> By using the ICD2 and checking the registers I have found that
TMR0H
> is not being loaded. Below is the code that I am using but it
does
> not work. > > movlw 0x02
> > movwf TMR0H
> > movlw 0xCC
> > movwf TMR0L
> >
>
> any help would be appreciated.

I had a similiar problem a few of month ago.
Are you using the ICD2 to step through the instructions? The timer
modules don't update right if you try to step through the code that
writes to the timer registers. You can place a break point
after "movwf TMR0L" instead. And since your using 16bit timer mode
TMR0H will get updated during the write to TMR0L.




I have done several different checks. The one that decided the issue
for me, was to put the following line of code in several lines after
I had loaded TMR0H and then loaded TMR0L and before I restarted the
Timer0 again.

; Do dummy read of TMR0L first so the read of TMR0h works
movff TMR0L, TMR0HSHAD
movff TMR0H, TMR0HSHAD

This code showed TMR0HSHAD was 0x00. I have also toggled a portA pin
every time the interrupt was called to find out the duration. The
duration = 9 secs.

Bradley --- In piclist@picl..., "Wouter van Ooijen" <wouter@v...>
wrote:
>> By using the ICD2 and checking the registers I have found that
>> TMR0H is not being loaded.

> How do you know for sure? If you read TMR0H just after it was
> written, does it show 'not change'? After starting again, does it
> also show no change after writing TMR0L? The RMR0L/TMR0H logic is a
> bit complex, I can imagine some erroneaous interaction with the
> ICD2/MPLAB (does the debugger know that reading TMR0L will change
> TMR0H?).
>
> Wouter van Ooijen
>
> -- -------
> Van Ooijen Technische Informatica: www.voti.nl
> consultancy, development, PICmicro products
> docent Hogeschool van Utrecht: www.voti.nl/hvu




My problem has been solved with the help of Microchip Tech support.

I was initializing timer0 in the wrong order and with the wrong
values. For a 16 bit timer0, the 16 bit operation must be setup
before you enable timer0. I was setting up T0CON with all desired
settings after or before I would load TMR0H and TMR0L which does not
work.

Here is the corrected order and values for a 100mS interrupt for
7.3728 Mhz.

; PIC18F1320 - Initialize Timer0 interrupt

; 16 bit timer,internal clock,use PSA,prescale = 256
movlw 0x07 ; must set up 16 bit first !!!!
movwf T0CON
movlw 0xFD
movwf TMR0H
movlw 0x30
movwf TMR0L

bsf T0CON,TMR0ON ; enabled timer0
bsf INTCON,GIE ; enable interrupts

I must say that the PIC18 documentation was not well written in this
case. Even though Microchip Tech support took 2 tries on solving my
problem, I am happy with their efforts.

Bradley




Memfault Beyond the Launch