PIC Timer 1 preload value

Status
Not open for further replies.

augustinetez

Active Member
Would somebody please check my maths for the preload value of Timer1 on a 16F1827 running at 4MHz.

I'm looking for a delay of 5mS, pretty sure I've screwed this up because it's taking a lot longer than 5mS on the hardware.

65536-(delay*clock freq)/(prescaler*4) = 65536-((.005*4000000)/(1*4))=60536 (EC78 HEX)

Thanks
 
I've never used a 16F1827 ... I just went from the datasheet and my experience with other micros that have bit me in similar ways. My favorite family of micros are the PIC16F15xxx series.

What - never heard of them

I'll have to go any look them up, do they have any specific advantages?.
 
If you just want a 5 ms beat, TMR2 might be a little shorter code. Tested in simulation:
Code:
Test
     movlb     1
     bsf       INTCON,PEIE
     clrf      PIE1                ;turn off TMR2 IE
     movlb     0
     movlw     250
     movwf     PR2
     movlw     b'00100001'         ;1:4 prescale, 1:5 postscale
                                   ;Net scale = 1:20 x 250 = 5000
     movwf     T2CON
TMR2_Beat
     clrf      TMR2                ;probably not necessary 
     bcf       PIR1,1              ;TMR2IF
     bsf       T2CON,TMR2ON        
     btfss     PIR1,1
     bra       $-1
     bcf       T2CON,TMR2ON
     nop
     bra       TMR2_Beat
John
 
The '$-16' was deliberate - I was under the mistaken impression that TMR1L & H only needing loading once, not every time the timer was stopped.

Anyway, moving the end jump to go back to reloading the registers, at the label 'toggle_pin' and reloading TMR1L & H again in the second half/low part of the code is now giving me the desired pulse, so the clock oscillator is loading correctly at 4MHz.

So the toggle pin exercise is sorted, now back to the original purpose, reading the encoder count.

John, thanks, I'll have a play with that in a little while.
 
The reason I mentioned the Special Events Trigger (Section 24.2.4) is it effectively gives you a period register for timer 1 so it will automatically roll over (and set T1IF) at a preset number of cycles. So, it's set and forget. It does require a CCPWM module to be available.

Mike.
 
Thanks Mike, I played with John's code post #23 and it does what I want with out needing any other dependencies.

Now to sort an encoder routine that works properly with high PPR Encoders.
 
augustinetez
If you want to shave a few microseconds, TMR2 can be let run continuously. Just start it in the setup. Since only one register needs to be cleared, there is insignificant error. That is what I usually do with TMR1 in capture mode.
Example:
Code:
     movlw     250                 ;total scale = 1:20 x 250 = 5000      
     movwf     PR2
     movlw     b'00100101'         ;1:4 prescale, 1:5 postscale
     movwf     T2CON               ;NB:TMR2 runs continuously

TMR2_Beat
     bcf       PIR1,1
     clrf      TMR2                
     btfss     PIR1,1
     bra       $-1
     bra       TMR2_Beat           ;do whatever you need to
 
Just for completeness, PR2 should be one less than the desired count, so 249. Not really relevant in this case but maybe for another (future) reader.
There is no need to clear TMR2 in the TMR2_Beat loop. Again, not really relevant etc.
Later, again for completeness, I'll post code to use the Special Events Trigger in case someone asks this question in the future and has already used Timer 2. Got to go out now.

Mike.
 
I agree, it rolls over. But the "do whatever you want" can take many cycles.


Presumably that's something like reading encoder counts, etc. That's why, when it runs continuously, it is safest to clear it. Oops, I just squeezed this simulation into one of my sandbox scribble projects. Ignore all the Not Founds.
 
Last edited:
Hi Terry:

I wonder if an in-line print string method would be of any use to you? The macros are normally placed near to top of the program before the code.

Cheerful regards...

Code:
putData macro   data            ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        movlw   data            ;                                 |
        call    data2LCD        ;                                 |
        endm                    ;

putCmd  macro   data            ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        movlw   data            ;                                 |
        call    cmnd2LCD        ;                                 |
        endm                    ;

putStr  macro   string          ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        call    putStrx         ; print in-line string to LCD     |
        dt      string,0        ; null terminated string          |
        endm                    ;
