Hot!Irregularities on Frequencies with timer0 interrupts.

Author
diegocw
New Member
  • Total Posts : 6
  • Reward points : 0
  • Joined: 2017/12/06 13:48:46
  • Location: 0
  • Status: offline
2017/12/07 11:39:53 (permalink)
0

Irregularities on Frequencies with timer0 interrupts.

Hello everyone, I have a little problem with timer0.
 
I am trying to toggle a pin from a PIC16f18875 (MPLABX+XC8) using interrupts caused by timer0.
I have no problems when using the other 6 timer in this chip. They work as expected, so my problem is only with timer0.
I'm using it in 8bit mode and the register with the preload value is TMR0H.
 
When TMR0H has values close to 255 the frequency of the interrupt is as expected (measured with an oscilloscope), but when the TMR0H values lower than 100 the frequency has more than 100Hz drift (in this case an expected frequency of 10000Hz is actually ~9900Hz) which isn't dramatic I guess, but for values lower than 30 (TMR0H=30) the frequency stays at aprox. 33,3kHz and no matter how much lower TMR0H gets, the frequency stays at 33,3kHz, even when TMR0H=1.
 
Maybe there is some sort of limitation for the frequency of which I haven't heard.
I've attached the exact code that I'm uploading to the chip.
 
Thanks in advance.
Diego.
#1

