TMR0 Confusion


Closed Thread
Results 1 to 16 of 16

Thread: TMR0 Confusion

  1. #1

    Default TMR0 Confusion

    Just after a bit of help with TMR0

    I have hacked Darrell's SSPWM routine and am now adapting it to use TRM0 instead of TMR1.

    Now I note you cant stop/start TMR0 I dont think that's a major issue in my application which is generating a 2khz pwm.

    I'm confused with the reloading of the prescaler i'm going to use 1/4 with a preload of 6 and 8mhz int clock to generate an interrupt at 2000hz.

    After the interrupt is dealt with and I reload TMR0 with my PWM duty + preload do I have to reassign the prescaler every time?

    My hacked start SSPWM code is below.

    Config

    Code:
    'OPTION_REG = %00000001  'Set Option Reg for TMR0 and prescaler 1/4
    Start SSPWM

    Code:
     
    StartSPWM: 'Set DutyCycle before calling
    'For TMR0 2khz pwm and 8mhz clock Ticks = xxx per cycle 
    GIE = 1
    PEIE = 1
    TMR0_ON_TICKS = DutyCycle '(DutyCycle must be between 25 - 225 (10-90%)
    TMR0_OFF_TICKS = 255 - TMR0_ON_TICKS
    TMR0_ON_VAL = 255 - TMR0_ON_TICKS + 6
    TMR0_OFF_VAL = 255 - TMR0_OFF_TICKS + 6
     
    TMR0IE = 1 'Enable TMR0 interrupt enable bit (1 = enabled) 
    TMR0IF = 0 'Clear TMR0 interrupt flag
    TMR0 = 255 'Load TMR0 with 255 First tick will cause an interrupt 
     
    1/4 Prescaler setup here ?????
     
    return
    My hacked Int routine is below

    Code:
    asm
    INT_CODE
          if (CODE_SIZE <= 2)
            movwf   wsave              ; copy W to wsave register
            swapf   STATUS,W           ; swap status reg to be saved into W
            clrf    STATUS             ; change to bank 0 regardless of current bank
            movwf   ssave              ; save status reg to a bank 0 register
            movf    PCLATH,w           ; move PCLATH reg to be saved into W reg
            movwf   psave       ;6     ; save PCLATH reg to a bank 0 register
           endif
     
            btfss   INTCON, TMR0IF     ; is TMR0IF set?   Timer0 Interrupt Flag
            GOTO  NoTimerInt           ; No.  Bypass timer load
            btfss   _SPWMstate         ; Is Output High?
            GOTO  TurnON      ;9/15    ; No.
    TurnOFF
            bcf     _CmdPwr             ; Set CmdPwr Low
            bcf     _SPWMstate          ;
            MOVF    _TMR0_OFF_VAL,W     ;  1
            ADDWF   TMR0,F              ;  1    ; reload timer with correct value
            GOTO  TimerDone   ;12/27
    TurnON  
            bsf     _CmdPwr             ; Set CmdPwr High
            bsf     _SPWMstate          ;
            MOVF    _TMR0_ON_VAL,W      ;  1
            ADDWF   TMR0,F              ;  1    ; reload timer with correct value
     
    TimerDone        
     
            1/4 Prescaler setup here ?????
     
            bcf     INTCON, TMR0IF  ; 1/28 ; Clear Timer0 Interrupt Flag
     
    NoTimerInt    
            Movf    psave,w             ; Restore the PCLATH reg
            Movwf   PCLATH
            swapf   ssave,w             ; Restore the STATUS reg   
            movwf   STATUS
            swapf   wsave,f
            swapf   wsave,w    ; 6/34   ; Restore W reg
     
        Retfie                          ; Exit the interrupt routine 
    endasm

  2. #2
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: TMR0 Confusion

    Prescaler should be set and forget as I understand it
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  3. #3
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default Re: TMR0 Confusion

    When you use the USART, are you setting the Baudrate after each character sent? Nope!

    When you use the CCP module in PWM mode, do you need to configure the frequency each time you want to play with the duty cycle? Nope!

    Internal hardware are often like so, you set them, you forget them.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  4. #4


    Did you find this post helpful? Yes | No

    Default Re: TMR0 Confusion

    That's why i'm confused the 12F683 data sheet says that writes to the TMR0 reg clear the prescaler :?

    The prescaler is not readable or writable. When
    assigned to the Timer0 module, all instructions writing to
    the TMR0 register will clear the prescaler.

  5. #5
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default Re: TMR0 Confusion

    mm, seems I need to send my crystal ball again for repair... she don't want to tell me the PIC you're using
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  6. #6
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: TMR0 Confusion

    That can be a little confusing. the prescaler keeps a count. Say it is set up for 1:8, it will count to 8 then roll over. the roll over is the new tmr count. When you write the tmr0 they are saying the count in pre scale will be reset back to 0. so if it had a count of 5, it will be cleared to zero. But the amount of pre scale will persist, it will still be 1:8

    Steve, she just needs glasses, look above the quote
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  7. #7


    Did you find this post helpful? Yes | No

    Default Re: TMR0 Confusion

    Thanks for that CNC! makes sense. I'm using a 12F683 FYI. I'll do some bench testing

  8. #8
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: TMR0 Confusion

    Hi,
    Now I note you cant stop/start TMR0 I dont think that's a major issue in my application which is generating a 2khz pwm.
    You can't stop TMR0 when its in timer mode but you can switch it from timer- to counter mode which, as long as you don't have a any pulses coming on the T0CKI pin, will have the same effect as stopping it. As always YMMV but it's a "trick" that might work.

    /Henrik.

  9. #9


    Did you find this post helpful? Yes | No

    Default Re: TMR0 Confusion

    Quote Originally Posted by HenrikOlsson View Post
    Hi,

    You can't stop TMR0 when its in timer mode but you can switch it from timer- to counter mode which, as long as you don't have a any pulses coming on the T0CKI pin, will have the same effect as stopping it. As always YMMV but it's a "trick" that might work.

    /Henrik.
    That's sneaky!!

  10. #10
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: TMR0 Confusion

    With Timer0 on 16F's, there's no reason to stop the timer while reloading since it's an 8-bit timer.

    With 16-bit timers there is the slim possibility that the lowbyte will overflow to the highbyte at the same time you are reloading it.
    But that can't happen with an 8-bit timer, so just reload the 8-bit value and don't worry about it.
    DT

  11. #11


    Did you find this post helpful? Yes | No

    Default Re: TMR0 Confusion

    Thanks it's working on the bench now just need to check my TMR0 calculations.

    Using http://eng-serve.com/pic/pic_timer.html I get a prescaler of 1/4 and preload of 6 giving 500us interrupts (2khz) so that gives me 250 ticks per cycle with 8mhz clock.

    That works out at 2.5ticks per 1% duty.
    So for 10% duty I need to load 25 + 6 into TMR0 for the 90% off part of the cycle? and 225 + 6 for the 10% on part of the cycle?
    Does that look sound right?

    So my modified code looks like this.

    Code:
        TMR0_ON_TICKS = DutyCycle           '(DutyCycle must be between 25 - 225 (10-90%)
        TMR0_OFF_TICKS = 250 - TMR0_ON_TICKS
        TMR0_ON_VAL = 250 - TMR0_ON_TICKS + 6
        TMR0_OFF_VAL = 250 - TMR0_OFF_TICKS + 6
    Last edited by retepsnikrep; - 4th August 2011 at 07:32.

  12. #12


    Did you find this post helpful? Yes | No

    Default Re: TMR0 Confusion

    Although this appears to be working in my application I'm confused by

    PEIE var INTCON.6 'Peripheral Interrupt enable

    (Does this need to be on for TMR0 interrupt?) I currently have it enabled.

    I understand PEIE needs to be enabled for TMR1 but TMR0?

  13. #13


    Did you find this post helpful? Yes | No

    Default Re: TMR0 Confusion

    Appears not as seems to be working without it set?

  14. #14
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: TMR0 Confusion

    In the Interrupts section of the datasheet (under SPECIAL FEATURES OF THE CPU), there is a diagram that shows the Interrupt Logic.

    Only the peripherals in the red box are affected by PEIE.

    Name:  PEIE.gif
