1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Problems with TIMER0

Discussion in 'Oshonsoft' started by Winch, Sep 21, 2014.

  1. Winch

    Winch New Member

    Joined:
    Sep 5, 2014
    Messages:
    24
    Likes:
    0
    Dear all,

    Can anyone tell me what is wrong with this code?
    I try to create a time delay of one minute. Instead, I get three seconds?
    I can not figure out the error?

    I use the software Oshonsoft! (basic)

    Code (text):
    'DEVICE 12F675

    Define CONFIG = 0x3184
    AllDigital                    'alle ports digital

    'parameters analoge ingang.
    Define ADC_CLOCK = 3                    'resolutie 8 bits
    Define ADC_SAMPLEUS = 50                    'sample time 5

    'poortnamen
    Symbol buzzer = GPIO.2                    'BUZZER is connected to port GPIO.2
    Symbol irled = GPIO.4                    'IR LED is connected to port GPIO.4
    Symbol led = GPIO.5                    'LED is connected to port GPIO.5

    'variabelen declareren
    Dim spanning As Byte                    'voltage as variable "Byte" (here the measured analog value)
    Dim var_timer As Byte                    'variable "TIMER" value "As Byte"
    Dim timer_limite As Byte                    '"TIMER" limite "As Byte"
    Dim timer As Byte                    'higher variable timer setting "As Byte"
    Dim puls As Bit                    'puls is turned as "1"
    Dim puls_2 As Bit                    'puls_2 is turned as "1"

    INTCON.GIE = 0                    'Disables all unmasked interrupts make sure by start that Interrupt = 0

        '543210
    GPIO = %000000                    'outputs at start are low-level
    TRISIO = %001011                    'GPIO.0 is set as input, GPIO.2, GPIO,4 en GPIO.5 is set as output

        '76543210
    ADCON0 = %00000001                    'bit0 as a/d geselecteerd, CHS1:CHS0 bit 3-2 are selected as AN0
    ANSEL = %00000001                    'ANS0 (leg 7) is set as "analog input" connected the IR FILTER

    'The INTCON register is a readable and writable register, which contains the various Enable And flag bits For TMR0 register overflow,
    'GPIO port change And external GP2 / int pin interrupts.

    INTCON.GIE = 1                    'Enables all unmasked interrupts
    INTCON.T0IE = 1                    'Enables the TMR0 interrupt (TMR0 Overflow Interrupt Enable bit)
    INTCON.T0IF = 1                    'TMR0 register has overflowed (must be cleared in software)

    'The OPTION register is a readable And writable register, which contains various control bits To configure:
    'TMR0/wdt prescaler 'external GP2/int Interrupt 'TMR0 'weak pull - ups On GPIO

    OPTION_REG.INTEDG = 0                    'Interrupt on falling edge of GP2/INT pin
    OPTION_REG.T0CS = 0                    'Internal instruction cycle clock (CLKOUT)
    OPTION_REG.T0SE = 0                    'Increment on low-to-high transition on GP2/T0CKI pin
    OPTION_REG.PSA = 0                    'Prescaler is assigned to the TIMER0 module
    OPTION_REG.PS0 = 0                    'Set the prescaler
    OPTION_REG.PS1 = 1                    'to increment TMR0
    OPTION_REG.PS2 = 1                    'every 128th instruction cycle

    TMR0 = 0                    'Clear TMR0 initially, (reset de timer0 module register)

    var_timer = 0                    'variable waarde van de timer is 0
    timer = 0                    'set timer to 0

    run:
    timer_limite = 61                    'intern klok (1mhz / (128 * 128)) give pulse afther every 1 seconden

    If var_timer > timer_limite Then                    'when var_timer is greater than timer_limite (61) than ...
            var_timer = 0                    'set var_timer back to 0
            puls = 1
        Endif
       
        If puls = 1 Then
            timer = timer + 1                    'increase timer by 1
            If timer > 60 Then led = 1                    'if timer is greater then 60 then.....
        Endif
       
    Goto run

    End                    'end program            

        'Interrupt
        On Interrupt                    'Interrupt timer
            Save System                    'Save
            var_timer = var_timer + 1                    'increment var_timer
            INTCON.T0IF = 0                    'clear Interrupt flag
        Resume                    'jump back where it started
     
     
  2. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,154
    Likes:
    907
    Location:
    Rochdale UK
    ONLINE
    If your timer is on the 1:128 prescale then 256 * 128 * 1nS is definitely not 1 minute..

    The largest number is on the 8 bit timer0 is... 256 * 256 * 1nS = 65,5mS If you use this you only get 3 seconds.

    Use a milli counter inside your interrupt..... Use the same setup but load TMR0 with 99.... This yeilds 20mS so a count of 5 will give you a 1 second count..
    Initialize TMRO with 99

    Then load the timer each interrupt and increase "milli" 5 times... Then increase the seconds....
     
  3. jjw

    jjw Member

    Joined:
    Apr 16, 2012
    Messages:
    258
    Likes:
    15
    Location:
    Helsinki, Finland
    It is running too fast because the variable puls is 1 after first 61 runs of the loop and stays there.
    It should be set to 0 after label "run:"
    What is the clock frequency of the PIC?
    If it is 4MHz, I think timer0 should be set to 128 +- few cycles in the interrupt routine.
    Now it runs too slow.
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Winch

    Winch New Member

    Joined:
    Sep 5, 2014
    Messages:
    24
    Likes:
    0

    Dear JJW,

    If I do that then it will never start? (It should be set to 0 after label "run:")
    Or I do not understand your explanation.
    Can you show me in code please.
    Clock frequency is 4MHz. Prescaler now is 1:128
     
  6. Winch

    Winch New Member

    Joined:
    Sep 5, 2014
    Messages:
    24
    Likes:
    0
    What do you mean white a milli counter inside the interrupt? I need some more explanation.
    I thought I had it under control but now I'm even further from home. :(
     
  7. jjw

    jjw Member

    Joined:
    Apr 16, 2012
    Messages:
    258
    Likes:
    15
    Location:
    Helsinki, Finland
     
  8. Winch

    Winch New Member

    Joined:
    Sep 5, 2014
    Messages:
    24
    Likes:
    0
    Thanks JJW,

    It works.
    But now I have a problem! I do not know what I'm doing! That is the painful conclusion.
    What does that TMR0 exactly? Unfortunately that is not clear to me now.
    Please, would you explain me that again.

    Thanks
     
  9. Winch

    Winch New Member

    Joined:
    Sep 5, 2014
    Messages:
    24
    Likes:
    0
    I untherstand that it was smarter to change the sentence "timer = timer + 1" in the above Aliana!
    So I did.
    But the TMR0 is still not clear to me.

    Thanks in advance.

    PHP:
    var_timer = 0                    'variable waarde van de timer is 0
    timer = 0                    '
    set timer to 0
    timer_limite = 61                    'intern klok (1mhz / (128 * 128)) give pulse afther every 1 second

    run:
    puls = 0

        If var_timer > timer_limite Then                    '
    when var_timer is greater than timer_limite (61) than ...
            var_timer = 0                    'set var_timer back to 0
            timer = timer + 1                    '
    increase timer by 1
            puls = 1
        Endif
       
        puls = 1
            If timer > 10 Then
            led = 1                    'if timer is greater then 60 then.....
        Endif
       
    Goto run

    End                    '
    end program              

        'Interrupt
        On Interrupt                    '
    Interrupt timer
            Save System                    'Save
            TMR0 = 128
            var_timer = var_timer + 1                    '
    increment var_timer
            INTCON.T0IF = 0                    'clear Interrupt flag
        Resume                    '
    jump back where it started
     
     
  10. jjw

    jjw Member

    Joined:
    Apr 16, 2012
    Messages:
    258
    Likes:
    15
    Location:
    Helsinki, Finland
    Timer0 is
    Timer0 is just an 8-bit counter.
    It's clock input comes from system clock ( oscillator frequency / 4 ) possibly divided by the prescaler.
    It counts upwards and can generate an interrupt when it goes from 255 to zero
    In your program ( first uncorrect version ) it generated an interrupt at frequency 4MHz/( 4*128*256 ) ~ 30.5 Hz
    When timer0 is set to 128 in the interrupt routine, it counts from 128 to 255 and the interrupt frequency is ~ 61Hz.
    Your program counts the number of interrupts and when it is 61 ( actually your program counts 62, from 0 to 61 ) it increments the seconds counter.
     
  11. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,154
    Likes:
    907
    Location:
    Rochdale UK
    ONLINE
    Sorry winch! I wasn't paying enough attention last night...
    I now see you have var_timer AND timer as your variables.... I didn't see the two variables....
     
  12. Winch

    Winch New Member

    Joined:
    Sep 5, 2014
    Messages:
    24
    Likes:
    0
    Dear JJW,

    Thanks for your explanation!
     

Share This Page