• PicŪ Basic


  • Interrupt Driven clock Timer 1

    In response to a question on the forum I wrote this little snippet of code to make a timer. At its core is an interrupt running at 100hz off of TMR1. In the interrupt routine is a series of incrementing counters and If THEN statements. As each counter rolls past its set point the IF THEN statement resets the counter and increments the next, Note it is written entirely in BASIC! Lastly we display the result on an lcd.

    Points to note are the interrupt is turned off before making a copy of all the timer vars, before enabling interrupts again. Play with FUDGE_FACTOR to get the timing right.

    Example Code

    '-----------------------------------------------
    ' DEMONSTARTION OF A 100THS OF A SECOND TIMER
    ' COUNTING UP TO 255 DAYS
    '
    '
    ' FIDDLE WITH FUDGE FACTOR TO IMPROVE ACCURACY
    '
    ' BY TIM BOX NOV 03
    '-----------------------------------------------

    Include "PROTON_4.INC"

    DIM _100THS ' DECLARE ALL VARS AS BYTES
    DIM SECS
    DIM MINS
    DIM HOURS
    DIM DAYS
    DIM TEMP_100THS
    DIM TEMP_SECS
    DIM TEMP_MINS
    DIM TEMP_HOURS
    DIM TEMP_DAYS

    DIM GIE AS INTCON.7 ' ALIAS

    DIM TIMER1REG AS TMR1L.WORD ' MAKE THE TIMER VAR INTO A WORD
    SYMBOL FUDGE_FACTOR = 7 ' FIDDLE WITH TO IMPROVE ACCURACY
    SYMBOL TMR1_VAL =((65536)-(XTAL*2500))+FUDGE_FACTOR ' CALCULATE OSC OFFSET VALUES FOR 100HZ INTERRUPT

    ON_INTERRUPT INTERRUPT_ROUTINE ' WHERE TO GO ON AN INTERRUPT


    GOTO START ' JUMP THE INTERRUPT CODE

    INTERRUPT_ROUTINE:

    CLEAR T1CON.0 ' STOP TMR1
    TIMER1REG = TIMER1REG + TMR1_VAL ' LOAD TMR1
    SET T1CON.0 ' START TMR1

    INC _100THS
    IF _100THS = 100 THEN ' UP 100TS
    CLEAR _100THS
    INC SECS ' UP SECONDS
    IF SECS = 60 THEN
    CLEAR SECS
    INC MINS ' UP MINS
    IF MINS = 60 THEN
    CLEAR MINS
    INC HOURS
    IF HOURS = 24 THEN ' UP HOURS
    CLEAR HOURS
    INC DAYS
    ENDIF
    ENDIF
    ENDIF
    ENDIF
    CLEAR PIR1.0 ' CLEAR TMR1 INTERRUPT FLAG
    CONTEXT RESTORE ' END INTERRUPT ROUTINE

    START:
    CLEAR ' CLEAR ALL VARS
    T1CON = %00000000 ' SET UP TMR1 TO HAVE 1:1 PRESCALER AND ACT AS A TIMER
    PIR1.0 = 0 ' CLEAR TMR1 INTERRUPT FLAG
    INTCON = %11000000 ' GLOBAL AND PERIPHERAL INTERRUPTS ON
    PIE1.0 = 1 ' ENABLE TMR1 AS PERIPHERAL INTERRUPT SOURCE
    T1CON.0 = 1 ' SET TIMER1 RUNNING

    CLS ' CLEAR THE LCD

    WHILE 1 = 1 ' MAKE AN ENDLESS LOOP
    GIE = 0 ' TURN OFF GLOBAL INTERRUPTS
    WHILE GIE = 1 : GIE = 0 : WEND ' AND MAKE SURE THEY ARE OFF
    TEMP_100THS = _100THS ' MAKE A COPY OF THE VARS
    TEMP_SECS = SECS
    TEMP_MINS = MINS
    TEMP_HOURS = HOURS
    TEMP_DAYS = DAYS
    GIE = 1 ' TURN THE INTERRUPTS BACK ON

    PRINT AT 1,1,DEC2 TEMP_DAYS,":",DEC2 TEMP_HOURS,":",DEC2 TEMP_MINS,":",DEC2 TEMP_SECS,":",DEC2 TEMP_100THS

    DELAYMS 100 ' SMALL DELAU

    WEND ' ROUND AND ROUND WE GO

    STOP
    contributed by Timothy Box
  • Recent Activity

    xldaedalus-432

    Mysterious PORTB problem

    Thread Starter: xldaedalus

    I'm using Proton+ to develop firmware for a product with switches. The MCU is an 18F26K22. Most of the switches reside on PORTB. I am NOT using a...

    xldaedalus Today, 03:21 Go to last post
    tumbleweed-20435

    PIC18F1330 PLL problem

    Thread Starter: rcurl

    I'm just starting out on a new project that uses a PIC18F1330. I haven't used this specific chip before, so I began by trying to blink an LED just...

    tumbleweed Today, 11:13 Go to last post
    See_Mos-247

    Pic16f18877 oread

    Thread Starter: evoortman

    Hi, On a PIC16F18877 the OREAD command doesn't seem to work. The code is working on a PIC16F1939. Both controllers use 32MHz int osc. If i...

    See_Mos Today, 11:19 Go to last post
    towlerg-21522

    Lin bus and auto baud detection

    Thread Starter: Tim

    Lin bus looks to be a great system for an application i'm working on. One of the main things is the slave can be really simple without needing a...

    towlerg Yesterday, 15:13 Go to last post