Difficulty toggling LED with TMR1 overflow interrupt


Closed Thread
Results 1 to 5 of 5
  1. #1
    Join Date
    Jul 2012
    Posts
    7

    Default Difficulty toggling LED with TMR1 overflow interrupt

    Hello all. I cannot persuade TMR1 interrupt to toggle an LED. I tried the "ON INTERRUPT...." method and that works fine, toggling the LED 3 or 4 times a second. But I cannot work out how to do this manually by polling the TMR1IF (PIR1.0) flag. I wonder if anyone has any ideas? I have spend hours reading through threads (including the Olympic Timer example thread) but to no avail. Presumably the solution is simple, but I can't work out what it is.

    Many thanks in advance.

    Jonathan.

    Code:
    define OSC 20
    
    TRISB = %11101111        ' PORTB.4 output
    led var PORTB.4
    led = 0
    
    INTCON = 0
    PIR1 = $00        ' clear interupt flags
    TMR1H = 0
    TMR1L = 0
    T1CON = %00110001 ' TMR1 on, prescaler=1:8, clock=(Fosc/4)
    INTCON = $C0    ' Enable global and peripheral interupts
    PIE1 = $01      ' Enable TMR1 overflow interrupt 
    
    main:
        if PIR1.0 then
            led = not led
            TMR1H = 0        ' reset timer1
            TMR1L = 0
            PIR1 = $00        ' clear interrupt flags
        endif
        goto main   
    end

  2. #2
    Join Date
    Jul 2012
    Posts
    7


    Did you find this post helpful? Yes | No

    Default Re: Difficulty toggling LED with TMR1 overflow interrupt

    After a few more hours of sifting through forums, I found the answer in this very forum, in Bruce's post (#2): http://www.picbasic.co.uk/forum/show...2824#post42824

    If you enable interrupts, then you need an interrupt handler. If you prefer just to monitor the
    timer1 overflow flag, then disable global interrupts.
    I'm not sure why this would be the case, but I'll work it out!

  3. #3
    Join Date
    Jul 2012
    Posts
    7


    Did you find this post helpful? Yes | No

    Default Re: Difficulty toggling LED with TMR1 overflow interrupt - SOLUTION

    For reference, here is the solution. The LED is toggled once every second by monitoring the TMR1 interrupt flag. 16F88.

    Jonathan.

    Code:
    define OSC 20
    
    ' SET UP PORTS
    TRISB = 101111   ' PORTB.4 output
                                                                                                
    ' SET UP TMR1  
    T1CON = 0            ' prescaler=1:1, clock=(Fosc/4)
    PIE1.0 = 1          ' Enable TMR1 overflow interrupt
    INTCON.6 = 0        ' Disable peripheral interrupts
    INTCON.7 = 0        ' Disable global interrupts (disable GIE and PEIE because there
                        ' is no ISR, polling PIR1.0 (TMR1IF) manually instead)  
    
    ' DECLARE VARIABLES
    led var PORTB.4
    overflow_counter var word
    tmr1_preload var word
    
    ' INIT PROGRAMME
    init:
        led = 0
        overflow_counter = 0
        tmr1_preload = 15536    ' 15536 for overflow every 10 ms
                    
        TMR1H = tmr1_preload.highbyte
        TMR1L = tmr1_preload.lowbyte
        T1CON.0 = 1        ' Start TMR1
    
    main:
        if PIR1.0 = 1 then                    ' if TMR1IF is set
            overflow_counter = overflow_counter + 1
            if overflow_counter = 100 then    ' 100 overflows = 1 second
                led = not led               ' toggle led
                overflow_counter = 0        ' reset overflow counter
            endif
            TMR1H = tmr1_preload.highbyte   ' reset TMR1 with preload value
            TMR1L = tmr1_preload.lowbyte
            PIR1.0 = 0                        ' clear TMR1IF
        endif
        goto main   
    end

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,580


    Did you find this post helpful? Yes | No

    Default Re: Difficulty toggling LED with TMR1 overflow interrupt

    If you enable interrupts the code will jump to the interrupt vector whenenver an interrupt occurs. If you don't have a interrupt service routine at that location (or a jump TO an interrupt service routine) it won't work properly. The interrupt flags (like the TMR1IF) will get set whenever the cause of the particular interrupt happens/occurs but an actual jump to the interrupt vector will only occur if interrupts are enabled.

    So, if you're actually going to use interrupts you need them enabled AND have an interrupt service routine. If you're just going to poll the interrupt flag then you can't have that particullar interrupt enabled.

  5. #5
    Join Date
    Jul 2012
    Posts
    7


    Did you find this post helpful? Yes | No

    Default Re: Difficulty toggling LED with TMR1 overflow interrupt

    Thank you for the explanation. Now I understand. From the 16F88 datasheet: "If the global interrupt is enabled, the program will branch to the interrupt vector (0004h)."

Members who have read this thread : 0

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