'**************************************************************** '* Name : Ring Light Controller V2 * '* Author : Georg Kohler * '* Notice : Copyright (c) 2007 Kohler Design Corp * '* : All Rights Reserved * '* Date : 10/25/2007 * '* Version : B (KDC-200/210 > Rev B) * '* Compiler : Proton + Basic V 3.5.7.1 * '* Notes : Ring Light controller V2 * '* : * '* : * '* : * '* : * '* : * '* : * '* : * '* : * '* '* : * '* : '* '* '**************************************************************** Device 16F88 'set config bits /disbale for use with IDC Config WDT_OFF , PWRTE_ON, BODEN_OFF, LVP_OFF , WRT_PROTECT_OFF , CP_OFF , CPD_OFF , DEBUG_OFF ,CCP1_RB3 , MCLR_OFF ,INTRC_IO ,IESO_OFF ,FCMEN_OFF All_Digital = True '4 Mghz 'OSCCON=%01101000' setup PIC For 4Hz 'Xtal = 4 'Proton clock setting (just for calculations) '8 Mhz OSCCON=%01111000 'setup PIC for 8Hz Xtal = 8 'Proton clock setting (just for calculations) '--------------------------------------------- 'Timer0 setup 'DECLARE SYMBOLS Symbol t0if = INTCON.2 'TMR0 Overflow Interrupt Flag Symbol t0ie = INTCON.5 'TMR0 Overflow Interrupt Enable Symbol GIE = INTCON.7 'Global Interrupt Enable Symbol PS0 = OPTION_REG.0 'Prescaler Rate Select Symbol PS1 = OPTION_REG.1 'Prescaler Rate Select Symbol PS2 = OPTION_REG.2 'Prescaler Rate Select Symbol PSA = OPTION_REG.3 'Prescaler Assignment Symbol tocs = OPTION_REG.5 '--------------------------------------------------------- 'Prescale Timer0 PS0 = 1 'prescaler TMR0 setting .... PS1 = 0 'prescaler TMR0 setting .... PS2 = 1 'prescaler TMR0 setting .... PSA = 0 'prescaler TMR0 setting .... 'Inital setup Timer0 tocs = 0 'set the clock source for internal oscillator t0if = 0 'clear the interrupt flag t0ie = 1 'enable tmr0 interrupt GIE = 1 'enable Global interrupts '--------------------------------------------------------- ' test Variables Dim x As Byte Dim TEST_BUTTON_STATE As Byte 'Declare Variables Dim LOOP_UP As Word Dim LOOP_DOWN As Word Dim LOOP_SAVE As Word Dim LOOP_IN_RESET As Word Dim LOOP_IN_EDIT As Word Dim BtnVar_Reset As Byte Dim PWM_MAX As Byte ' max level allowed Dim PWM_MIN As Byte ' min level usable Dim PWM_SUSPEND As Byte 'Suspend Level Dim PWM_SUSPEND_MIN As Byte ' minutes until suspend outputs Dim PWM1_SETPOINT As Word Dim PWM1_ACTIVE As Word Dim ADJUST_STEP As Byte Dim BTN_RESET_LOOPS As Byte Dim BUTTON_DEBOUNCE As Byte ' loops used for debounce Dim UP_STATE As Byte Dim DOWN_STATE As Byte Dim EDIT_STATE As Byte Dim RESET_STATE As Byte Dim SAVE_REQUIRED As Byte ' inidcate the PWM setpoint has changed Dim STARTUP_COUNTER As Byte ' prevents teh svae flag from being set Dim LED_OPTIONS As Byte ' LED setup options (BCD) Dim LED_EDIT As Byte ' LED edit string selected (BCD) Dim Delay_Loop As Byte ' slow down Loop a bit ' suspend LED PWM Dim LOOP_SUSPEND As Dword ' msec Dim SUSPEND_STATE As Bit ' Flag indicating that LEd output should be suspended Dim SUSPEND_MIN As Byte ' counts minutes until to suspend the LED lights Dim tmr0_ms As Dword 'holds TMR0 in mS Dim ttmr0_offset As Dword ' varables for HPWM Dim Frequency As Word 'Dim Scale_Dutycycle As Word ' variables for Eprom reading/ writing Dim Temp_word As Word 'Dim LED2_Saved As Word Dim Option_Index As Word ' selected Function based on Code Switch '------------------------------------------------- 'Declare Symbols Symbol IN_UP = PORTA.2 Symbol IN_DOWN = PORTA.5 Symbol IN_EDIT = PORTA.0 Symbol IN_RESET = PORTA.1 'Symbol PWM_1 = PORTB.3 ' Options switch Inputs Symbol IN_OPTION1 = PORTB.0 Symbol IN_OPTION2 = PORTB.4 Symbol IN_OPTION4 = PORTB.7 ' Edit switch Inputs Symbol IN_EDIT1 = PORTA.0 Symbol IN_EDIT2 = PORTA.7 Symbol IN_EDIT4 = PORTA.6 ' test Leds Symbol BLINK_1 = PORTA.3 Symbol BLINK_2 = PORTA.4 '---------------------------------------------- 'Declare Constants TRISA = %11100111 'Configure pins of PORTA as Inputs TRISB = %10111111 'Configure pins of PORTB as Inputs Declare CCP1_Pin PORTB.3 ' Select HPWM port and bit for CCP1 module. i.e. channel 1 'Declare CCP2_Pin PORTB.6 ' Select HPWM port and bit for CCP2 module. i.e. channel 2 main: 'ini PRG states LOOP_UP = 0 LOOP_DOWN = 0 'loop_EDIT = 0 'loop_RESET = 0 tmr0_ms = 0 ttmr0_offset =60000 ' set to 1min BTN_RESET_LOOPS = 200 BUTTON_DEBOUNCE = 20 SAVE_REQUIRED = 0 STARTUP_COUNTER = 0 Frequency = 20000 'set HPWM 489-32767 Hz (at8Mhz) Delay_Loop =5 SUSPEND_MIN =0 BtnVar_Reset =0 ' Button variable for Reset Input ' adjust PWM ADJUST_STEP = 10 PWM_MAX = 254 PWM_MIN = 10 PWM_SUSPEND = 2 ' PWM level set durings suspend PWM_SUSPEND_MIN = 2 ' minutes until suspend is active SUSPEND_STATE = 0 ' test values BLINK_1 =0 BLINK_2 =0 On Interrupt GoTo my_int 'Enable software interrupts, and point to interrupt handler GoTo MAIN_LOOP 'jump over subs 'Enable Debug Disable 'Disable interrupts in the handler my_int: If t0if = 1 Then 'check for TMR0 Flag ' If tmr0_ms < 100000 Then ' reset before Word overflows ?? ' Inc tmr0_ms ' Else tmr0_ms =0 ' EndIf 't0if = 0 'reset TMR0 interrupt flag 'TMR0 = ttmr0_offset 'preload timer with offset End If Enable 'Enable interrupts after the handler Resume 'Return to main program GET_EDIT: LED_EDIT = %00000000 ' reset the variable to 0 If IN_EDIT1 =1 Then SetBit LED_EDIT,0: Else : ClearBit LED_EDIT,0 : EndIf If IN_EDIT2 =1 Then SetBit LED_EDIT,1: Else : ClearBit LED_EDIT,1 : EndIf If IN_EDIT4 =1 Then SetBit LED_EDIT,2: Else : ClearBit LED_EDIT,2 : EndIf Return GET_OPTIONS: LED_OPTIONS = %00000000 ' reset the variable to 0 If IN_OPTION1 =1 Then SetBit LED_OPTIONS,0 : Else : ClearBit LED_OPTIONS,0 :EndIf If IN_OPTION2 =1 Then SetBit LED_OPTIONS,1 : Else : ClearBit LED_OPTIONS,1 :EndIf If IN_OPTION4 =1 Then SetBit LED_OPTIONS,2 : Else : ClearBit LED_OPTIONS,2 :EndIf Return Write_EPROM: EWrite 00 ,[PWM1_SETPOINT] ' Save PWM 1 to 00 and 01 (word =2 byte ) ' EWrite 02 ,[PWM2_SETPOINT] 'PWM 2 To 02 And 03 (Word =2 Byte ) SAVE_REQUIRED =0 'reset save flag Return START_PWM: PWM1_SETPOINT = ERead 00 ' Read PWM 1 to 00 and 01 (word =2 byte ) PWM1_ACTIVE = PWM1_SETPOINT HPWM 1,PWM1_ACTIVE,Frequency BLINK_2 = 1 DelayMS 3000 BLINK_2 = 0 'PWM2_SETPOINT = Eread 02 ' read PWM 2 to 02 and 03 (word =2 byte ) Return ' Exit the subroutine ' Process Butten UP PROCESS_BTN_UP: If IN_UP = 1 Then Inc LOOP_UP LOOP_SAVE =0 End If If IN_UP = 0 Then LOOP_UP = 0 UP_STATE = 0 End If If UP_STATE = 0 And LOOP_UP >= BUTTON_DEBOUNCE Then UP_STATE = 1 If PWM_MAX - PWM1_SETPOINT > ADJUST_STEP Then PWM1_SETPOINT = PWM1_SETPOINT + ADJUST_STEP Else PWM1_SETPOINT = PWM_MAX EndIf End If If LOOP_UP = BTN_RESET_LOOPS Then PWM1_SETPOINT = PWM_MAX EndIf Return ' ' Process Butten Down PROCESS_BTN_DOWN: If IN_DOWN = 1 Then LOOP_SAVE =0 Inc LOOP_DOWN EndIf If IN_DOWN = 0 Then LOOP_DOWN = 0 DOWN_STATE = 0 End If If DOWN_STATE = 0 And LOOP_DOWN >= BUTTON_DEBOUNCE Then DOWN_STATE = 1 If PWM1_SETPOINT > PWM_MIN+ ADJUST_STEP Then PWM1_SETPOINT = PWM1_SETPOINT - ADJUST_STEP Else PWM1_SETPOINT = PWM_MIN EndIf EndIf If LOOP_DOWN = BTN_RESET_LOOPS Then PWM1_SETPOINT = PWM_MIN End If Return ' Process RESET INPUT PROCESS_IN_RESET: If IN_RESET = 1 Then Inc LOOP_IN_RESET EndIf If IN_RESET = 0 Then LOOP_IN_RESET = 0 RESET_STATE = 0 End If If RESET_STATE = 0 And LOOP_IN_RESET >= BUTTON_DEBOUNCE Then PWM1_ACTIVE = PWM1_SETPOINT HPWM 1,PWM1_ACTIVE,Frequency ' reenable PWM without raising the save flag BLINK_1 =0 BLINK_2 = 0 SUSPEND_MIN = 0 LOOP_SUSPEND =0 SUSPEND_STATE = 0 RESET_STATE = 1 EndIf Return ' //////////////////// TEST PROCEDURES ////////////////////// Blink: BLINK_1 =0 DelayMS 1000 BLINK_1 =1 DelayMS 1000 BLINK_1 =0 DelayMS 1000 BLINK_1 =1 DelayMS 1000 BLINK_1 =0 Return DISPLAY_OPTIONS: GoSub GET_OPTIONS If LED_OPTIONS > 0 Then For x =0 To LED_OPTIONS -1 BLINK_2 =1 DelayMS 300 BLINK_2 =0 DelayMS 300 Next EndIf Return '///////////////////////////////////////////////////////////// ' MAIN '//////////////////////////////////////////////////////////// MAIN_LOOP: ' LED Options: ' 0 = Disable Edit Protection and Reset ' 1 = Enable Reset ' 2 = enable Edit Protection ' 3 = Enable both Edit Protection & Reset ' If PORTA.1 = 1 And TEST_BUTTON_STATE = 0 Then ' GoSub DISPLAY_OPTIONS ' TEST_BUTTON_STATE = 1 ' EndIf ' If PORTA.1 = 0 Then ' TEST_BUTTON_STATE = 0 ' EndIf 'Button PORTA.1, 0, 255, 255, Btnvar_Test, 0, BYPASS_BUTTON ''GoSub DISPLAY_OPTIONS 'Gosub Blink 'BYPASS_BUTTON: If STARTUP_COUNTER = 0 Then GoSub GET_OPTIONS ' get option switch GoSub START_PWM ' Read saved values & start PWM with read values 'GoSub DISPLAY_OPTIONS ' Test Blinking STARTUP_COUNTER =1 EndIf GoSub PROCESS_BTN_UP GoSub PROCESS_BTN_DOWN ' ' LED option RESET If LED_OPTIONS = 1 Or LED_OPTIONS = 3 Then GoSub PROCESS_IN_RESET If SUSPEND_STATE = 0 Then If LOOP_SUSPEND * Delay_Loop < 10000 Then ' 1 Min ?? Inc LOOP_SUSPEND Else SUSPEND_MIN = SUSPEND_MIN + 1 LOOP_SUSPEND =0 'GoSub Blink EndIf If SUSPEND_MIN = PWM_SUSPEND_MIN Then PWM1_ACTIVE = PWM_SUSPEND HPWM 1,PWM_SUSPEND,Frequency SUSPEND_STATE = 1 BLINK_1 = 1 'Turn on BLINK_2 = 1 'Turn on EndIf EndIf EndIf 'Adjust PWM If PWM1_ACTIVE <> PWM1_SETPOINT And SUSPEND_STATE = 0 Then PWM1_ACTIVE = PWM1_SETPOINT HPWM 1,PWM1_ACTIVE,Frequency SAVE_REQUIRED = 1 BLINK_2 =0 'turn Test Blink LED OFF 'GoSub Blink EndIf If SAVE_REQUIRED = 1 Then Inc LOOP_SAVE EndIf If LOOP_SAVE = 3000 Then GoSub Write_EPROM BLINK_2 =1 'turn Test Blink LED ON EndIf DelayMS Delay_Loop ' slow down a bit GoTo MAIN_LOOP