Hot!TMR1 as volatile variable or not

Page: 12 > Showing page 1 of 2
Author
naeem1234
Junior Member
  • Total Posts : 117
  • Reward points : 0
  • Joined: 2015/02/19 06:39:28
  • Location: 0
  • Status: offline
2017/10/12 22:14:42 (permalink)
0

TMR1 as volatile variable or not

Hello everyone
My chip is PIC18F46K22.
I am using Timer1 in 16-bit counter mode. Following function is called periodically in the code.
void sendTMR1CounterValue(void) {
    
   unsigned int T1Value = 0;

   T1Value = TMR1;
   TMR1=0;
   bin2asciii(T1Value, TMR1Decimal);
}

 
The Timer1 should have reset to zero after every call to the above function. At times it does not happen like that, but at other times it works as expected.
 
Do i have to declare 'T1Value' as volatile variable or something other than that could be the problem?
 
Any help is appreciated.
#1

33 Replies Related Threads

    qhb
    Superb Member
    • Total Posts : 5824
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/12 22:23:07 (permalink)
    +1 (1)
    Is it called from interrupt code, or non-interrupt code?
    You only need to declare a variable as "volatile" if you write to it in interrupt code, and read from it in non-interrupt code.
    Be very aware of what "16 bit read/write mode" means on a timer register.
    You did not show your timer initialisation, so I don't know how you have set the RD16 bit.
    When RD16 is set, the high byte of the timer is accessed via a buffer, so it's important that you:
    • read low byte then high byte, and
    • write high byte then low byte.
    You will need to check the assembly output from the compiler to see what your code is doing.
    As I recall the compiler is not guaranteed to access them in the right order.
     
     
     
    #2
    naeem1234
    Junior Member
    • Total Posts : 117
    • Reward points : 0
    • Joined: 2015/02/19 06:39:28
    • Location: 0
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/12 22:33:28 (permalink)
    0
    qhb
    • read low byte then high byte, and
    • write high byte then low byte.
     



    Yes the RD16 is set in the timer initialization.
    Do i still have to read the high and low bytes of TMR1 separately one by one?

     
    T1Value = TMR1;
     

    Does the above code not sufficient to read both high low bytes into T1Value integer variable?
     
    And is it not enough to reset TMR1 by following line?
     
     TMR1=0;

    post edited by naeem1234 - 2017/10/12 22:34:53
    #3
    qhb
    Superb Member
    • Total Posts : 5824
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/12 22:40:31 (permalink)
    +1 (1)
    naeem1234
    Do i still have to read the high and low bytes of TMR1 separately one by one?
    T1Value = TMR1;

    Does the above code not sufficient to read both high low bytes into T1Value integer variable?

    As I already said:

    You will need to check the assembly output from the compiler to see what your code is doing.

    You can't just assume it will work.
     

    And is it not enough to reset TMR1 by following line?
     TMR1=0;

    There are no 16 bit writes in the PIC18F assembly language, so the C compiler has to write zero to the low and high bytes of the timer register separately.
    You won't know what order it writes unless you check the assembly output.
     
    #4
    naeem1234
    Junior Member
    • Total Posts : 117
    • Reward points : 0
    • Joined: 2015/02/19 06:39:28
    • Location: 0
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/12 23:16:17 (permalink)
    0
    Ok, thanks for the details.
     
    Apart from the problem that would arise from the wrong order in which 16-bit TMR1 is read or updated, i am facing a different problem.
     
    I am reading the TMR1 counter value periodically and every read resets the TMR1 counter. So the next read only gives the number of counts during the previous period, and it comes out to be as expected count value.
     
    But when i read TMR1 after a shorter interval then i should get a reduced value of TMR1 count, but mysteriously i get the exact same value as previous read value, and it appears as if TMR1 somehow missed the reset to zero instruction or did not execute it at all.
     
    Is it possible that its due to some optimization in the code so then if i declare it as volatile then it will always reset the TMR1 count? Or something that other than that? 
    #5
    jtemples
    Super Member
    • Total Posts : 10199
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/12 23:51:16 (permalink)
    +1 (1)
    T1Value is local to a function; I can't see any point in making it volatile.
     
    Apart from the problem that would arise from the wrong order in which 16-bit TMR1 is read or updated

     
    You should resolve that before trying to debug other problems with TMR1.
     
    #6
    naeem1234
    Junior Member
    • Total Posts : 117
    • Reward points : 0
    • Joined: 2015/02/19 06:39:28
    • Location: 0
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/13 00:07:00 (permalink)
    0
    jtemples
    You should resolve that before trying to debug other problems with TMR1.

     
    If i explicitly read and write TRM1 low and high bytes separately even when TMR1 is set as 16-bit timer, will that work?
    #7
    qhb
    Superb Member
    • Total Posts : 5824
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/13 00:37:17 (permalink)
    +1 (1)
    naeem1234
    ...even when TMR1 is set as 16-bit timer, will that work?

    Your continued use of incorrect terminology makes me suspect you don't understand the issues.
    Timer1 IS ALWAYS a 16 bit timer, you don't have any control over that.
    All you have control over is how the value is accessed by you.
    If the RD1 bit is clear, you have direct access to both the high and low bytes of the timer count.
    That means it is possible for the value to change between you reading the low byte and the high byte.
    (e.g. you might read the low byte when the value is 0x00FF, receiving 0xFF. If it increments to 0x0100 before you read the high byte, then will read 0x01, and therefore think the value is 0x01FF.)
    That is why the RD16 bit exists, to insert a latch between you and the high byte.
    This is all explained in section 12.6 of the datasheet.
     
    #8
    naeem1234
    Junior Member
    • Total Posts : 117
    • Reward points : 0
    • Joined: 2015/02/19 06:39:28
    • Location: 0
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/13 01:06:15 (permalink)
    0
    qhb
    Timer1 IS ALWAYS a 16 bit timer, you don't have any control over that.
    All you have control over is how the value is accessed by you.

     
    I am trying to learn it.
    So as my RD16 bit is set so now i have tp check the assembly code if order in which high and low bytes are operated is correct or not.
     
    As i have not worked on assembly so far, would you kindly tell me which file and location i will find the corresponding assembly code?
    #9
    1and0
    Access is Denied
    • Total Posts : 6963
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/13 02:58:59 (permalink)
    +1 (1)
    naeem1234
    I am trying to learn it.

    Then read the datasheet a few more times.
     

    So as my RD16 bit is set so now i have tp check the assembly code if order in which high and low bytes are operated is correct or not.

    Yes. However, the order might change with the next compiler version or whatnot.
     

    As i have not worked on assembly so far, would you kindly tell me which file and location i will find the corresponding assembly code?

    The assembly code should appear in the disassembly listing window, the program memory window, and the listing file.
     
    #10
    DarioG
    Scheisse Menschen
    • Total Posts : 52446
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: hi there
    • Status: online
    Re: TMR1 as volatile variable or not 2017/10/13 03:11:29 (permalink)
    0
    There used to be some function and/or macro, named WriteTimer1() which should take care of it all.
    #11
    naeem1234
    Junior Member
    • Total Posts : 117
    • Reward points : 0
    • Joined: 2015/02/19 06:39:28
    • Location: 0
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/13 03:40:58 (permalink)
    +1 (1)
    DarioG
    There used to be some function and/or macro, named WriteTimer1() which should take care of it all.




    This looks like a good option. Would you kindly tell me which header file it's prototype can be found?
    #12
    1and0
    Access is Denied
    • Total Posts : 6963
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/13 03:47:11 (permalink)
    +1 (1)
    naeem1234
     
    This looks like a good option. Would you kindly tell me which header file it's prototype can be found?

    Plib is not longer being supported. Why not just code the accesses in the correct order yourself?
    #13
    naeem1234
    Junior Member
    • Total Posts : 117
    • Reward points : 0
    • Joined: 2015/02/19 06:39:28
    • Location: 0
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/13 04:05:20 (permalink)
    0
    1and0
    Plib is not longer being supported. Why not just code the accesses in the correct order yourself?


    Will this data structure work for accessing high and low bytes separately?
     

    union{
    struct{
    unsigned char t1hi;
    unsigned char t1lo;
    }s_timer1;
    unsigned int timer1;
    }u_timer1;

     
    Is the order of 't1hi' and 't1lo' above correct or is it the other was around?
     
    Should i also reset the RD16 bit for TMR1?
    #14
    qhb
    Superb Member
    • Total Posts : 5824
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/13 04:13:44 (permalink)
    +2 (2)
    No, you need  RD16 to be set!
    Those macros are present in PIC18.h, which should be sucked in for you by xc.h
     
    pic18.h contains these lines:

     
    /* Accurate read/write macros for 16-Bit timers */
    /*** please note, the timer needs to be enabled ***
    *** to handle 16-Bit read/write operations for ***
    *** these routines to be of benefit ***/
    #define WRITETIMER0(x) ((void)(TMR0H=((x)>>8),TMR0L=((x)&0xFF)))
    #define WRITETIMER1(x) ((void)(TMR1H=((x)>>8),TMR1L=((x)&0xFF)))
    #define WRITETIMER3(x) ((void)(TMR3H=((x)>>8),TMR3L=((x)&0xFF)))
    #define READTIMER0() (TMR0)
    #define READTIMER1() (TMR1)
    #define READTIMER3() (TMR3)

     
    So that implies that the read operation would just work anyway, but you need to use the macro if you want to write to the timer while it is running.
     
    post edited by qhb - 2017/10/13 04:15:18
    #15
    naeem1234
    Junior Member
    • Total Posts : 117
    • Reward points : 0
    • Joined: 2015/02/19 06:39:28
    • Location: 0
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/13 04:22:50 (permalink)
    +1 (1)
    qhb
    No, you need  RD16 to be set!
    Those macros are present in PIC18.h, which should be sucked in for you by xc.h
     
    pic18.h contains these lines:

     
     
     
    /* Accurate read/write macros for 16-Bit timers */
    /*** please note, the timer needs to be enabled ***
    *** to handle 16-Bit read/write operations for ***
    *** these routines to be of benefit ***/
    #define WRITETIMER0(x) ((void)(TMR0H=((x)>>8),TMR0L=((x)&0xFF)))
    #define WRITETIMER1(x) ((void)(TMR1H=((x)>>8),TMR1L=((x)&0xFF)))
    #define WRITETIMER3(x) ((void)(TMR3H=((x)>>8),TMR3L=((x)&0xFF)))
    #define READTIMER0() (TMR0)
    #define READTIMER1() (TMR1)
    #define READTIMER3() (TMR3)

     
    So that implies that the read operation would just work anyway, but you need to use the macro if you want to write to the timer while it is running.
     




    Its strange.. the last part of your reply does not appear in the post. I saw it in the 'Quote' while writing this reply.
     
    Anyways thanks for this find.
     
    BTW if read just work straight then do you think my original issue will be solved by this?
    #16
    qhb
    Superb Member
    • Total Posts : 5824
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/13 04:36:18 (permalink)
    +1 (1)
    Don't forget, you were doing a write also (when you cleared the timer), which as I just said, you need the macro to do correctly.
     
    #17
    1and0
    Access is Denied
    • Total Posts : 6963
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/13 04:41:05 (permalink)
    0
    qhb
    So that implies that the read operation would just work anyway, ...

    Does this also imply the XC8 compiler "guarantee" to access the low byte before the high byte when accessing a 16-bit SFR?
     
    #18
    qhb
    Superb Member
    • Total Posts : 5824
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/13 04:45:57 (permalink)
    +1 (1)
    It must do (when reading) if that is all the macro they supply does. See above.
    I assume it also does when writing, which is why they need to manually do it high then low.
     
    #19
    1and0
    Access is Denied
    • Total Posts : 6963
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: TMR1 as volatile variable or not 2017/10/13 04:52:13 (permalink)
    +1 (1)
    Yes, it must in order for those macros to work correctly. Is this order-ness documented in the XC8 User's Guide?
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2017 APG vNext Commercial Version 4.5