Code:
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;  display LCD 'spash' screen for 2 seconds.                      ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        radix   dec
splash                          ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        putCmd (128+0)          ; LCD line 1, htab 0              |
        putStr "VAR RATE V0.01  "       
        putCmd (192+0)          ; LCD line 2, htab 0              |
        putStr "ENCODER TEST    "
        return                  ;                                 |

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;  'putStrx' - print string embedded in-line with code.           ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
putStrx
        banksel TOSL            ; bank 31                         |31
        movf    TOSL,W          ; copy return address to FSR1     |31
        movwf   FSR1L           ;  "                              |31
        movf    TOSH,W          ;  "                              |31
        movwf   FSR1H           ;  "                              |31
        bsf     FSR1H,7         ; required for program memory     |31
        incf    TOSL,F          ; bump return/string address      |31
        skpnz                   ;  "                              |31
        incf    TOSH,F          ;  "                              |31
        movlb   0               ; bank 00                         |00
        movf    INDF1,W         ; end-of-string (0)?              |00
        skpnz                   ; no, skip (send char), else      |00
        return                  ; exit (end-of-string)            |00
        call    data2LCD        ; send character                  |00
        bra     putStrx         ; branch (next character)         |00
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
Hi Mike, by pure fluke, I've just been playing with your encoder routine (an not very successfully unfortunately - will put that in a seperate thread).

I'll keep those snippets above to play with later thankyou.
 
As promised above, the Special Events code,
Code:
setup            
            banksel    OSCCON
          movlw   b'01101000'        ;select 4MHz clock = 1MHz instruction cycle         
          movwf   OSCCON          ; Set PIC oscillator frequency                
            banksel    T1CON
            movlw      b'00000001'          ;timer 1 on
            movwf      T1CON
            banksel    CCP1CON
            movlw      b'00001011'          ;Special Events Trigger
            movwf      CCP1CON
            banksel    CCPR1L                ;set timer 1 to repeat
            movlw      low(5000)            ;every 500 clock cycles
            movwf      CCPR1L                ;equals 5mS
            banksel    CCPR1H
            movlw      high(5000)
            movwf      CCPR1H
loop        
            banksel    PIR1
            btfss      PIR1,CCP1IF          ;wait for interrupt flag
            goto      loop                  ;to be set
      
            ;5mS has passed
      
            bcf          PIR1,CCP1IF          ;clear it
            goto      loop

Mike.
Edit, why does the forum STILL mess up the formatting of code!!!!
 
Last edited:
Is it because you've got a combination of spaces and tabs?, and the formatting here is slightly different to MPLABX?. I've always presumed that when it messes my formatting up
 
I assumed it was and so I copied it into Notepad++ which removes the tabs but it still messes up.

Mike.
Edit, just found out that Notepad++ only replaces tabs when you edit a line.
I also use Notepad++, nice editor, and interesting to hear that it only replaces tabs when you edit a line.

What we need to do is examine the file using a hex editor, so we can see exactly what is in the file - I used to have one years back, can't remember what it was called now?.

Just did a quick google, HxD sounds familiar?.

I've just downloaded it, and copied and pasted your code from post #33, and it includes no tabs at all - but of course the forum software may have replaced them with spaces?.
 
Hi Mike,

I still have CodeTidy (dated 05/22/2008) installed. MPLab 8.92 has the option of replacing tabs with spaces, which I always keep on. Not sure about MPLABX. When I post, I use [code=MPASM] [/code] tags, but I'm not sure that is any different here than simple plain text or code tags, i.e., [plain] [/plain] or [code] [/code] . I assume you are using code tags.
 
OK, quick test.


Code:
Spaces and Tabs test using NotePad++
No Tab
    One Tab
    Spaces instead
        Two Tabs
        Spaces and Tab
        Tab and Spaces
        Just Spaces
Back to none.

Interesting - all came out OK, but when I entered Spaces followed by a Tab, Notepad++ replaced the Tab with Spaces. However, with Tab followed by Spaces, it was left alone.

Notepad++ is set to a Tab size of 4, and NOT to replace with spaces.
 
Last edited:
Trying a version with only spaces,
Code:
setup       
      banksel  OSCCON
      movlw    b'01101000'    ;select 4MHz clock = 1MHz instruction cycle    
      movwf    OSCCON         ; Set PIC oscillator frequency           
      banksel  T1CON
      movlw    b'00000001'    ;timer 1 on
      movwf    T1CON
      banksel  CCP1CON
      movlw    b'00001011'    ;Special Events Trigger
      movwf    CCP1CON
      banksel  CCPR1L         ;set timer 1 to repeat
      movlw    low(5000)      ;every 500 clock cycles
      movwf    CCPR1L         ;equals 5mS
      banksel  CCPR1H
      movlw    high(5000)
      movwf    CCPR1H
loop   
      banksel  PIR1
      btfss    PIR1,CCP1IF    ;wait for interrupt flag
      goto     loop           ;to be set
      ;5mS has passed
      bcf       PIR1,CCP1IF   ;clear it
      goto      loop

Mike.
Edit, appears it's tabs that cause the problem.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…