Count down timer with interrupt/jump ?


Results 1 to 4 of 4

Threaded View

  1. #3
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    As I understand it, interrupts only work at the end of a command so if I pause 1sec the interrupt would only execute at the end of the pause ? Same as if I paused 1sec then just read an input pin.
    Yes, but only if you're using ON INTERRUPT, which is really not the way to go for something
    like this application. Assembler interrupts would work, but I think this can be done with a lot
    less hassle.

    Let's get creative on this one, and not use interrupts. We'll just monitor the Timer1 overflow
    flag. With Timer1 running in the background you have a multi-tasking environment that can
    remove a ton of firmware overhead.
    Code:
       DEFINE LOADER_USED 1
       DEFINE OSC 4
       
       ' Define LAB-X1 LCD registers and bits
       DEFINE  LCD_DREG        PORTD
       DEFINE  LCD_DBIT        4
       DEFINE  LCD_RSREG       PORTE
       DEFINE  LCD_RSBIT       0
       DEFINE  LCD_EREG        PORTE
       DEFINE  LCD_EBIT        1
       DEFINE  LCD_COMMANDUS   2000
       DEFINE  LCD_DATAUS      50
       
       SYMBOL PROBE = PORTA.0 ' O-scope probe for timing tests
       SEC_COUNT VAR BYTE     ' seconds counter
       OLD_COUNT VAR BYTE     ' copy of count
       PORT_VAL  VAR BYTE     ' holds value read from input port
       O_FLOWS   VAR BYTE     ' holds the number of timer1 overflows
       
       T1LO CON $B0           ' timer1 reload values
       T1HI CON $3C
       
       PORTB = 0              ' RB3 to RB0 = 0
       TRISB = %11110000      ' RB7 to RB4 = inputs, RB3 to RB0 = outputs
       INTCON  = 0            ' interrupts disabled (we're just watching tmr1 int flag)
       OPTION_REG = 0         ' portb pull-ups on for RB7 to RB4
       T1CON = %00100000      ' 1:4 prescale (4uS per tick), timer1 off
       TMR1H = T1HI           ' $3CB0=15,536. 65,536-15,536 = 50,000
       TMR1L = T1LO           ' 50,000 ticks * 4uS = 0.2 seconds. 1 second / 0.2 = 5
                              ' every 5 timer1 overflows = 1 second
       ADCON1 = 7             ' Set PORTA and PORTE to digital
       LOW PORTE.2            ' LCD R/W line low (W)
       PAUSE 1000             ' Wait for LCD to start up
       LCDOUT $FE,1           ' Clear LCD
       
    Main:
       SEC_COUNT=30           ' load for 30 to 0 countdown
       OLD_COUNT=1            ' mismatch for display (see below)
       O_FLOWS=0              ' clear overflow count
       PIR1.0=0               ' clear timer1 overflow flag
       T1CON.0=1              ' start timer1
        
    Test:
       TOGGLE PROBE           ' 77uS from start to return
    
       ' Note: Timer1 overflows every 0.2 seconds, so we have time to execute
       ' a whopping 200,000 single-cycle instructions before this section is
       ' executed
       IF PIR1.0 THEN           ' if timer1 overflow then
          O_FLOWS=O_FLOWS+1     ' inc oveflow counter
          IF O_FLOWS=5 THEN     ' if 1 second elapsed then
             SEC_COUNT=SEC_COUNT-1 ' decrement seconds count
             O_FLOWS=0          ' reset overflow counter
          ENDIF
          PIR1.0=0              ' clear timer1 overflow flag
          T1CON.0 = 0           ' stop timer1
          TMR1L = TMR1L + T1LO  ' add in low byte
          IF TMR1L < T1LO THEN  TMR1H = TMR1H + 1  ' if low byte overflow, increment high byte
          TMR1H = TMR1H + T1HI  ' add in high byte
          T1CON.0=1             ' re-start timer1
          IF SEC_COUNT=255 THEN
             SEC_COUNT=30       ' reset to 30 after 0-1 underflow
             OLD_COUNT=1        ' make sure new value is displayed
          ENDIF
       ENDIF
       
       ' display is updated only when count has changed, so LCDOUT gets executed
       ' only once each second
       IF SEC_COUNT != OLD_COUNT THEN
          LCDOUT $FE,1,"Count = ",DEC SEC_COUNT
          OLD_COUNT=SEC_COUNT  ' match last displayed count for next pass
       ENDIF
       
       ' portb gets read ~every 77uS
       PORT_VAL = (PORTB >> 4) ' read portb
       IF PORT_VAL !=15 THEN ProcessInput ' do something if switch pressed
       GOTO Test
       
    ProcessInput:
       ' print switch inputs on 2nd line of LCD when RB7, 6, 5 or 4 are at ground
       LCDOUT $FE,$C0,IBIN4 PORT_VAL ' display input values
       GOTO Test
        
       END
    This is pretty heavily commented, but if you have questions, let me know. I didn't have a
    serial LCD handy, but this should be pretty easy to modify for your own hardware.

    Making entry into the time-consuming routines conditional, leaves a ton of time to monitor
    your switch inputs, and it's easy to keep everything up to date without using interrupts.

    So you have a boat-load of time to goof-off doing other stuff between the count,
    display updates, and timer reloads.

    Instead of wasting valuable time with a PAUSE 1000, you're running around the entire loop
    from start to return in around 77uS, and have plenty of time to burn for other stuff.

    If you have an O-scope, try placing the TOGGLE PROBE at different locations to see how fast
    everything happens.
    Last edited by Bruce; - 24th August 2007 at 01:19.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

Similar Threads

  1. Elapsed Timer Demo
    By Darrel Taylor in forum Code Examples
    Replies: 111
    Last Post: - 29th October 2012, 17:39
  2. COUNT is not counting again
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 33
    Last Post: - 19th June 2009, 04:52
  3. Timer interrupt frequency
    By Samoele in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 17th January 2009, 23:49
  4. Alarms with Mel's "Olympic Timer" based timer - how to?
    By flotulopex in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 20th June 2007, 22:09
  5. timer interupt help 16f73
    By EDWARD in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 3rd July 2005, 08:41

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