'**************************************************************** '* Name : UNTITLED.BAS * '* Author : [select VIEW...EDITOR OPTIONS] * '* Notice : Copyright (c) 2013 [select VIEW...EDITOR OPTIONS] * '* : All Rights Reserved * '* Date : 2/10/2013 * '* Version : 1.0 * '* Notes : * '* : * '**************************************************************** ; Board Setup File for PCB-6.3 ; PIC 18F86K22 ; CONFIGURATION BITS - ONLY CHANGES FROM DEFAULTS ARE DESCRIBED ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #CONFIG CONFIG FOSC = HS2, FCMEN = OFF, IESO = OFF CONFIG PWRTEN = ON, BOREN = SBORDIS, BORV = 0, BORPWR = HIGH CONFIG WDTEN = SWDTDIS, WDTPS = 256 CONFIG XINST = OFF CONFIG CP0 = ON, CP1 = ON, CP2 = ON, CP3 = ON CONFIG CPB = ON CONFIG WRT0 = ON, WRT1 = ON, WRT2 = ON, WRT3 = ON CONFIG CCP2MX = PORTBE #ENDCONFIG ; MISC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DEFINE OSC 20 ; oscillator frequency 20MHz DEFINE INTHAND INTVECT ; label for interrupt vector MEMCON.7 = 1 ; disable external memory ; PORT PIN DIRECTION AND INITIALIZATION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TRISA = %11111111 ; A0: analog in 0 (J2: Scaled Current) LATA = %00000000 ; A1: analog in 1 (J3: Compressor Temperature) ; A2: analog in 2 (J2: Scaled Voltage) ; A3: analog in 3 reference (5.00V 1%) ; A4: digital in (Tilt Sensor) ; A5: analog in 4 (spare, not used) ; A6: oscillator (CLKO) ; A7: oscillator (CLKI) TRISB = %00000101 ; B0: digital in (J2: DC-DC fault) LATB = %00011000 ; B1: digital out (J2: Reverse Condenser Fan) ; B2: digital in (J2: External Load Fault) ; B3: digital out (J3: Red LED) ; B4: digital out (J3: Green LED) ; B5: digital out (Buzzer) ; B6: program (PGC) ; B7: program (PGD) TRISC = %10000011 ; C0: digital in (J5: Compressor Fault) LATC = %00000000 ; C1: digital in (J5: Compressor Tachometer, Pulse Ch2) ; C2: digital out (J5: Compressor Speed Control, PWM Ch1) ; C3: digital I/O (not used) ; C4: digital I/O (not used) ; C5: digital I/O (not used) ; C6: digital out (J5: Data Serial Port Tx Ch1) ; C7: digital in (J5: Compressor Serial Port Rx Ch1) TRISD = %00101000 ; D0: digital I/O (not used) LATD = %10000000 ; D1: digital I/O (not used) ; D2: digital I/O (not used) ; D3: digital in (J6: Compressor Fault) ; D4: digital out (SPI2 Data Out) ; D5: digital in (SPI2 Data In) ; D6: digital out (SPI2 Clock) ; D7: digital out (EEPROM (U2) Chip Select) TRISE = %11100111 ; E0: digital in (J6-J7: Storm Button 1) LATE = %00000000 ; E1: digital in (J6-J7: Storm Button 2) ; E2: digital in (J6-J7: Storm Button 3) ; E3: digital I/O (not used) ; E4: digital out (J3: Short Control) ; E5: digital in (J3: DC Sense) ; E6: digital in (J3 On Sense) ; E7: digital in (J6: Compressor Tach) TRISF = %11111111 ; F0: not connected LATF = %00000000 ; F1: analog in 6 (J3: Ambient Air Temperature) ; F2: analog in 7 (J4: Liquid Line Temperature) ; F3: analog in 8 (J4: Suction Line Temperature) ; F4: analog in 9 (J4: Liquid Line Temperature) ; F5: analog in 10 (J4: High Side Pressure) ; F6: analog in 11 (J3: Clamped Voltage) ; F7: analog in 5 (J3: Evaporator Pressure) TRISG = %100100 ; G0: digital out (J6-J7: Display Backlight, PWM Ch3) LATG = %000000 ; G1: digital out (J7: External Display Serial Port Tx Ch2) ; G2: digital in (J7: External Display Serial Port Rx Ch2) ; G3: digital I/O (not used) ; G4: digital I/O (not used) ; G5: MCLR TRISH = %11110001 ; H0: digital In (J3: 120V Sense) LATH = %00000010 ; H1: digital out (DAC (U1) Chip Select) ; H2: digital I/O (not used) ; H3: digital I/O (not used) ; H4: analog in 12 (J3: DC-DC Current) ; H5: analog in 13 (J3: Compressor Current) ; H6: analog in 14 (J3: PV Voltage) ; H7: analog in 15 (J3: Short Current) TRISJ = %00000000 ; J0: digital out (J6: Internal Display Data0) LATJ = %00000000 ; J1: digital out (J6: Internal Display Data1) ; J2: digital out (J6: Internal Display Data2) ; J3: digital out (J6: Internal Display Data3) ; J4: digital out (J6: Internal Display RS) ; J5: digital out (J6: Internal Display R/W) ; J6: digital out (J6: Internal Display E) ; J7: digital I/O (not used) ; HARDWARE INITIALIZATION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pause 100 ;LCD DEFINE LCD_DATAUS 140 ; LCD Data delay, adjust if LCD is erratic DEFINE LCD_COMMANDUS 6000 ; LCD Command delay, adjust if LCD is erratic DEFINE LCD_LINES 4 ; 4 lines in LCD display DEFINE LCD_DREG PORTJ ; LCD data is on PortJ DEFINE LCD_DBIT 0 ; First LCD data bit is on RJ0 DEFINE LCD_RSREG PORTJ ; LCD RS signal is on PortJ DEFINE LCD_RSBIT 4 ; LCD RS signal is on RJ4 DEFINE LCD_EREG PORTJ ; LCD E signal is on PortJ DEFINE LCD_EBIT 6 ; LCD E signal is on RJ6 DEFINE LCD_RWREG PORTJ ; LCD R/W signal is on PortJ DEFINE LCD_RWBIT 5 ; LCD R/W signal is on RJ5 define LCD_BITS 4 ; LCD bus size is 4 bits ; HARDWARE DATA SERIAL PORT1 DEFINE HSER_RCSTA 90h ; receiver DEFINE HSER_TXSTA 24h ; transmitter DEFINE HSER_BAUD 9600 ; baud rate ; HARDWARE LCD SERIAL PORT2 DEFINE HSER2_RCSTA 90h ; receiver DEFINE HSER2_TXSTA 24h ; transmitter DEFINE HSER2_BAUD 19200 ; baud rate ; ANALOG IN DEFINE ADC_BITS 12 ; 12 bit resolution DEFINE ADC_SAMPLEUS 10 ; time between channel selection and conversion start ANCON0 = %11111111 ; first 16 analog channels enabled ANCON1 = %11111111 ANCON2 = 0 ADCON0 = %00000001 ; -------1 enable ADC ADCON1 = %00010000 ; ---1---- ref+ = AN3 ; ----0--- ref- = VSS ; -----000 single ended ADCON2 = %10001010 ; 1------- right justified ; --001--- acquisition time 2 TAD = 3.2uS ; -----010 clock = FOSC/32 = 1.6uS CM1CON = %00000000 ; disable comparator CM2CON = %00000000 ; disable comparator CM2CON = %00000000 ; disable comparator CVRCON = %00000000 ; disable comparator reference ADCON0 = %00000011 ; start first conversion ; SPI SSP2STAT = %00000000 ; 0------- sample middle ; -0------ transmit on transition from idle to active clock state SSP2CON1 = %00100010 ; --1----- enable SPI port ; ---0---- idle state for clock is low ; ----0010 master mode, clock = Fosc/64 = 312KHz SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) ; Initialize DAC to WTM Mode ; DAC/SPI Variables AOValue VAR Word bank0 ; analog output value in counts (0- 1023) AOCh VAR byte bank0 ; analog output channel (0 - 5) SPIData VAR byte bank0 ; command data byte SPIDummy var byte bank0 ; dummy variable SPIData = SSP2BUF ; read buffer to allow transmission SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) LATH.1 = 0 ; enable (clear) chip select ; Build First Data Byte SPIData = %10010000 ; set WTM code (update immediately) ; Send First Data Byte PIR2.5 = 0 SSP2BUF = SPIData ; byte sent While (PIR2.5 = 0) ; wait for end of transmission Wend PIR2.5 = 0 pauseus 10 ; Build Second Data Byte SPIData = SSP2BUF ; read buffer to allow transmission SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) SPIData = 0 ; Send Second Data Byte SSP2BUF = SPIData While (PIR2.5 = 0) ; wait for end of transmission Wend PIR2.5 = 0 LATH.1 = 1 ; set (disable) chip select ; SETUP INTERRUPT VARIABLES FOR TIMERS AND SOFTWARE PWM, INITIALIZE INTERRUPT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Setup TIMER Variables TimAmS VAR WORD bank0 ; mS timer TimADumS VAR WORD bank0 ; timer dummy counter, (counts 1 second) TimAS VAR WORD bank0 ; second timer TimAM VAR WORD bank0 ; minute timer TimBmS VAR WORD bank0 ; mS timer TimBDumS VAR WORD bank0 ; timer dummy counter, (counts 1 second) TimBS VAR WORD bank0 ; second timer TimBM VAR WORD bank0 ; minute timer TimCmS VAR WORD bank0 ; mS timer TimCDumS VAR WORD bank0 ; timer dummy counter, (counts 1 second) TimCS VAR WORD bank0 ; second timer TimCM VAR WORD bank0 ; minute timer TimDmS VAR WORD bank0 ; mS timer TimDDumS VAR WORD bank0 ; timer dummy counter, (counts 1 second) TimDS VAR WORD bank0 ; second timer TimDM VAR WORD bank0 ; minute timer TimEmS VAR WORD bank0 ; mS timer TimEDumS VAR WORD bank0 ; timer dummy counter, (counts 1 second) TimES VAR WORD bank0 ; second timer TimEM VAR WORD bank0 ; minute timer TimFmS VAR WORD bank0 ; mS timer TimFDumS VAR WORD bank0 ; timer dummy counter, (counts 1 second) TimFS VAR WORD bank0 ; second timer TimFM VAR WORD bank0 ; minute timer ResetA VAR BYTE bank0 ; reset timer flag A ResetB VAR BYTE bank0 ; reset timer flag B ResetC VAR BYTE bank0 ; reset timer flag C ResetD VAR BYTE bank0 ; reset timer flag D ResetE VAR BYTE bank0 ; reset timer flag E ResetF VAR BYTE bank0 ; reset timer flag F fReadTach var byte bank0 ; reading tach flag (don't update) TachTime var word bank0 ; timer for tach LastCap var word bank0 ; last capture values for tach TempCap var word bank0 NoTachCount var byte bank0 ; number of ms with no tach LastCap = 0 NoTachCount = 0 ; Setup Interrupt Saved State Variables psave VAR BYTE bank0 system fsr0Lsave var byte bank0 system fsr0Hsave var byte bank0 system fsr1Lsave var byte bank0 system fsr1Hsave var byte bank0 system fsr2Lsave var byte bank0 system fsr2Hsave var byte bank0 system prodLsave var byte bank0 system prodHsave var byte bank0 system ; Initialize Tach Capture CCP2CON = %00000111 ; capture mode, prescale 16 T1CON = %00111001 CCPTMRS0 = %00000000 ; Set timer 1 to capture CCP2 ; Initialize Interrupt T0CON = %11000100 ; 1------- enable Timer0 ; -1------ 8 bit ; --0----- clock source is internal instruction cycle ; ---0---- increment on low to high transition of clock ; ----0--- timer prescale active ; -----100 timer prescale = 32 TMR0L = 100 ; reset timer for 1mS interrupt INTCON.2 = 0 ; clr TMR0 int flag (TOIF) INTCON.5 = 1 ; enable TMR0 interrupt (T0IE) PIR3.2 = 0 ; clr CCP2 interrupt (tach) PIE3.2 = 0 ; enable CCP2 interrupt (tach) INTCON.6 = 0 ; enable peripheral interrupt RCON.7 = 0 ; disable priority interrupts ;INTCON.7 = 1 ; enable interrupts GoTo MAIN_PROGRAM ; INTERRUPT ROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Asm INTVECT movlb 0x00 movf PCLATH,W,ACCESS movwf psave movf FSR0L,W,ACCESS movwf fsr0Lsave movf FSR0H,W,ACCESS movwf fsr0Hsave movf FSR1L,W,ACCESS movwf fsr1Lsave movf FSR1H,W,ACCESS movwf fsr1Hsave movf FSR2L,W,ACCESS movwf fsr2Lsave movf FSR2H,W,ACCESS movwf fsr2Hsave movf PRODL,W,ACCESS movwf prodLsave movf PRODH,W,ACCESS movwf prodHsave ; Determine interrupt btfsc PIR3,CCP2IF,0 ; chk if capture interrupt goto CAPINT goto DO_TIMER ; Service Tach Capture CAPINT bcf PIR3,CCP2IF,0 ; clr interrupt flag clrf _NoTachCount ; clr no count flag movff CCPR2L,_TempCap ; save capture values movff CCPR2H,_TempCap+1 movf _fReadTach,W ; chk if ok to update btfss STATUS,Z ; clr = not zero = not safe to update goto CAPRESET movf _LastCap,W ; subtract old from new subwf _TempCap,W movwf _TachTime movf _LastCap+1,W subwfb _TempCap+1,W movwf _TachTime+1 CAPRESET movff CCPR2L,_LastCap movff CCPR2H,_LastCap+1 goto ENDINT ; Service 1mS Timer DO_TIMER bcf INTCON,T0IF movlw 0x63 ; reset timer, account for latency by 1 less count movwf TMR0L ; Service Analog Input goto DO_AI ; Check if Need to Reset Timer A DO_TIMER1 incf _NoTachCount,F movlw 0x50 ; load 80 ms number subwf _NoTachCount,W btfss STATUS,C,0 ; clr = negative = tach OK goto DO_TIMER2 clrf _TachTime clrf _TachTime+1 DO_TIMER2 movf _ResetA,W btfss STATUS,Z ; clr = flag set = reset timer goto DORESETA ; Service mS Timer A incf _TimAmS,F ; inc mS timer btfsc STATUS,Z incf _TimAmS+1,F ; Service Minute Timer A movlw 0xEA ; chk if over 60000 (60 seconds) xorwf _TimAmS+1,W ; chk hi byte btfss STATUS,Z ; clr = not zero = not there yet goto DOTIMAS movlw 0x60 ; chk lo byte subwf _TimAmS,W btfss STATUS,C ; clr = neg = time is not up goto DOTIMAS incf _TimAM ; inc minute timer btfsc STATUS,Z incf _TimAM clrf _TimAmS ; clr mS timer at 60000 clrf _TimAmS+1 ; Service Second Timer A DOTIMAS incf _TimADumS,F ; inc dummy second counter btfsc STATUS,Z incf _TimADumS+1,F movlw 0x03 ; chk if over 1000 (1 second) xorwf _TimADumS+1,W ; chk hi byte btfss STATUS,Z ; clr = not zero = not there yet goto DOB movlw 0xE8 ; chk lo byte subwf _TimADumS,W btfss STATUS,C ; clr = neg = time is not up goto DOB incf _TimAS,F ; inc second timer btfsc STATUS,Z incf _TimAS+1,F clrf _TimADumS ; clr Dummy counter at 1000 clrf _TimADumS+1 goto DOB ; Reset Timer A DORESETA clrf _TimAmS clrf _TimAmS+1 clrf _TimADumS clrf _TimADumS+1 clrf _TimAS clrf _TimAS+1 clrf _TimAM clrf _TimAM+1 clrf _ResetA ; Check if Need to Reset Timer B DOB movf _ResetB,W btfss STATUS,Z ; clr = flag set = reset timer goto DORESETB ; Service mS Timer B incf _TimBmS,F ; inc mS timer btfsc STATUS,Z incf _TimBmS+1,F ; Service Minute Timer B movlw 0xEA ; chk if over 60000 (60 seconds) xorwf _TimBmS+1,W ; chk hi byte btfss STATUS,Z ; clr = not zero = not there yet goto DOTIMBS movlw 0x60 ; chk lo byte subwf _TimBmS,W btfss STATUS,C ; clr = neg = time is not up goto DOTIMBS incf _TimBM ; inc minute timer btfsc STATUS,Z incf _TimBM clrf _TimBmS ; clr mS timer at 60000 clrf _TimBmS+1 ; Service Second Timer B DOTIMBS incf _TimBDumS,F ; inc dummy second counter btfsc STATUS,Z incf _TimBDumS+1,F movlw 0x03 ; chk if over 1000 (1 second) xorwf _TimBDumS+1,W ; chk hi byte btfss STATUS,Z ; clr = not zero = not there yet goto DOC movlw 0xE8 ; chk lo byte subwf _TimBDumS,W btfss STATUS,C ; clr = neg = time is not up goto DOC incf _TimBS,F ; inc second timer btfsc STATUS,Z incf _TimBS+1,F clrf _TimBDumS ; clr Dummy counter at 1000 clrf _TimBDumS+1 goto DOC ; Reset Timer B DORESETB clrf _TimBmS clrf _TimBmS+1 clrf _TimBDumS clrf _TimBDumS+1 clrf _TimBS clrf _TimBS+1 clrf _TimBM clrf _TimBM+1 clrf _ResetB ; Check if Need to Reset Timer C DOC movf _ResetC,W btfss STATUS,Z ; clr = flag set = reset timer goto DORESETC ; Service mS Timer C incf _TimCmS,F ; inc mS timer btfsc STATUS,Z incf _TimCmS+1,F ; Service Minute Timer C movlw 0xEA ; chk if over 60000 (60 seconds) xorwf _TimCmS+1,W ; chk hi byte btfss STATUS,Z ; clr = not zero = not there yet goto DOTIMCS movlw 0x60 ; chk lo byte subwf _TimCmS,W btfss STATUS,C ; clr = neg = time is not up goto DOTIMCS incf _TimCM ; inc minute timer btfsc STATUS,Z incf _TimCM clrf _TimCmS ; clr mS timer at 60000 clrf _TimCmS+1 ; Service Second Timer C DOTIMCS incf _TimCDumS,F ; inc dummy second counter btfsc STATUS,Z incf _TimCDumS+1,F movlw 0x03 ; chk if over 1000 (1 second) xorwf _TimCDumS+1,W ; chk hi byte btfss STATUS,Z ; clr = not zero = not there yet goto DOD movlw 0xE8 ; chk lo byte subwf _TimCDumS,W btfss STATUS,C ; clr = neg = time is not up goto DOD incf _TimCS,F ; inc second timer btfsc STATUS,Z incf _TimCS+1,F clrf _TimCDumS ; clr Dummy counter at 1000 clrf _TimCDumS+1 goto DOD ; Reset Timer C DORESETC clrf _TimCmS clrf _TimCmS+1 clrf _TimCDumS clrf _TimCDumS+1 clrf _TimCS clrf _TimCS+1 clrf _TimCM clrf _TimCM+1 clrf _ResetC ; Check if Need to Reset Timer D DOD movf _ResetD,W btfss STATUS,Z ; clr = flag set = reset timer goto DORESETD ; Service mS Timer D incf _TimDmS,F ; inc mS timer btfsc STATUS,Z incf _TimDmS+1,F ; Service Minute Timer D movlw 0xEA ; chk if over 60000 (60 seconds) xorwf _TimDmS+1,W ; chk hi byte btfss STATUS,Z ; clr = not zero = not there yet goto DOTIMDS movlw 0x60 ; chk lo byte subwf _TimDmS,W btfss STATUS,C ; clr = neg = time is not up goto DOTIMDS incf _TimDM ; inc minute timer btfsc STATUS,Z incf _TimDM clrf _TimDmS ; clr mS timer at 60000 clrf _TimDmS+1 ; Service Second Timer D DOTIMDS incf _TimDDumS,F ; inc dummy second counter btfsc STATUS,Z incf _TimDDumS+1,F movlw 0x03 ; chk if over 1000 (1 second) xorwf _TimDDumS+1,W ; chk hi byte btfss STATUS,Z ; clr = not zero = not there yet goto DOE movlw 0xE8 ; chk lo byte subwf _TimDDumS,W btfss STATUS,C ; clr = neg = time is not up goto DOE incf _TimDS,F ; inc second timer btfsc STATUS,Z incf _TimDS+1,F clrf _TimDDumS ; clr Dummy counter at 1000 clrf _TimDDumS+1 goto DOE ; Reset Timer D DORESETD clrf _TimDmS clrf _TimDmS+1 clrf _TimDDumS clrf _TimDDumS+1 clrf _TimDS clrf _TimDS+1 clrf _TimDM clrf _TimDM+1 clrf _ResetD goto DOE ENDASM ASM ; Check if Need to Reset Timer E DOE movf _ResetE,W btfss STATUS,Z ; clr = flag set = reset timer goto DORESETE ; Service mS Timer E incf _TimEmS,F ; inc mS timer btfsc STATUS,Z incf _TimEmS+1,F ; Service Minute Timer E movlw 0xEA ; chk if over 60000 (60 seconds) xorwf _TimEmS+1,W ; chk hi byte btfss STATUS,Z ; clr = not zero = not there yet goto DOTIMES movlw 0x60 ; chk lo byte subwf _TimEmS,W btfss STATUS,C ; clr = neg = time is not up goto DOTIMES incf _TimEM ; inc minute timer btfsc STATUS,Z incf _TimEM clrf _TimEmS ; clr mS timer at 60000 clrf _TimEmS+1 ; Service Second Timer E DOTIMES incf _TimEDumS,F ; inc dummy second counter btfsc STATUS,Z incf _TimEDumS+1,F movlw 0x03 ; chk if over 1000 (1 second) xorwf _TimEDumS+1,W ; chk hi byte btfss STATUS,Z ; clr = not zero = not there yet goto DOF movlw 0xE8 ; chk lo byte subwf _TimEDumS,W btfss STATUS,C ; clr = neg = time is not up goto DOF incf _TimES,F ; inc second timer btfsc STATUS,Z incf _TimES+1,F clrf _TimEDumS ; clr Dummy counter at 1000 clrf _TimEDumS+1 goto DOF ; Reset Timer E DORESETE clrf _TimEmS clrf _TimEmS+1 clrf _TimEDumS clrf _TimEDumS+1 clrf _TimES clrf _TimES+1 clrf _TimEM clrf _TimEM+1 clrf _ResetE goto DOF ; Check if Need to Reset Timer F DOF movf _ResetF,W btfss STATUS,Z ; clr = flag set = reset timer goto DORESETF ; Service mS Timer F incf _TimFmS,F ; inc mS timer btfsc STATUS,Z incf _TimFmS+1,F ; Service Minute Timer F movlw 0xEA ; chk if over 60000 (60 seconds) xorwf _TimFmS+1,W ; chk hi byte btfss STATUS,Z ; clr = not zero = not there yet goto DOTIMFS movlw 0x60 ; chk lo byte subwf _TimFmS,W btfss STATUS,C ; clr = neg = time is not up goto DOTIMFS incf _TimFM ; inc minute timer btfsc STATUS,Z incf _TimFM clrf _TimFmS ; clr mS timer at 60000 clrf _TimFmS+1 ; Service Second Timer F DOTIMFS incf _TimFDumS,F ; inc dummy second counter btfsc STATUS,Z incf _TimFDumS+1,F movlw 0x03 ; chk if over 1000 (1 second) xorwf _TimFDumS+1,W ; chk hi byte btfss STATUS,Z ; clr = not zero = not there yet goto ENDINT movlw 0xE8 ; chk lo byte subwf _TimFDumS,W btfss STATUS,C ; clr = neg = time is not up goto ENDINT incf _TimFS,F ; inc second timer btfsc STATUS,Z incf _TimFS+1,F clrf _TimFDumS ; clr Dummy counter at 1000 clrf _TimFDumS+1 goto ENDINT ; Reset Timer F DORESETF clrf _TimFmS clrf _TimFmS+1 clrf _TimFDumS clrf _TimFDumS+1 clrf _TimFS clrf _TimFS+1 clrf _TimFM clrf _TimFM+1 clrf _ResetF goto ENDINT ENDINT movf prodLsave,W movwf PRODL,ACCESS movf prodHsave,W movwf PRODH,ACCESS movf fsr0Lsave,W movwf FSR0L,ACCESS movf fsr0Hsave,W movwf FSR0H,ACCESS movf fsr1Lsave,W movwf FSR1L,ACCESS movf fsr1Hsave,W movwf FSR1H,ACCESS movf fsr2Lsave,W movwf FSR2L,ACCESS movf fsr2Hsave,W movwf FSR2H,ACCESS movf psave,W movwf PCLATH,ACCESS retfie 0x01 EndAsm ; SUBROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAC Analog Out DACOUT: if(AOValue > 1023) then AOValue = 1023 ; limit value if(AOValue < 0) then AOValue = 0 if(AOCh > 7) then return ; limit value if(AOCh < 0) then return SPIData = SSP2BUF ; read buffer to allow transmission SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) ; Build First Data Byte SPIData = AOCh << 4 ; get channel SPIDummy = AOValue >> 6 ; get high byte of value SPIData = SPIData | SPIDummy ; add high byte of value ; Send First Data Byte LATH.1 = 0 ; enable (clear) chip select PIR2.5 = 0 SSP2BUF = SPIData ; byte sent While (PIR2.5 = 0) ; wait for end of transmission Wend PIR2.5 = 0 pauseus 10 ; Build Second Data Byte SPIData = SSP2BUF ; read buffer to allow transmission SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) SPIData = AOValue & %11111111 ; add reset of value SPIData = SPIData << 2 ; Send Second Data Byte SSP2BUF = SPIData While (PIR2.5 = 0) Wend PIR2.5 = 0 LATH.1 = 1 ; set (disable) chip select Return ; EEPROM Routines ; EEPROM Variables EEAddress var long bankA EEValue var byte bankA EEWRITE: if(EEAddress > 131071) then EEAddress = 131071 ; limit value SSP2STAT.6 = 1 ; transmit on falling clock edge SPIData = SSP2BUF ; read buffer to allow transmission SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) ; Build First Data Byte, write enable SPIData = %00000110 ; Send First Data Byte LATD.7 = 0 ; enable (clear) chip select PIR2.5 = 0 SSP2BUF = SPIData ; byte sent While (PIR2.5 = 0) ; wait for end of transmission Wend PIR2.5 = 0 LATD.7 = 1 ; set (disable) chip select pauseus 10 ; Build Second Data Byte, write instruction SPIData = SSP2BUF ; read buffer to allow transmission SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) SPIData = %00000010 ; Send Second Data Byte LATD.7 = 0 ; enable (clear) chip select SSP2BUF = SPIData While (PIR2.5 = 0) Wend PIR2.5 = 0 pauseus 10 ; Build Third Data Byte, Address High Byte SPIData = SSP2BUF ; read buffer to allow transmission SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) SPIData = EEAddress >> 16 ; Send Third Data Byte SSP2BUF = SPIData While (PIR2.5 = 0) Wend PIR2.5 = 0 pauseus 10 ; Build Fourth Data Byte, Address Mid Byte SPIData = SSP2BUF ; read buffer to allow transmission SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) SPIData = (EEAddress >> 8) & %11111111 ; Send Fourth Data Byte SSP2BUF = SPIData While (PIR2.5 = 0) Wend PIR2.5 = 0 pauseus 10 ; Build Fifth Data Byte, Address Low Byte SPIData = SSP2BUF ; read buffer to allow transmission SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) SPIData = EEAddress & %11111111 ; Send Fifth Data Byte SSP2BUF = SPIData While (PIR2.5 = 0) Wend PIR2.5 = 0 pauseus 10 ; Build Sixth Data Byte, Data SPIData = SSP2BUF ; read buffer to allow transmission SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) SPIData = EEValue ; Send Sixth Data Byte SSP2BUF = SPIData While (PIR2.5 = 0) Wend PIR2.5 = 0 LATD.7 = 1 ; set (disable) chip select SSP2STAT.6 = 0 ; transmit on rising clock edge Return EEREAD: if(EEAddress > 131071) then EEAddress = 131071 ; limit value SSP2STAT.6 = 1 ; transmit on falling clock edge SPIData = SSP2BUF ; read buffer to allow transmission SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) ; Build First Data Byte, read instruction SPIData = %00000011 ; Send first Data Byte LATD.7 = 0 ; enable (clear) chip select SSP2BUF = SPIData While (PIR2.5 = 0) Wend PIR2.5 = 0 pauseus 10 ; Build Second Data Byte, Address High Byte SPIData = SSP2BUF ; read buffer to allow transmission SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) SPIData = EEAddress >> 16 ; Send Second Data Byte SSP2BUF = SPIData While (PIR2.5 = 0) Wend PIR2.5 = 0 pauseus 10 ; Build Third Data Byte, Address Mid Byte SPIData = SSP2BUF ; read buffer to allow transmission SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) SPIData = (EEAddress >> 8) & %11111111 ; Send Third Data Byte SSP2BUF = SPIData While (PIR2.5 = 0) Wend PIR2.5 = 0 pauseus 10 ; Build Fourth Data Byte, Address Low Byte SPIData = SSP2BUF ; read buffer to allow transmission SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) SPIData = EEAddress & %11111111 ; Send Fourth Data Byte SSP2BUF = SPIData While (PIR2.5 = 0) Wend PIR2.5 = 0 pauseus 10 ; Read Data SPIData = SSP2BUF ; read buffer to allow transmission SSP2CON1.6 = 0 ; clr SPI overflow flag (SSPOV) SSP2CON1.7 = 0 ; clr SPI collision flag (WCOL) SPIData = 0 ; must send data to read from EEPROM ; Send Fifth Data Byte SSP2BUF = SPIData While (PIR2.5 = 0) Wend PIR2.5 = 0 pauseus 10 EEValue = SSP2BUF LATD.7 = 1 ; set (disable) chip select SSPSTAT.6 = 0 ; transmit on rising clock edge Return