Code:
@ __config _INTOSCIO & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BOD_OFF & _IESO_OFF & _FCMEN_OFF & _CP_OFF & _CPD_OFF
'-------
CLEAR 'Clear all ram registers
'MCU CLOCK SOURCE
OSCCON.0 = 0 'int osc is used for sys clock (SCS bit)
OSCCON.6 = 0 'int osc freq 32kHz (IRCF bits)
OSCCON.5 = 0
OSCCON.4 = 0
'PORTS CONFIG
ANSEL=0 'Analog to Digital converter disabled
TRISA = %10000000 'PORTA.7 (T1OSI=XTAL) to inputs
TRISB = %00000001 'PORTB.0 (=external interrupts) to input
TRISC = %00000111 'PORTC.2 to 0 (=1/3 BIAS for LCD) to inputs
''Timer1 CONFIGURATION (part of)
T1CON.1 = 1 'clock for Timer1 is ext (TMR1CS bit)
T1CON.2 = 1 'do not sync with the int clock (T1SYNC bit)
T1CON.3 = 1 'LP oscillator is enabled for Timer1 clock (when INTOSC without CLKO is active) (T1OSCEN bit)
'LCD CONFIGURATION
LCDCON.4 = 1 'enable bias voltage pins (VLCDEN bit)
LCDCON.3 = 1 'clock source LFINTOSC (31kHz/32) (CS bits)
'LCDCON.2 = ?
LCDCON.0 = 1 '1/4 multiplex (all COM used) (LMUX bits)
LCDCON.1 = 1
LCDPS.7 = 0 'waveform type-A (WFT bit)
LCDPS.6 = 0 'bias mode (when LMUX=11) (BIASMD bit)
LCDPS.3 = 0 '1:16 prescaler (31kHz/32/8=121Hz) (LP bits)
LCDPS.2 = 1
LCDPS.1 = 1
LCDPS.0 = 1
LCDSE0.3 = 1 'enable SEG3,4,5,6,8,9 (SE bits)
LCDSE0.4 = 1
LCDSE0.5 = 1
LCDSE0.6 = 1
LCDSE1.0 = 1
LCDSE1.1 = 1
'Clear??? LCDDATA registers see AN1070
LCDCON.6 = 0 'enable the LCD in SLEEP mode (SLPEN bit)
'PIR2.4 = 0 '(why ???) clear LCD Interrupt Flag (LCDIF bit)
'VARIABILES
adr4tmr1LO VAR BYTE 'RAM adr for startup timer1_LOW _BYTE value
adr4tmr1HI VAR BYTE 'for timer1_HIGH _BYTE value
T1 VAR WORD 'temp var for TMR1 startup value
nc var word
nc0 var word 'number of cigarettes (index) at address 0+1
nc2 var word 'at adr 2+3
nc4 var word 'at adr 4+5
LCD VAR WORD 'number on LCD
hundreds VAR BYTE 'temporary LCD var
tens var byte 'temp LCD var
ones var byte 'temp LCD var
'-----
INCLUDE "DT_INTS-14.bas"
INCLUDE "ReEnterPBP.bas"
ASM
INT_LIST macro
INT_Handler INT_INT, _open_battery_cover, PBP, yes
endm
INT_CREATE
INT_ENABLE INT_INT
ENDASM
'WRITE TO EEPROM the startup timer1 values DIVIDED by 4 to fit into the 14 bytes (Timer1_startup_value/4)
DATA @48,WORD 12773,WORD 12927,WORD 13080,WORD 13234,WORD 13388,WORD 13541,WORD 13695,WORD 13848
'...not completed...more then 10k characters to upload
'LATCH THE BOX
lock_the_box:
PORTB.1 = 1 'armature out
PAUSE 1
PORTB.1 = 0
'GET THE CIGARETTE INDEX
Interval_Tigari:
READ 0, NC0.LowByte 'read the last cigarette index from EEPROM_location 1
READ 1, NC0.HighByte 'from EEPROM_location 1
READ 2, NC2.LowByte 'from EEPROM_location 2
READ 3, NC2.HighByte 'from EEPROM_location 2
READ 4, NC4.LowByte 'from EEPROM_location 3
READ 5, NC4.HighByte 'from EEPROM_location 3
'IF power down at writing between (nc0.LowByte and nc0.HighByte) or (nc0 and nc2)
if nc4-nc2=0 then
IF nc2-nc0<>0 THEN
nc=nc2+1
goto next_cigarette
ENDIF
endif
'IF power down at writing between (nc2.LowByte and nc2.HighByte)
if nc4-nc2<>0 THEN
IF nc2-nc0<>0 then
nc=nc4+1
goto next_cigarette
ENDIF
endif
'IF power down (or not) at writing anywere else
nc=nc0
'-------
next_cigarette:
if nc = 16383 then 'EEPROM is just 14 bytes
goto get_adr4tmr1
endif
NC = NC+1 'next cigarette
'GET START RAM ADDRESS RANGE FOR TIMER1 STARTUP VALUE BY CIGARETTE INDEX
get_adr4tmr1:
SELECT CASE nc
Case Is < 141 '1st week
adr4tmr1lo=48
Case Is < 255 '2nd week
adr4tmr1lo=64
Case Is < 349 '3rd week
adr4tmr1lo=80
Case Is < 430 '4th week
adr4tmr1lo=96
Case Is < 500 '5th week
adr4tmr1lo=112
Case Is < 563 '6th week
adr4tmr1lo=128
Case Is < 619 '7th week
adr4tmr1lo=144
Case Is < 670 '8th week
adr4tmr1lo=160
Case Is < 717 '9th week
adr4tmr1lo=176
Case Is < 760 '10th week
adr4tmr1lo=192
Case Is < 800 '11th week
adr4tmr1lo=208
Case Is < 837 '12th week
adr4tmr1lo=224
Case Is >=837 '13th week and more
adr4tmr1lo=240
END SELECT
'COUNTDOWN LCD
Countdown:
LCDCON.7 = 1 'enable the LCD module (LCDEN bit)
for hundreds = 9 to 0 step -1
LOOKUP hundreds,[1,0,1,1,0,1,1,1,1,1],LCDDATA10.1
'hundreds seg A (0 to 9)
'...not completed...more then 10k characters to upload
for tens = 9 to 0 step -1
LOOKUP TENS,[1,0,1,1,0,1,1,1,1,1],LCDDATA9.3
'tens seg A (0 to 9)
'...not completed...more then 10k characters to upload
for ones = 9 to 0 step -1
LOOKUP ones,[1,0,1,1,0,1,1,1,1,1],LCDDATA9.5 'ones seg A (0 to 9)
'...not completed...more then 10k characters to upload
LCD=hundreds*100+TENS*10+ONES
'>>>>>>>
'GET START RAM ADDRESS FOR TIMER1 STARTUP VALUE BY LCD VALUE
IF LCD<=999 THEN
IF LCD>=875 THEN
goto Start_Timer1_interrupt
ENDIF
ENDIF
IF LCD<=874 THEN
IF LCD>=750 THEN
adr4tmr1lo = adr4tmr1lo+2
goto Start_Timer1_interrupt
ENDIF
ENDIF
IF LCD<=749 THEN
IF LCD>=625 THEN
adr4tmr1lo = adr4tmr1lo+4
goto Start_Timer1_interrupt
ENDIF
ENDIF
IF LCD<=624 THEN
IF LCD>=500 THEN
adr4tmr1lo = adr4tmr1lo+6
goto Start_Timer1_interrupt
ENDIF
ENDIF
IF LCD<=499 THEN
IF LCD>=375 THEN
adr4tmr1lo = adr4tmr1lo+8
goto Start_Timer1_interrupt
ENDIF
ENDIF
IF LCD<=374 THEN
IF LCD>=250 THEN
adr4tmr1lo = adr4tmr1lo+10
goto Start_Timer1_interrupt
ENDIF
ENDIF
IF LCD<=249 THEN
IF LCD>=125 THEN
adr4tmr1lo = adr4tmr1lo+12
goto Start_Timer1_interrupt
ENDIF
ENDIF
IF LCD<=124 THEN
adr4tmr1lo = adr4tmr1lo+14
ENDIF
'>>>>>>>
Start_Timer1_Interrupt:
READ adr4tmr1lo,T1.LowByte 'Timer1_startup_value/4
adr4tmr1HI=adr4tmr1lo+1
READ adr4tmr1HI,T1.HighByte
T1 = T1*4 'Timer1 REAL startup value
TMR1H = T1.HighByte
TMR1L = T1.LowByte
T1CON.0 = 1 'enable Timer1 (TMR1ON bit)
T1CON.5 = 1 'Timer1 input clock prescale (1:8) (T1CKPS bits)
T1CON.4 = 1
T1CON.6 = 1 'enable Timer1 Gate (T1GE bit)
T1CON.7 = 0 'Timer1 Gate is not inverted (T1GWN bit)
PIE1.0 = 1 'enable overflow int (TMR1IE bit)
INTCON.6 = 1 'enable all unmasked peripheral int (PEIE bit)
INTCON.7 = 1 'enable global int (GIE bit)
@ sleep
@ nop
@ nop
PIR1.0 = 0 'clear Timer1 int flag (TMR1IF bit)
PIE1.0 = 0 'disable overflow int (TMR1IE bit)
T1CON.0 = 0 'disable Timer1 (TMR1ON bit)
next ones
next tens
next hundreds
'UNLOCK THE BOX
unlock_the_box:
WHILE PORTB.0 = 1
'write to lcd OCE "open cover error"
WEND
PORTA.0 = 1 'armature in
PAUSE 1
PORTA.0 = 0
'write the same "nc" value at three locations to fix the power down issue at the writing time
WRITE 1, NC.HighByte 'write to RAM the "nc" LOW BYTE
WRITE 0, NC.LowByte 'the "nc" HIGH BYTE
WRITE 3, NC.HighByte
WRITE 2, NC.LowByte
WRITE 5, NC.HighByte
WRITE 4, NC.LowByte
'turn off the LCD
LCDCON.4 = 0 'disable bias voltage pins (VLCDEN bit)
LCDCON.6 = 1 'disable the LCD in SLEEP mode (SLPEN bit)
LCDCON.7 = 0 'disable the LCD module (LCDEN bit)
END 'wait for MCLR reset
'INTERRUPT WHEN THE BATTERY COVER IS OPEN
open_battery_cover:
PORTB.1 = 1 'armature out
PAUSE 1
PORTB.1 = 0
@ INT_RETURN
Bookmarks