TMR1 - strange behaviour when toggeling a BIT variable on overflow


Closed Thread
Results 1 to 13 of 13
  1. #1
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    895

    Default TMR1 - strange behaviour when toggeling a BIT variable on overflow

    Hello There,

    This piece of code is meant to flash a LED every second.

    In my mind, and since the TMR1 is setup to overflow every 0.5 second, toggeling a BIT variable and checking when it is set should do the trick.

    First, as long as the variable is not reset, the LED will do weird and never really go OFF.

    Second, when I reset this variable (Flag = 0), it does kind of work, still not with a one second delay but 0.5 second instead.

    What is the explanation please? What is wrong with my code?

    Code:
    ' PIC 16F690
    
    @ __config _FCMEN_OFF &_IESO_OFF &_CPD_OFF &_WDT_OFF &_INTRC_OSC_NOCLKOUT &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF
    
    OPTION_REG = %10000000 '
    OSCCON     = %01100000 ' Internal oscillator 4MHz
    ANSEL      = %00000000 ' analog inputs Channels 0 to 7
    ANSELH     = %00000000 ' analog inputs Channels 8 to 11
    INTCON     = %11000000 ' INTerrupts CONtrol; GIE=1, T0IE=1
    T1CON      = %00110001 ' <5:4> prescaler 1:8, <1> Timer1 enabled
    
    DEFINE OSC 4
    
    Flag    VAR BIT
    CAL_H   CON 11
    CAL_L   CON 219 
    
    MAIN:
        IF PIR1.0 THEN
            PIR1.0 = 0
            TOGGLE Flag
            TMR1H = CAL_H : TMR1L = CAL_L
        ENDIF
        
        IF Flag THEN
            Flag = 0
            TOGGLE PORTC.0
        ENDIF
            
        GOTO MAIN
    
    END
    Roger

  2. #2
    Join Date
    Aug 2011
    Posts
    419


    1 out of 1 members found this post helpful. Did you find this post helpful? Yes | No

    Default Re: TMR1 - strange behaviour when toggeling a BIT variable on overflow

    First off, get rid of this:
    Code:
    INTCON     = %11000000 ' INTerrupts CONtrol; GIE=1, T0IE=1
    You're polling the TMR1F flag (PIR1.0), so you don't want to enable interrupts since there's no ISR to handle them.
    Weird things are going to happen.

    Secondly, with this
    Code:
        IF Flag THEN
            Flag = 0
            TOGGLE PORTC.0
        ENDIF
    You're only going to toggle PORTC.0 when Flag=1. Setting Flag back to 0 is going to screw with the next time TMR1IF gets set since it's now 0 (again).

    If you want to use 'Flag' then you could do
    Code:
    IF Flag THEN
       PORTC.0 = 1
    ELSE
       PORTC.0 = 0
    ENDIF
    or
    Code:
    PORTC.0 = Flag

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,531


    1 out of 1 members found this post helpful. Did you find this post helpful? Yes | No

    Default Re: TMR1 - strange behaviour when toggeling a BIT variable on overflow

    Code:
    Flag    VAR BIT
    
    TOGGLE Flag
    Don't do this!
    It might work now but it will mess you up. TOGGLE is ONLY meant to be used on PORT and LAT registers. Look it up in the manual for more details.

    You can easily toggle a bit variable by doing either one of
    Code:
    Flag = !Flag
    Flag = ~Flag

  4. #4
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,859


    Did you find this post helpful? Yes | No

    Default Re: TMR1 - strange behaviour when toggeling a BIT variable on overflow

    On top of the other replies, why not do this:

    Code:
    IF PIR1.0 THEN
            PIR1.0 = 0
            TOGGLE portc.0
            TMR1H = CAL_H : TMR1L = CAL_L
        ENDIF
    Toggle directly port insted of flag and then port.

    Not tested though.

    Ioannis

  5. #5
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    895


    Did you find this post helpful? Yes | No

    Default TMR1 - strange behaviour when toggeling a BIT variable on overflow

    Hi All,

    Thanks for all ideas and suggestions

    I tried them all except the one toggeling the port since I need to read that flag for different actions in the full program.

    Unfortunately, none of them work in a "one second ON - a second OFF" rhythm.

    Anyway, the way I found to make it work is to change the Flag BIT var to a BYTE one and sum up the number of PIR1.0 changes into the Flag var to trigger a port TOGGLE.

    Still, I don't understand why this code doesn't work (it actually works, but in a 0.5 sec rhythm)
    Code:
    ' PIC 16F690
    
    @ __config _FCMEN_OFF &_IESO_OFF &_CPD_OFF &_WDT_OFF &_INTRC_OSC_NOCLKOUT &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF
    
    OPTION_REG = %10000000
    OSCCON     = %01100000 ' Internal oscillator 4MHz
    ANSEL      = %00000000 ' analog inputs Channels 0 to 7
    ANSELH     = %00000000 ' analog inputs Channels 8 to 11
    T1CON      = %00110001 ' <5:4> prescaler 1:8, <1> Timer1 enabled
    
    DEFINE OSC 4
    
    Flag    VAR BIT
    CAL_H   CON 11
    CAL_L   CON 219
    
    Flag = 0
    
    MAIN:
        IF PIR1.0 THEN
            PIR1.0 = 0
            Flag = Flag + 1
            TMR1H = CAL_H : TMR1L = CAL_L
        ENDIF
    
        IF Flag THEN
            Flag = 0
            TOGGLE PORTC.0
        ENDIF
        
        GOTO MAIN
    
    END


    ...while this one will light the LED for one second and switch it OFF for another second (= what I finally want):
    Code:
    ' PIC 16F690
    
    @ __config _FCMEN_OFF &_IESO_OFF &_CPD_OFF &_WDT_OFF &_INTRC_OSC_NOCLKOUT &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF
    
    OPTION_REG = %10000000
    OSCCON     = %01100000 ' Internal oscillator 4MHz
    ANSEL      = %00000000 ' analog inputs Channels 0 to 7
    ANSELH     = %00000000 ' analog inputs Channels 8 to 11
    T1CON      = %00110001 ' <5:4> prescaler 1:8, <1> Timer1 enabled
    
    DEFINE OSC 4
    
    Flag    VAR BYTE
    CAL_H   CON 11
    CAL_L   CON 219
    
    Flag = 0
    
    MAIN:
        IF PIR1.0 THEN
            PIR1.0 = 0
            Flag = Flag + 1
            TMR1H = CAL_H : TMR1L = CAL_L
        ENDIF
    
        IF Flag > 1 THEN
            Flag = 0
            TOGGLE PORTC.0
        ENDIF
        
        GOTO MAIN
    
    END
    Roger

  6. #6
    Join Date
    Aug 2011
    Posts
    419


    Did you find this post helpful? Yes | No

    Default Re: TMR1 - strange behaviour when toggeling a BIT variable on overflow

    Maybe because TMR1 is set for a 500ms interval?

  7. #7
    Join Date
    May 2013
    Location
    australia
    Posts
    2,400


    1 out of 1 members found this post helpful. Did you find this post helpful? Yes | No

    Default Re: TMR1 - strange behaviour when toggeling a BIT variable on overflow

    if you use a chip with clc module you can blink a led with no code at all
    its all in hardware once configured

    Code:
    '****************************************************************
    '*  Name    : hw-blinky.BAS                                     *
    '*  Author  : richard                                           *
    '*  Notice  : Copyright (c) 2023 caveat emptor                  *
    '*          : All Rights Reserved                               *
    '*  Date    : 18/05/2023                                        *
    '*  Version : 1.0                                               *
    '*  Notes   : pic16f18875@4mhz                                  *
    '*          : led portb.0 blink @1hz                            *
    '****************************************************************
    #CONFIG
        __config _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT1 & _CLKOUTEN_OFF & _CSWEN_ON & _FCMEN_ON
        __config _CONFIG2, _MCLRE_ON & _PWRTE_OFF & _LPBOREN_OFF & _BOREN_ON & _BORV_LO & _ZCD_OFF & _PPS1WAY_OFF & _STVREN_ON & _DEBUG_OFF
        __config _CONFIG3, _WDTCPS_WDTCPS_11 & _WDTE_ON & _WDTCWS_WDTCWS_7 & _WDTCCS_LFINTOSC
        __config _CONFIG4, _WRT_OFF &   _LVP_OFF
        __config _CONFIG5, _CP_OFF & _CPD_OFF
    
    
    #ENDCONFIG   
        ANSELB = 0   
        trisb=$fe  'led var portb.0
        OSCCON1 = $60 
        OSCCON3 =  0 
        OSCEN =  0
        OSCFRQ =  2
        OSCTUNE =  0
        
    'led var portb.0
    gosub   set_blinky
     
     
      
    loopy:
    ; look no hands
    goto loopy 
     
     
     
    end   
       
    set_blinky:   
        ;// Set the CLC1 to the options selected in the User Interface
        ;// LC1G1POL not_inverted; LC1G2POL inverted; LC1G3POL not_inverted; LC1G4POL not_inverted; LC1POL not_inverted; 
        CLC1POL = $02;
        ;// LC1D1S T1_overflow; 
        CLC1SEL0 = $0B;
        ;// LC1D2S CLC1_OUT; 
        CLC1SEL1 = $20;
        ;// LC1D3S CLC1_OUT; 
        CLC1SEL2 = $20;
        ;// LC1D4S CLC1_OUT; 
        CLC1SEL3 = $20;
        ;// LC1G1D3N disabled; LC1G1D2N disabled; LC1G1D4N disabled; LC1G1D1T enabled; LC1G1D3T disabled; LC1G1D2T disabled; LC1G1D4T disabled; LC1G1D1N disabled; 
        CLC1GLS0 = $02;
        ;// LC1G2D2N disabled; LC1G2D1N disabled; LC1G2D4N disabled; LC1G2D3N disabled; LC1G2D2T enabled; LC1G2D1T disabled; LC1G2D4T disabled; LC1G2D3T disabled; 
        CLC1GLS1 = $08;
        ;// LC1G3D1N disabled; LC1G3D2N disabled; LC1G3D3N disabled; LC1G3D4N disabled; LC1G3D1T disabled; LC1G3D2T disabled; LC1G3D3T disabled; LC1G3D4T disabled; 
        CLC1GLS2 = $00;
        ;// LC1G4D1N disabled; LC1G4D2N disabled; LC1G4D3N disabled; LC1G4D4N disabled; LC1G4D1T disabled; LC1G4D2T disabled; LC1G4D3T disabled; LC1G4D4T disabled; 
        CLC1GLS3 = $00;
        ;// LC1EN enabled; INTN disabled; INTP disabled; MODE 1-input D flip-flop with S and R; 
        CLC1CON = $84;
        
        ;// Set the CLC3 to the options selected in the User Interface
        ;// LC3G1POL not_inverted; LC3G2POL inverted; LC3G3POL not_inverted; LC3G4POL not_inverted; LC3POL not_inverted; 
        CLC3POL = $02;
        ;// LC3D1S CLC1_OUT; 
        CLC3SEL0 = $20;
        ;// LC3D2S CLC3_OUT; 
        CLC3SEL1 = $22;
        ;// LC3D3S CLC3_OUT; 
        CLC3SEL2 = $22;
        ;// LC3D4S CLC3_OUT; 
        CLC3SEL3 = $22;
        ;// LC3G1D3N disabled; LC3G1D2N disabled; LC3G1D4N disabled; LC3G1D1T enabled; LC3G1D3T disabled; LC3G1D2T disabled; LC3G1D4T disabled; LC3G1D1N disabled; 
        CLC3GLS0 = $02;
        ;// LC3G2D2N disabled; LC3G2D1N disabled; LC3G2D4N disabled; LC3G2D3N disabled; LC3G2D2T enabled; LC3G2D1T disabled; LC3G2D4T disabled; LC3G2D3T disabled; 
        CLC3GLS1 = $08;
        ;// LC3G3D1N disabled; LC3G3D2N disabled; LC3G3D3N disabled; LC3G3D4N disabled; LC3G3D1T disabled; LC3G3D2T disabled; LC3G3D3T disabled; LC3G3D4T disabled; 
        CLC3GLS2 = $00;
        ;// LC3G4D1N disabled; LC3G4D2N disabled; LC3G4D3N disabled; LC3G4D4N disabled; LC3G4D1T disabled; LC3G4D2T disabled; LC3G4D3T disabled; LC3G4D4T disabled; 
        CLC3GLS3 = $00;
        ;// LC3EN enabled; INTN disabled; INTP disabled; MODE 1-input D flip-flop with S and R; 
        CLC3CON = $84;
        
        RB0PPS = $03;   //RB0->CLC3:CLC3OUT; 
        T1CLK = 1
        T1CON = $31; 
    return
    Last edited by richard; - 18th May 2023 at 11:39.
    Warning I'm not a teacher

  8. #8
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,859


    Did you find this post helpful? Yes | No

    Default Re: TMR1 - strange behaviour when toggeling a BIT variable on overflow

    Nice one Richard! It good to refresh these ideas based on hardware peripherals.

    But I am sure F690 does not have CLC nor he (Roger) uses MCC.

    Ioannis

  9. #9
    Join Date
    Aug 2011
    Posts
    419


    Did you find this post helpful? Yes | No

    Default Re: TMR1 - strange behaviour when toggeling a BIT variable on overflow

    ... nor he (Roger) uses MCC.
    There's an updated version of the standalone CLC Designer Tool over on the Swordfish site at CLCDesignerTool.
    It can produce code in C or various dialects of BASIC. There's even a simple interactive simulator to explore the basic functions.

    It's pretty up to date for the 18F family, but the list of supported 16F's hasn't been updated in a while.
    If you use it and need something, just let me know...
    Last edited by tumbleweed; - 18th May 2023 at 13:51.

  10. #10
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,859


    Did you find this post helpful? Yes | No

    Default Re: TMR1 - strange behaviour when toggeling a BIT variable on overflow

    Thanks for the tip!

    Ioannis

  11. #11
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,616


    Did you find this post helpful? Yes | No

    Default Re: TMR1 - strange behaviour when toggeling a BIT variable on overflow

    BTW ...

    I remember Melanie posted ( long, long time ago ) about such a very simple blink trick ... with " classical " PIC's ....

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  12. #12
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    895


    Did you find this post helpful? Yes | No

    Default TMR1 - strange behaviour when toggeling a BIT variable on overflow

    Bravo Alain, excellente mémoire

    I think I found the thread you're referring to and this is the post that is what I'm doing too:
    https://www.picbasic.co.uk/forum/sho...5912#post75912

    I have to compare Sayzer's code and I find out what's wrong with mine.
    Roger

  13. #13
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,616


    Did you find this post helpful? Yes | No

    Default Re: TMR1 - strange behaviour when toggeling a BIT variable on overflow

    RTFM Datasheet § 6.5.1 ...

    For writes, it is recommended that the user simply stop
    the timer and write the desired values. A write
    contention may occur by writing to the timer registers,
    while the register is incrementing. This may produce an
    unpredictable value in the timer register.
    Might be a good reason ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

Similar Threads

  1. Difficulty toggling LED with TMR1 overflow interrupt
    By jgjgjg in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 30th July 2012, 11:17
  2. Strange IT behaviour
    By MikeBZH in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 10th February 2012, 09:00
  3. Strange behaviour
    By financecatalyst in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 8th October 2009, 22:35
  4. Strange Serout Behaviour
    By bluesmoke in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 12th August 2009, 04:12
  5. Strange HSEROUT behaviour
    By Charles Linquis in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 7th July 2006, 23:37

Members who have read this thread : 1

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