Code:
' PIC16F88
' Basic blinky code provided by Darrel Taylor
' See forum posting here:
' http://www.picbasic.co.uk/forum/showthread.php?t=17299&p=116934#post116934
#DEFINE USE_LCD_FOR_DEBUG ; comment out for non-debug use
DEFINE OSC 20 ; Set oscillator 20Mhz
DEFINE BLINKYFREQ 100 ; 10mS periods
' ***************************************************************
' Device Fuses
' ***************************************************************
' PIC chip data sheets can be found here: C:\Program Files\Microchip\MPASM Suite
#CONFIG
__config _CONFIG1, _FOSC_HS & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _LVP_OFF
#ENDCONFIG
' ***************************************************************
' Initialization
' ***************************************************************
;OSCCON = %01100000 ; 4MHz internal osc (not needed when using ext crystal)
pause 100
ANSEL = 0 ; Digital only
TRISA = 0 ; PORTA all output
TRISB = %00000001 ; Make PORTB pin 0 input for flash mode button
OPTION_REG.6 = 1 ; 1=Rising edge (default) or button "PRESS";
; 0=Falling edge or button "RELEASE"
LEDcount CON 7 ; Number of blinking LEDs on PORTA
;(includes running lights, which are
; defined separately below)
' BL1,BL2,BL3,BL4,BL5,STB
OnTimes DATA 50 ,22 ,38 ,75 ,17 , 2 ; default "on" periods for each output
OffTimes DATA 150 ,45 ,38 ,95 ,22 ,48 ; default "off" periods for each output
; (Strobe flashes 2 times per second
; or every 500ms; subtract "on" time)
FlashMode_Default CON 0
EE_FlashMode DATA FlashMode_Default
FlashMode VAR BYTE
READ EE_FlashMode, FlashMode
;----------------------------------------------------------------
#DEFINE USE_RANDOM_SEQUENCE ; comment for contiuous Sequence
#IFDEF USE_RANDOM_SEQUENCE ; randomization used for BL1-5 only
RND VAR WORD : RND = 13864
MIN_ON CON 15 ; Minimum random ON time
MAX_ON CON 115 ; Maximum random ON time
MIN_OFF CON 15 ; Minimum random OFF time
MAX_OFF CON 200 ; Maximum random OFF time
RandPeriod VAR WORD[LEDcount-3]
RandPeriods DATA WORD 1000, WORD 1250, WORD 1500, WORD 1750, WORD 2000
#ENDIF
CCPR1val CON EXT : @CCPR1val = (OSC*1000000/4)/ BLINKYFREQ
;CCPR1 VAR WORD EXT : @CCPR1 = CCPR1L
;Timer1 VAR WORD EXT : @Timer1 = TMR1L
CCPIF VAR PIR1.2
LoopLED VAR BYTE[LEDcount]
OnTime VAR BYTE[LEDcount]
OffTime VAR BYTE[LEDcount]
x VAR BYTE
Old_FlashMode VAR BYTE
PRI_HULL_LGHTS_ON_MS VAR BYTE
PRI_HULL_LGHTS_OFF_MS VAR BYTE
#IFDEF USE_LCD_FOR_DEBUG
LCD_PIN VAR PORTA.4 ' Alias PORTA.4 as "LCD_PIN"
LCD_INST CON 254 ' instruction
LCD_CLR CON 1 ' Clear screen
LCD_L1 CON 128 ' LCD line 1
LCD_L2 CON 192 ' LCD line 2
LCD_BAUD CON 16780 ' Baud rate/mode for ILM-216 2x16 character display
LCD_PACE CON 1 ' Optional pace value
#ENDIF
' ***************************************************************
' Includes
' ***************************************************************
INCLUDE "DT_INTS-14.bas" ' DT's base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
' --> copy both files to PBP main folder
' (i.e. c:\pbp3)
INCLUDE "SPWM_INT.bas" ; DT's software PWM module
DEFINE SPWM_FREQ 200 ; SPWM Frequency
DEFINE SPWM_RES 256 ; SPWM Resolution
DutyVars VAR BYTE[3] ; DutyCycle Variables
DutyVar1 VAR DutyVars[0] ; group them in an array for easy access
DutyVar2 VAR DutyVars[1] ; with FOR loops etc.
DutyVar3 VAR DutyVars[2]
ASM
SPWM_LIST macro ; Define Pin's to use for SPWM
SPWM_PIN PORTA, 0, _DutyVar1 ; and the associated DutyCycle variables
SPWM_PIN PORTA, 1, _DutyVar2 ; Notice the underscore before variables
SPWM_PIN PORTA, 2, _DutyVar3
endm
SPWM_INIT SPWM_LIST ; Initialize the Pins
ENDASM
DutyVar1 = 7
DutyVar2 = 25
DutyVar3 = 255
;-- Place a copy of these variables in your Main program -------------------
;-- The compiler will tell you which lines to un-comment --
;-- Do Not un-comment these lines --
;---------------------------------------------------------------------------
;wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3
' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using --
;wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
;wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
;wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------
' ***************************************************************
' ASM Interrupt Definitions
' ***************************************************************
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _Flash_Mode_Btn, PBP, yes
INT_Handler TMR1_INT, SPWMhandler, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
' ***************************************************************
;----[Initialize on/off periods & random sequencing (if enabled)]---------------
; (only randomize first 5 blinkies; 6th is strobe which must remaing constant)
; (running lights (7th) are set up separately)
FOR x = 0 to (LEDcount - 2) ; Load the periods from EEPROM
READ OnTimes+x, OnTime(x)
READ OffTimes+x, OffTime(x)
#IFDEF USE_RANDOM_SEQUENCE
IF x < 5 THEN
READ RandPeriods+(x<<1), WORD RandPeriod(x)
ENDIF
#ENDIF
NEXT X
;-- setup CCP1 and Start Timer1 --
CCPR1 = CCPR1val ; set compare value
CCP1CON = %00001011 ; compare mode, special event
Timer1 = 0 ; clear Timer1
T1CON.0 = 1 ; start Timer1
Old_FlashMode = FlashMode ; Set initial value for comparator var
GOSUB SetNavLtsFlashRates ; Set up flash rates based on saved "FlashMode" val
' Enable interrupt
INTCON = %10010000 ; Global int enabled, INTE enabled, IOCI enabled,
; INTF flag bit 0 clr, IOCI flag bit 0 clr
INTCON.1 = 0 ; Clear RB0/INT External Interrupt Flag
@ INT_ENABLE INT_INT ; INT/Ext Interrupt
@ INT_ENABLE TMR1_INT ; enable Timer1 interrupts
#IFDEF USE_LCD_FOR_DEBUG
serout2 LCD_PIN, LCD_BAUD, LCD_PACE, [LCD_INST, LCD_CLR] ; clear screen
pause 5
serout2 LCD_PIN, LCD_BAUD, LCD_PACE, ["FlashMode:", DEC FlashMode, " "]
#ENDIF
;----[Main Program Loop]----------------------------------------
Main:
' Check if flash mode has changed
IF FlashMode <> Old_FlashMode Then
Old_FlashMode = FlashMode
GOSUB SetNavLtsFlashRates
EndIF
x = (x + 1) // LEDcount
PORTB.1(x) = !!(LoopLED(x) < OnTime(x))
LoopLED(x) = (LoopLED(x) + 1) // (OnTime(x) + OffTime(x))
#IFDEF USE_RANDOM_SEQUENCE
IF x < 5 THEN
RandPeriod(x) = RandPeriod(x) - 1
IF RandPeriod(x) = 0 THEN
READ RandPeriods+(x<<1), WORD RandPeriod(x)
RANDOM RND
OnTime(x) = (MAX_ON - MIN_ON)* RND.HighByte / 255 + MIN_ON
OffTime(x)= (MAX_OFF - MIN_OFF)* RND.LowByte / 255 + MIN_OFF
ENDIF
ENDIF
#ENDIF
IF x != (LEDcount - 1) THEN Main
Waiting: IF !CCPIF THEN Waiting
CCPIF = 0
GOTO Main
SetNavLtsFlashRates:
If FlashMode = 0 Then
PRI_HULL_LGHTS_ON_MS = 150
PRI_HULL_LGHTS_OFF_MS = 50
ElseIf FlashMode = 1 Then
PRI_HULL_LGHTS_ON_MS = 50
PRI_HULL_LGHTS_OFF_MS = 150
Else
PRI_HULL_LGHTS_ON_MS = 75
PRI_HULL_LGHTS_OFF_MS = 83
EndIf
OnTime(6) = PRI_HULL_LGHTS_ON_MS
OffTime(6) = PRI_HULL_LGHTS_OFF_MS
#IFDEF USE_LCD_FOR_DEBUG
serout2 LCD_PIN, LCD_BAUD, LCD_PACE, [LCD_INST, LCD_CLR] ; clear screen
pause 5
serout2 LCD_PIN, LCD_BAUD, LCD_PACE, ["FlashMode:", DEC FlashMode, " "]
#ENDIF
RETURN
END
' ***************************************************************
' [INT - interrupt handler]
' ***************************************************************
Flash_Mode_Btn:
' Toggle flash mode between the 3 values (0, 1 or 2)
FlashMode = FlashMode + 1
If FlashMode > 2 Then FlashMode = 0
' Save selected running light flash mode
WRITE EE_FlashMode, FlashMode
PAUSE 100
INTCON.1 = 0 ' Clear RB0/INT External Interrupt Flag
@ INT_RETURN
Bookmarks