11 Replies Related Threads

    qɥb
    Monolothic Member
    • Total Posts : 1231
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: online
    Re: Irregularities on Frequencies with timer0 interrupts. 2017/12/07 14:08:21 (permalink)
    0
    Why are you reloading TMR0H on every interrupt?
    Are you running the compiler in FREE mode, or PRO mode?
    Have you checked how long the interrupt service actually takes to execute?
     

    PicForum "it just works"
    #2
    qɥb
    Monolothic Member
    • Total Posts : 1231
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: online
    Re: Irregularities on Frequencies with timer0 interrupts. 2017/12/07 14:39:29 (permalink)
    +1 (1)
    When you say "frequency", are you referring to the frequency at which interrupts are occuring, or the frequency on the RB0 pin (which will be half the interrupt frequency).
     
    By my count, in FREE mode, the ISR code is 27 instructions.
    Add 2 instruction clocks to get into the ISR, and 2 to get out, makes 31 instruction cycles total.
    At 8MHz clock, that means the fastest you can possibly service the interrupts is (8MHz/4)/31 = 64.5 kHz
    so the pin will be toggling at about 32.25 kHz.
     
    In PRO mode, the ISR comes down to 11 instructions, so about twice as fast.
     
    You could of course just run the PIC faster than 8MHz ...
     
     

    PicForum "it just works"
    #3
    qɥb
    Monolothic Member
    • Total Posts : 1231
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: online
    Re: Irregularities on Frequencies with timer0 interrupts. 2017/12/07 14:51:01 (permalink)
    0
    qɥb
    In PRO mode, the ISR comes down to 11 instructions, so about twice as fast.

    Without the redundant load of TMR0H, it's 9 instructions, so even better. :)
     
    If TMR0 is the only enabled interrupt source, then the "if(TMR0IF)" is also redundant.
    Removing that brings the ISR down to 7 instructions. 
    (20 in FREE mode).
    post edited by qɥb - 2017/12/07 14:52:21

    PicForum "it just works"
    #4
    diegocw
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2017/12/06 13:48:46
    • Location: 0
    • Status: offline
    Re: Irregularities on Frequencies with timer0 interrupts. 2017/12/07 16:00:02 (permalink)
    0
    I was reloading TMR0H because I thought it was necessary. Now i know it isn't.
    Yes I am running the compiler in FREE mode and I didn't know that it would make the code slower. Could you please point me to some documentation that explains the difference between PRO and FREE mode? or maybe explain your calculations?
    How could I check how long the ISR takes? just using the Simulator Debugging, or is there a better way?
     
    Thanks for all the other comments, ~33kHz it's pretty much right the maximum frequency (RB0 frequency) that i'm getting, so your calculations seem to be right.
     
    Diego
    #5
    qɥb
    Monolothic Member
    • Total Posts : 1231
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: online
    Re: Irregularities on Frequencies with timer0 interrupts. 2017/12/07 16:38:48 (permalink)
    0
    diegocw
    ...
    Yes I am running the compiler in FREE mode and I didn't know that it would make the code slower. Could you please point me to some documentation that explains the difference between PRO and FREE mode? or maybe explain your calculations?

    Simply looking in the LST file generated by the compiler, and counting instructions.
    Here's your original version, in FREE mode.
     859  0004                     _ISR:    
       860                           
       861                           ;incstack = 0
       862  0004  147E                   bsf    126,0    ;set compiler interrupt flag (level 1)
       863                           
       864                           ; Regs used in _ISR: [wreg+status,2+status,0]
       865  0005  3180                   pagesel    $
       866  0006  0020                   movlb    0    ; select bank0
       867  0007  087F                   movf    127,w
       868  0008  00F1                   movwf    ??_ISR+1
       869                           
       870                           ;timer0_v1.c: 40: if(TMR0IF){
       871  0009  002E                   movlb    14    ; select bank14
       872  000A  1E8C                   btfss    12,5    ;volatile
       873  000B  281A                   goto    i1l62
       874                           
       875                           ;timer0_v1.c: 41: TMR0IF = 0;
       876  000C  128C                   bcf    12,5    ;volatile
       877                           
       878                           ;timer0_v1.c: 42: LATBbits.LATB0^=1;
       879  000D  0020                   movlb    0    ; select bank0
       880  000E  0817                   movf    23,w    ;volatile
       881  000F  3901                   andlw    1
       882  0010  00F0                   movwf    ??_ISR
       883  0011  3001                   movlw    1
       884  0012  06F0                   xorwf    ??_ISR,f
       885  0013  0817                   movf    23,w    ;volatile
       886  0014  0670                   xorwf    ??_ISR,w
       887  0015  39FE                   andlw    -2
       888  0016  0670                   xorwf    ??_ISR,w
       889  0017  0097                   movwf    23    ;volatile
       890                           
       891                           ;timer0_v1.c: 44: TMR0H = 40;
       892  0018  3028                   movlw    40
       893  0019  009D                   movwf    29    ;volatile
       894  001A                     i1l62:    
       895  001A  0871                   movf    ??_ISR+1,w
       896  001B  0020                   movlb    0    ; select bank0
       897  001C  00FF                   movwf    127
       898  001D  107E                   bcf    126,0    ;clear compiler interrupt flag (level 1)
       899  001E  0009                   retfie
       900  001F                     __end_of_ISR:   

     
    and here it is in PRO mode, after removing the TMR0H load and TMR0IF test
       609  0004                     _ISR:    
       610                           
       611                           ;incstack = 0
       612                           ; Regs used in _ISR: [wreg]
       613  0004  3180                   pagesel    $
       614                           
       615                           ;timer0_v1.c: 43: TMR0IF = 0;
       616  0005  002E                   movlb    14    ; select bank14
       617  0006  128C                   bcf    12,5    ;volatile
       618                           
       619                           ;timer0_v1.c: 44: LATBbits.LATB0^=1;
       620  0007  3001                   movlw    1
       621  0008  0020                   movlb    0    ; select bank0
       622  0009  0697                   xorwf    23,f    ;volatile
       623  000A  0009                   retfie
       624  000B                     __end_of_ISR:

    Strictly speaking, the PAGESEL at the start is also redundant, as there are no GOTO or CALL instructions at all, so hand crafted assembler could be one instruction shorter again.
     

    PicForum "it just works"
    #6
    ric
    Super Member
    • Total Posts : 22101
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Irregularities on Frequencies with timer0 interrupts. 2017/12/07 16:51:08 (permalink)
    0
    diegocw
    ...
    Could you please point me to some documentation that explains the difference between PRO and FREE mode?

    XC8 User Guide.
    "3.6.1 What’s the Difference Between the Free, Standard and PRO Modes?"
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #7
    diegocw
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2017/12/06 13:48:46
    • Location: 0
    • Status: offline
    Re: Irregularities on Frequencies with timer0 interrupts. 2017/12/08 08:38:50 (permalink)
    0
    Thanks to both of you for the very useful information!
    #8
    DavidBLit
    Super Member
    • Total Posts : 1510
    • Reward points : 0
    • Joined: 2012/02/18 13:08:48
    • Location: The Land of Confusion
    • Status: online
    Re: Irregularities on Frequencies with timer0 interrupts. 2017/12/08 13:39:47 (permalink)
    0
    diegocw
    Thanks to both of you for the very useful information!

    mr green: mr green

    Yeah, "//Code and stuff".
    #9
    diegocw
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2017/12/06 13:48:46
    • Location: 0
    • Status: offline
    Re: Irregularities on Frequencies with timer0 interrupts. 2017/12/09 05:09:14 (permalink)
    0
    I was thinking, what if I write the ISR in assembler, but the rest in C. Would the FREE compiler still write a "slow" version of de ISR? or would it be exactly what i write in Assembler?
     
    #10
    mbrowning
    Just a Member
    • Total Posts : 786
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: Irregularities on Frequencies with timer0 interrupts. 2017/12/09 07:04:38 (permalink)
    0
    I've done entire ISRs in inline assembly.  The new 'k42 PIC18s make this easy since many registers are saved in shadow. For your PIC, you will have to be careful in context saving.
     
    Inline assembly will be exactly what you write for better or worse.  I found one exception to this for newer PIC18s - the MOVFF instruction is always replaced by the MOVFFL (in free mode), but this is true for compiler generated code as well.

    Can't remember. I've slept since then - Mark
    #11
    1and0
    Access is Denied
    • Total Posts : 7478
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Irregularities on Frequencies with timer0 interrupts. 2017/12/09 07:05:46 (permalink)
    0
    diegocw
    I was thinking, what if I write the ISR in assembler, but the rest in C. Would the FREE compiler still write a "slow" version of de ISR? or would it be exactly what i write in Assembler?

    It will do exactly as you say. ;)  Here's an assembly psect for your ISR, saved as filename isr.as:
    #include <xc.inc>
    psect   intentry,class=CODE,delta=2
            banksel PIR0
            bcf     PIR0,PIR0_TMR0IF_POSN
            banksel LATB
            movlw   LATB_LATB0_MASK
            xorwf   LATB
            retfie

    #12
    Jump to:
    © 2018 APG vNext Commercial Version 4.5