PDA

View Full Version : Silly little LED flasher



Charles Linquis
- 2nd September 2011, 06:34
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.




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

Ioannis
- 2nd September 2011, 09:19
Nice job Charles.

Ioannis

lester
- 2nd September 2011, 12:57
Published in the code examples section, thank you for taking time to post this code example.

http://www.picbasic.co.uk/forum/content.php?r=437-Silly-little-LED-flasher