PDA

View Full Version : timer0 10ms setting check



longpole001
- 30th June 2015, 02:10
HI guys , i transfer some code from another processor which from the data sheet hs the same registers but seem to be getting a 20ms timer0 , not a 10ms interupt

all looks correct but it cant be , can someone have a look and see where i made the error

pic 18f46k80
osc32 internal,
timer 0 to give a 10ms interupt




;----- CONFIG1L Options --------------------------------------------------
CONFIG XINST = OFF
CONFIG SOSCSEL = DIG ; Digital (SCLKI) mode; I/O port functionality of RC0 and RC1 is enabled
CONFIG INTOSCSEL = LOW ; LF-INTOSC in low-power mode during Sleep
CONFIG RETEN = ON ; Ultra Low power regulator is Enabled (Controlled by SRETEN bit)when in sleep

;----- CONFIG1H Options --------------------------------------------------
CONFIG IESO = OFF
CONFIG FCMEN = OFF
CONFIG PLLCFG = ON
CONFIG FOSC = INTIO2 ; Internal RC oscillator , PORTA.6 , PORTA.7 as I/O







OSCCON = %01100000 ' Select 32Mhz - using 8Mhz internal with PPLx4 in Config1H<3:0> = IDLEN =0 , 8Mhz , OSTS=0,RFIOFS=1,RC_Run (1x) OSC using PLL
' Bit 7 IDLEN =0 ( sleep mode when sleep instraction executed)
' Bits 6-4 - 111 = 16Mhz , 110 = 8MHz ,101 = 4 MHz, 100 = 2MHz 011 = 1MHz
' If INTTSRC=0 and MFIOSEL= 0 then 010 = HF-INTOSC/32 (500Khz), 001 = HF-INTOSC/64 (250Khz) ,000 = LF-INTOSC (31.25Khz)
' If INTTSRC=0 and MFIOSEL= 1 then 010 = MF-INTOSC (500Khz), 001 = MF-INTOSC/2 (250Khz) ,000 = LF-INTOSC (31.25Khz)
' If INTTSRC=1 and MFIOSEL= 0 then 010 = HF-INTOSC/32 (500Khz), 001 = HF-INTOSC/64 (250Khz) ,000 = HF-INTOSC/512 (31.25Khz)
' If INTTSRC=1 and MFIOSEL= 1 then 010 = MF-INTOSC (500Khz), 001 = MF-INTOSC/2 (250Khz) ,000 = MF-INTOSC/16 (31.25Khz)
' Note: INTSRC = OSCTUNE<7> and MFIOSEL = OSCCON2<0>
' Bit 3 - OSTS = 0 - Osc startup time out is ruinning from internal OSC ( HF, MF or LF-INTOSC)
' Bit 2 - HFIOFS =1 ( INTOSC Frq stable bit - 1 = stable , 0 = not stable
' Bits 1-0 - 00= Dephalt Pri OSc ( OSC1/2 or HF-INTOSC with/without PLL set in FOSC,3:0> config1H <3.0>
' 01 = SOSC osc
' 1x = Internal osc ( LF, MF,HF-INTOSC)

' OSCCON2 = $00 ' Bit 7 n/a , Bit 6 - SOSCRUN - Run status bit , Bit 5-4 n/a,
' Bit 3 = SOASCGO - Osc Start control bit 1 = OSC running , 0 = OSC shut off if no requests for it
' Bit 2 n/a , Bit 1 - MFIOFS 1= MFINTOSC stable 0 = Not stable
' Bit 0 MFIOSEL - 1 = MF-INTOSC replaces HF-ISTOSC Freq for 500Khz,250Khz,31.25KHz) 0 = MF-INTOSC not used

OSCTUNE = %01000000 ' Bit 7 - INTSRC - internal LF Source Select 1 = 31.25 from 16Mhz Internal /512 HF-INTOSC ) 0 = Internal 31khz OSC
' Bit 6 - PLLEN - 1 PLL enabled , 0 = PLL disabled
' Bits 5-0 Frequancy callibaration 00000 = centre Frq









' ---------- Timer 0 Register Setups ----------------
INTCON2.2 = 1 ' TMR0IP - TIMER 0 Overflow Interupt Priority - 1 = High Priorty , 0 = Low Priority
T0CON.7 = 1 ' Bit7 - TMR0 1= Enable 0 = Stop timer
T0CON.6 = 0 ' Bit6 - TMR0 8/16bit control 1= 8bit 0=16bit,
T0CON.5 = 0 ' Bit5 - TMR0 Clock Source 1=clk on T0CKI pin input 0=Internal clcck (Fosc/4)
T0CON.4 = 0 ' Bit4 - TMR0 Source Edge Select 1= H/L of TOCKI 0= L/H of TOCKI ,
T0CON.3 = 0 ' Bit3 - TMR0 PSA select 1=TMR0 Bypass Prescaler 0= CLK Input from Prescaler output
T0CON.2 = 0 ' Bit2-0 - Timer0 prescaler Rate Select bits 2-0(set to 1:256)
T0CON.1 = 0 ' 000 = 1:2 , 001= 1:4 , 010 = 1:8 , 011 = 1:16
T0CON.0 = 0 ' 100 = 1:32 , 101 = 1:64, 110 = 1:128 , 111 = 1:256






