• Silly little LED flasher

    I don't know why anyone else might need this, but who knows?

    I needed a warning LED to light up when there was a problem, and I needed to indicate the nature of the problem with the number of flashes. I couldn't just let the program sit around while it flashed, I needed it to run in the background.
    And since people who count flashes expect nice, even-spaced flashes, I couldn't just rely on program loops (at least in my case, where some loops take longer than others).

    So here is the result. I uses Timer 1 to flash a led at a 1 Hz rate. Just give the variable "MakeFlash" a number, and it will flash ON that many times, then hold the LED ON for 5 periods, and start all over again. If you clear MakeFlash, the flashing stops.

    Since it is interrupt-driven, it runs entirely in the background.

    Let us hope it formats better on the forum than it does on my screen.

    Code:
     
    Warn           VAR PORTD.5
    MakeFlash      VAR BYTE
    DoFlash        VAR BYTE
    CounterF       VAR WORD
    T1Counter      VAR BYTE
    FlashFlag      VAR BIT
    WaitCounter    VAR BYTE
    InFlashRoutine VAR BIT
    CR             CON 13
    LF             CON 10
    ONN            CON 1
    OFFF           CON 0
     
    CounterF =0
    T1Counter = 0
    FlashFlag = 0
    WaitCounter = 0
    inFlashRoutine = 0
     
    ;-----------------  ----------------------------
     
        INCLUDE "DT_INTS-18.bas"         ; Base Interrupt System
        INCLUDE "ReEnterPBP-18.bas"     ; Include if using PBP interrupts
     
    ASM
     
    INT_LIST  macro        ; IntSource,    Label,  Type, ResetFlag?
              INT_Handler    TMR1_INT,  _FlashLEDs, PBP,   yes
    endm
    INT_CREATE
     
    ENDASM
     
    '-------------------------------
     
    GOTO OverInt
     
    FlashLEDs:
       PIR1.0 = 0 ; Clear INT flag
       IF !InFlashRoutine THEN
          IF MakeFlash THEN
             DoFlash = MakeFlash + 1    ; Transfer contents to working varible that the INT can change
             InFlashRoutine = 1         ; Let system know that we are actively flashing now.
             ; The MakeFlash "+1" is used if you don't count the HOLD time as a flash
          ELSE
             Warn = OFFF
          ENDIF
       ENDIF
    
       T1Counter = T1Counter + 1      ; Effectively divides interrupt period by 10
       IF T1Counter < 10 THEN GOTO EndRoutine
       T1Counter = 0  ; Clear interrupt counter
       IF DoFlash > 0 THEN         ; Should we still be flashing?
           FlashFlag = 1             ; Set once we enter routine so we know we were previously flashing
           IF Warn = OFFF THEN
               Warn = ONN
               DoFlash = DoFlash - 1  ; Keep track of the times we have flashed
               GOTO EndRoutine
           ELSE
               Warn = OFFF        ; Turn it off
           ENDIF
        ELSE
            IF FlashFlag = 1 THEN     ; When we are done flashing, we need to hold the LED ON for a period
                                      ; so mere mortals can determint the difference
                Warn = ONN
                WaitCounter = WaitCounter + 1
                IF WaitCounter > 5 THEN
                    FlashFlag = 0
                    WaitCounter = 0
                    InFlashRoutine = 0
                ENDIF
            ELSE
                WaitCounter = 0    ; Just to make certain it gets cleared
            ENDIF
        ENDIF
     
    EndRoutine:
    @ INT_ENABLE TMR1_INT
    @ INT_RETURN
     
    ;---------------------------------------------------------
     
    OverInt:
       HSEROUT ["Hello World"]
       TMR1H = 0
       TMR1L = 0
       PIR1.0 = 0
       T1CON = %00110001  ; Turns it on, /8 prescaler, load 8 bits at a time
    @ INT_ENABLE TMR1_INT
       MakeFlash = 5 ;   Just for test
     
    Top:
         PAUSE 20000
         MakeFlash = 0
         GOTO Top
    This article was originally published in forum thread: Silly little LED flasher started by Charles Linquis View original post