Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

TIMER0 - Have I got this right?

Status
Not open for further replies.

UTMonkey

Member
I would like to have a TIMER0 interrupt fire "around" 300 times a second.

Here is my working out, please point out any misunderstandings

1. The uC is running at 8Mhz so FOSC/4 = 2MIPS
2. The TIMER0 interrupt will fire at 8 bit rollover (FF->00) or 16 bit rollover (FFFF->0000), depending on a clear\set of the relevant bit.
3. An increment of TIMER0 will take 1 instruction (or tick?), so 256 (or 65536) ticks later the interrupt will fire.
4. If my uC is running at 2MIPS the interrupt (without prescaling) would fire7,812 times a second (8 bit) or 30 times (16bit).

If the above is correct I guess I would need to muck around with TIMER0's prescaler.

Here goes:-
Prescale set @ 1:2 TIMER0 interrupt will fire 3,906 times (8bit) or 15 times (16bit) a second.
Prescale set @ 1:4 TIMER0 interrupt will fire 1,953 times (8bit) or 7 times (16bit) a second.
Prescale set @ 1:8 TIMER0 interrupt will fire 976 times (8bit) or 3 times (16bit) a second.
Prescale set @ 1:16 TIMER0 interrupt will fire 488 times (8bit) or Once (16bit)
Prescale set @ 1:32 TIMER0 interrupt will fire 244 times a second (8bit) or every second (16bit)
Prescale set @ 1:64 TIMER0 interrupt will fire 122 times a second (8bit) or once every 2 seconds (16bit)
Prescale set @ 1:128 TIMER0 interrupt will fire 61 times a second (8bit) or once every 4 seconds (16bit)
Prescale set @ 1:256 TIMER0 interrupt will fire 30 times a second (8bit) or once ever 8 seconds (16bit)

These are very rough calculations as I don't know how to include the remainder element of prescaling.

So looking back at my original requirement if I wanted to have the TIMER0 interrupt to fire 300 times, a prescaling value of 1:16 (488) comes closest to what I want? Is their a better way of doing this?


Mark
 
your calc seems great, wanna something easier? grab PicMultiCalc, and use the Timer Helper. This will list you the best match for your requirement. this include Preload, Prescaller, the calculated value and error% for 8 and 16 bits timer.

**broken link removed**

HTH
 
Thanks "Mister e" I'll have a look.

Pommie - The uC is a 18F1320, the application is really to charlieplex 6 LEDs (yep I have a JuneBug).

I suppose I could go for any setting that gives me something greater than 300 but I don't necessarily want to be stealing cycles from the main program.

This is just an exercise really, I have no "real" application.
 
Mister e,
You utility does the job very nicely, can you confirm my usage:-

OSC = 8Mhz
Reload = 7 (default)
Interrupt\Frequency = 300hz

Just a couple of questions as well I'm afraid
1. What is reload?
2. What is preload?

Thanks for your help!

Mark
 
Reload : some call it fudge factor... it's the amount of clock cycle needed to reload the timer. If you don't know, use the default and compare your results. It's a kind of fine tuning.

Preload : value to place in TMRxX register to ensure the correct timing by reducing the timer rollover.

Let's say we use the defaults, and we use a 16Bit timer, Calc says:
Preload=58876 => E5FC hex
Prescaler= 1:1

This mean you need to
1) set the Timer prescaller to 1:1
2) Load TMRxH with E5 hex
3) Load TMRxL with FC hex

Bad explanations i know... language barrier here...

which programming language are you going to use?
 
Last edited:
Ahh, thanks Master E, your english is fine!

I am using ASM.

So at the end of my interrupt service before I set the relevant flag to set the timer going again I plug in values E5FC to TMR0H and TMR0L?

Thanks
 
try this one
Code:
        LIST p=18F1320 
        include "P18F1320.inc"
        CONFIG OSC = HS, FSCM = OFF, IESO = OFF, PWRT = OFF, BOR = OFF, WDT = OFF, LVP = OFF, WRTC = OFF

        ;
        ;       Software constants
        ;       ==================
PreLoad = .58875    ; use to Preload Timer1 to generate 300Hz     

        ;
        ;       Software Vectors
        ;       ================
                ;
        org 0   ; Main Program
        bra Init;
                ;
        org 0X8 ; HiPri. INTs
         
TimerINT
        ;   
        ;       Timer1 ISR
        ;       ==========
                ;       Here we will just toggle a LED
                ;       at each INT events
                ;       producing 150Hz frequency
                ;
        BTG     LATB,0          ; Toggle LED on PORTB,0
        BCF     T0CON, TMR0ON   ; stop TIMER0 -- 1
        MOVLW   LOW(PreLoad)    ; load lowbyte - 1    
        MOVWF   TMR0L           ; -------------- 1
        MOVLW   HIGH(PreLoad)   ; load HighByte -1    
        MOVWF   TMR0H           ; -------------- 1
        BSF     T0CON, TMR0ON   ; start TIMER0 - 1 
                                ; ----------------              
                                ; Reload =   --- 6
                                ; 
        BCF     INTCON, TMR0IF  ; clear INT flag
        RETFIE  FAST            ; getout of here
        
        ;
        ;       Main Program 
        ;       ============
Init    ;
        ;       Configure PIC registers
        ;       -----------------------
                ;
        CLRF    TRISB           ; PORTB = output  
        CLRF    LATB            ; clear all PORTB I/Os
                                ;
        MOVLW   0XFF            ;
        MOVWF   ADCON1          ; Disable ALL ADCs
                                ;
        BSF     RCON,IPEN       ; Enable priority levels on interrupts
                                ;
        MOVLW   b'00100000'     ; Enable 
        MOVWF   INTCON          ;    TIMER0 int
        BSF     INTCON2,TMR0IP  ; Set TMR0 to High priority
                                ; 
        MOVLW   b'00001000'     ;       
        MOVWF   T0CON           ; Set TMR0 to
                                ;   off
                                ;   16 bit
                                ;   clock source = internal
                                ;   no prescaller... 1:1
                                ;
        MOVLW   LOW(PreLoad)    ; Load Preload
        MOVWF   TMR0L           ;   value
        MOVLW   HIGH(PreLoad)   ;       into    
        MOVWF   TMR0H           ;           TMR0
                                ;
        BSF     INTCON, GIEH    ; Enable Hi-Pri interupts     
        BSF     T0CON, TMR0ON   ; Start TIMER0
        ;
        ;       Main loop
        ;       ---------                        
Main            ;
                ;       nothing fancy, just
                ;       toggle another LED on PORTB,1 
                ;    
        BTG LATB,1              ; Toggle LED on PORTB,1
        bra Main                ; do it again
        end

I'm not an asm programmer, but it worked here. Maybe some could provide another/better solution

HTH
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top