' ---------- Set up DT_INTS-18 Routine for Instant Interupt handling -----------

INCLUDE "DT_INTS-18.bas" ; Base Interrupt System for 18FxxK80 processors
INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts

ASM
INT_LIST macro ; IntSource , Label , Type, ResetFlag?

INT_Handler TMR0_INT, _Timer0_Count, PBP, yes ; call Timer0_Count subroutine

endm
INT_CREATE ; Creates the Interrupt Processor
ENDASM









' ============ Timer 0 Interupt handler ================
' a 10 ms timer interupt

Timer0_Count:

INTCON.5 = 0 ' STOP TIMER
T0Count1 = T0Count1 + 1 ' inc counter on interupt flag
TMR0H = $63 ' preset Timer 0 to a 10ms timer
TMR0L = $C0
INTCON.5 = 1 ' START TIMER
@ INT_RETURN
RETURN

towlerg
- 30th June 2015, 03:44
As your error is double, it's likely a problem with the 2:1 prescaler. Perhaps your setting of T0CON is being overwritten in one of the include files.

Or your clock is running at 16Mhz.

George

HenrikOlsson
- 30th June 2015, 06:17
Not sure it's got anything to do with your problem but flipping INTCON.5 does not start/stop TMR0 - it enables/disables the interrupt.


Timer0_Count:

INTCON.5 = 0 ' STOP TIMER <----- No it doesn't
T0Count1 = T0Count1 + 1 ' inc counter on interupt flag
TMR0H = $63 ' preset Timer 0 to a 10ms timer
TMR0L = $C0
INTCON.5 = 1 ' START TIMER <------ No it doesn't
@ INT_RETURN
RETURN

Also, verify that your oscillator is actually running at the expected frequency. A simple LED blinking at 10Hz will tell you if it's off bu a factor of 2.

/Henrik.

longpole001
- 30th June 2015, 09:49
YES CHECKED THE PRESCALLER AS SHOWN

osc as shown
ameding the interupt routine as follows changes nothing

it not clear what i missed





' ============ Timer 0 Interupt handler ================
' a 10 ms timer interupt

Timer0_Count:

T0CON.7 = 0 ' Bit7 - TMR0 1= Enable 0 = Stop timer
INTCON.5 = 0 ' clear timer0 interupt IE
T0Count1 = T0Count1 + 1 ' inc counter on interupt flag
TMR0H = $63 ' preset Timer 0 to a 10ms timer
TMR0L = $C0
INTCON.5 = 1 ' enable Interupt
T0CON.7 = 1 ' Bit7 - TMR0 1= Enable 0 = Stop timer
@ INT_RETURN
RETURN

longpole001
- 30th June 2015, 10:12
yes i fixed it after puting in a pin to toggle found it was jumping out of the service routine

sorry guys

longpole001
- 30th June 2015, 11:27
also dont take the MIkro timer calculator at its word

i been testing lower osc +PPL for power usage ( lower the main osc the lower the current use)

when using thier calculator for 1mhz main osc + PPl - so entering the value of 4Mhz on the caclulator FOR 10MS , gives T0CON = $88 , TRM0H = $D8 TRM0L = $F0

which is does not give you a 10ms time it give you a 40ms time , as the t0con setting bit 3 uses the base osc bypass prescale ,

entering in the a main osc of 1mhz AND 10MS interupt give a T0CON= $88, TRM0H=F6,TRM0L=3C - which is correct

handy tool just need to know its not correct when timer0 on 18f gives a tocon = $88 - bypassing the prescaler

HenrikOlsson
- 30th June 2015, 12:26
For accurate timings you also need to take the interrupt latency and the time it takes to actually reload the timer registers into account.
The interrupt fires, then it takes a couple of hundred instructions to do the context saving etc before you actually get to reloading the timer for another 10ms period. If it's used for something like a clock it'll run slow.

What you usually do in the ISR is stop the timer, read it's value, then ADD the reload value (minus a fudge factor to account for the time the timer isn't running) to the value being read from the timer. Then you write the new value back and restart the timer. That way the interrupt latency is always compensated for.

/Henrik.

towlerg
- 30th June 2015, 13:37
....takes a couple of hundred instructions.... To save context?

George

HenrikOlsson
- 30th June 2015, 13:47
Yes, when you're using DT-Ints with an PBP-type ISR it has to save all the system variables when entering the ISR (and restore them on exit). The exact amount of time that takes can probably be different depending on device, if you're using LONGs, what PBP commands are being used in the program and so on. I've measured it a couple of times and the notes I can find at the moment says that the latency is around 20us on an 18F4431 running at 40MHz with a program compiled using LONGs.

20us at 40MHz is 160 instructions.

/Henrik.

longpole001
- 1st July 2015, 10:36
thanks for that , yes i dont need it too accurate for this requirement