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
Bookmarks