Views: 1040
Size:  19.2 KB
    DT

  15. #15


    Did you find this post helpful? Yes | No

    Default Re: TMR0 Confusion

    Thanks Darrel that's very clear, little by little i'm learning.

  16. #16


    Did you find this post helpful? Yes | No

    Default Re: TMR0 Confusion

    How long to execute the reload?

    I'm now using the timers for a few things but how do you work out the value to add on to the reload value for the time it takes to do the reload?

    Code:
     
     T1CON.0 = 0            'Stops Timer
     
     TMR1RunOn.Highbyte = TMR1H    'Load the Run-On (Over-Run) value (if any)
     TMR1RunOn.Lowbyte = TMR1L   'Load the Run-On (Over-Run) value (if any)
     TMR1RunOn = PreLoad + TMR1RunOn   'Calculate new Preload setting to include any timer overrun 
     TMR1H = TMR1RunOn.HighByte   'Load the timer with new value
     TMR1L = TMR1RunOn.LowByte      'Load the timer with new value
     PIR1.0 = 0     'Clear TMR1 int flag 
         T1CON.0 = 1            'Starts Timer
    The above for instance how much to add to keep the accuracy? How long does that all take? Any rough estimates? It's a pretty standard reload code but I could not find any examples. I'm running at 8mhz with 1/8 prescaler.

Members who have read this thread : 2

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts