PDA

View Full Version : Broken code



sinoteq
- 7th February 2007, 09:11
Hi,
I am using a 18F4620 and now I have some really strange things going on. I have a sub that is shifiting data to a external chip. If the code is smaller than 5A7F this works perfectly, but if I change anything in the code so it becomes larger the sub stops to work. The sub is in the middle of my program and the things I change are not related at all with this sub. Any ideas??

Mike

mister_e
- 7th February 2007, 12:40
i elaredy something like that but... it never happen to me. What you need to do is to move your sub somewhere else.

sinoteq
- 7th February 2007, 12:55
If I move the sub won't another sub take it's place? And then that one will not work. I need all my subs working :) There must be a reason for these stange things, I just need someone to figure it out or point me in the right direction.

Mike

skimask
- 7th February 2007, 13:10
If I move the sub won't another sub take it's place? And then that one will not work. I need all my subs working :) There must be a reason for these stange things, I just need someone to figure it out or point me in the right direction.

Mike

Which version of PBP are you using?

sinoteq
- 7th February 2007, 13:14
I am using MPLAB 7.10 and PicBasic Pro 2.46

skimask
- 7th February 2007, 13:16
I am using MPLAB 7.10 and PicBasic Pro 2.46

Got some source code for us to look at?

On another note - you said you are using the 4620 to shift code out to another chip. Are you using the hardware SPI? If so, I've had nothing but trouble with that (nothing in the errata from Microchip). But I gave up on the hardware SPI and just wrote some code to 'bit-bang' the shifting for me. Fixed all my problems...

sinoteq
- 7th February 2007, 14:46
I am using a bit bang shift out so that part is no problem. I have done some more investigation and this is what things looks like:

I have a working program and I add ONE new variable (Fire_Rate Var Byte), this code compiles to 5A7F and is working.

I change the variable to Word size (Fire_Rate Var Word) this code compiles to 5ABF. This is 64 bytes larger but that can be explained with the 64 bytes blocks used in the 18F flash. This code does not work.

If I change back to Byte size variable and use Define Reset ORG to trick the PIC into "making my program bigger" by adding 64 empty bytes in the begining the code compiles to 5ABF. This code is working.

I take it from this that the problem is not related to the program size but to the allocation of RAM. The Fire_Rate variable is not used at all in the sub that has the problem, but obviously it is related in some way, most likely because it is changing the RAM allocation and bank select.

I will look at the list file and see if I can come up with why and where things stops to work.

Mike

keithdoxey
- 7th February 2007, 15:46
Do you have any BRANCH instructions which may need to be changed to BRANCHL ?

sinoteq
- 7th February 2007, 16:05
Nope. Only old useful Goto and GOSUB. By the way I can't see anything strange with the LST file.

Mike

Bruce
- 7th February 2007, 17:21
Check to see if you have a GOSUB to any routine that doesn't issue a
RETURN to get back.

sinoteq
- 7th February 2007, 18:31
Thank you for all ideas but still no luck in fixing the problem. The program jumps to the sub but the sub makes some really strange things before it jumps back to where should. If I just remove the new variable or make it a Byte size things are working. I will see what happenes if I make 2 new byte size variables, that should be similar to making one word variable and using a word variable becomes crap. :)

Later.....
Mike

Darrel Taylor
- 7th February 2007, 23:33
Since we have to play 20 questions here...

Do you have any Assembly instructions in your code?

Adding a variable might move something to a different bank than the program is expecting.
<br>

sinoteq
- 17th February 2007, 03:14
Sorry for playing "20 questions". I could not post the code because the code should not be public knowledge. Anyway the problem is solved and here is an update.

The problem is with RAM allocation, PBP has a problem when assigning RAM space to variables. In this case one byte of a WORD size variable was assigned to the last adress in BANKA and the other byte of the same Word variable to the first adress in BANK0. Variables can not span 2 banks and this is why strange things happend. Melabs helped me to find this and they are working on a fix for this. There is a workaround, assign any BYTE size variable to the last adress of each bank you are using. Check the .ASM file and you can see how many variables you are using. This problem can happen between all RAM banks not only BANKA and BANK0. For 18F4620 that I use I added

n Var Byte $7F

This prevents a WORD to be assigned to the last adress of BANKA and also solved the problem.

If you have a program with many variables this is something you would like to check. This problem is ALSO in current versions of 2.47!

Mike

MarkEngineer
- 28th November 2014, 16:37
It is the day after Thanksgiving. This sound like a problem I am having with a PIC18F46K22. Certain subs that I call make the program go into outer space. I have even tried GOSUB to a subroutine that only contains a RETURN statement and it never returns. ONLY subs after what seems to be a sizable program exhibit this problem and it is every one of them.. Will check variables on the boundary on Monday.

towlerg
- 28th November 2014, 17:17
Have you overflowed (or is that overflown?) the stack? Don't know 18F46K22 but some 18F's have option to reset on stack overflow.

George

Acetronics2
- 28th November 2014, 17:28
no code to look at = no serious answer .... :rolleyes:

MIGHT be a stack overflow ...

Alain

MarkEngineer
- 28th November 2014, 17:30
Watchdog timer is off, I do use an Assembly interrupt routine to create a time base using TIMER2. AT 16 MHZ I can make a 1/100th second interrupt.
I do not think I am overflowing the stack (or maybe I am?) as there is one GOSUB to one subroutine at a time in a Mainloop which contains nothing but a RETURN statement. If I move the subroutine further up in the code, it works fine. It seems like once it is further down enough, no subroutine will RETURN back.
The PIC has 64K of code space, I should be nowhere near that. I wonder if I am crossing some 2K boundary or something like that or if the interrupt routine
screws up a bank select register. I use MOVFF in the assembly interrupt routine to save W, STATUS, BSR, PCLATH upon entering, and restore upon exiting then RETFIE.

towlerg
- 28th November 2014, 19:39
JOOQ I looked at 18F46K22 datasheet. You can read the stack pointer, STKPTR. Just before your call test the stack pointer. At least you know whether your about to overflow. And of course make sure you have STVREN on.

George

rsocor01
- 28th November 2014, 23:05
Mark, most people here, including myself, won't be able to help you with assembly language. Only a few here have gone to the dark side and know assembly :).

You said that the RETURN command in your subroutine doesn't seem to be working. It is very important to know the line where the program isn't working anymore. What I ussually do is to write a line of code to turn on an LED for 5 seconds. Then, I move that line toward the end of the program until the LED doesn't turn on anymore. Put this line before entering the subroutine and then inside the subroutine and let us know what you find out.

MarkEngineer
- 1st December 2014, 13:22
OK I am using MPLAB 8.92 with PICBASIC 3 Gold

GOSUB TEST1 works fine
GOSUB TEST2 (or ANY subroutine after it) does not
Here is my code, all comments are welcome

; Tell PBP the expected system-clock frequency

INCLUDE "PIC18F46K22.INC"

DEFINE OSC 16

'Define interrupt handler
DEFINE INTHAND TIMERINT

'Don’t insert CLRWDTs
DEFINE NO_CLRWDT 1

'Set receive register to receiver enabled
DEFINE HSER_RCSTA 90h
' RCSTA

'Set transmit register to transmitter enabled
DEFINE HSER_TXSTA 20h

'Set baud rate
DEFINE HSER_BAUD 19200

'Clear overrun error upon execution of every HSERIN command
DEFINE HSER_CLROERR 1

'disable intrs during EEPROM writes
DEFINE WRITE_INT 1

GOTO START
'------------------------------------------------------------------------------------------------------------------------
'interrupt handler

ASM
TIMERINT

;interrupt service routine

;MOVFF source, destination = move source reg to dest reg
;either register can be in ram 000 to FFF

;save critical registers
MOVFF W,_PreISR_W ;save W register contents
MOVFF STATUS,_PreISR_STATUS ;save contents of STATUS register
MOVFF PCLATH,_PreISR_PCLATH ;save contents of PCLATH register
MOVFF PCLATU,_PreISR_PCLATU ;save contents of PCLATU register
MOVFF BSR,_PreISR_BSR ;save contents of BSR register
MOVFF FSR0L,_PreISR_FSR0L ;ind addr pointer lo
MOVFF FSR0H,_PreISR_FSR0H ;ind addr pointer hi

CLRF PCLATH
CLRF STATUS
CLRF BSR

;look for the timer2 interrupt
NextIfCLR PIR1,TMR2IF ;check if timer2 int flag is set
GOTO NotTimer2INT ;no
BCF PIR1,TMR2IF ;yes,reset timer2 int flag

MOVLB H'A' ;select ram bank A

;increment interrupt counters
INCF _INTRCOUNT,File_reg
;................................................. .................................................. .....................
NotTimer2INT

CHECKRS232

;If an overrun occurred, clear the OERR flag by clearing the CREN receiver enable bit.
BANKSEL RCSTA1
NextIfSET RCSTA1,1 ;check for overrun by testing the OERR flag
GOTO OverRUN

BANKSEL PIR1
NextIfSET PIR1,RCIF ;check for any received data
GOTO GOTchar

MOVLB H'A' ;select ram bank A
CLRF _RS232RECD
GOTO FinishISR

GOTchar
BANKSEL RCREG1
MOVF RCREG1,W_reg
MOVLB H'A' ;select ram bank A
MOVWF _RS232RECD
GOTO FinishISR

OverRUN
BCF RCSTA1,1
BCF RCSTA1,4
NOP
BSF RCSTA1,4

FinishISR
MOVFF _PreISR_PCLATH,PCLATH ;restore pre-isr PCLATH register
MOVFF _PreISR_PCLATU,PCLATU ;restore pre-isr PCLATU register
MOVFF _PreISR_STATUS,STATUS ;restore pre-isr STATUS register
MOVFF _PreISR_BSR,BSR ;restore pre-isr BSR register
MOVFF _PreISR_FSR0L,FSR0L ;ind addr pointer lo
MOVFF _PreISR_FSR0H,FSR0H ;ind addr pointer hi
MOVFF _PreISR_W,W

RETFIE ;return from interrupt

ENDASM
'------------------------------------------------------------------------------------------------------------------------
START:


'setup the oscillator

OSCCON = %01111100
' 0 IDLEN Device enters Sleep mode on SLEEP instruction
' .111 IRCF<2:0> = HFINTOSC – (16 MHz)
' ....1 Device is running from the clock defined by FOSC<3:0> of the CONFIG1H register
' .....1 HFINTOSC frequency is stable
' ......00 Primary clock (determined by FOSC<3:0> in CONFIG1H)

OSCCON2 = %10000111
' 1 System clock comes from 4xPLL
' .0 System clock comes from an oscillator, other than SOSC
' ..0 Unimplemented: Read as ‘0’
' ...0 MFINTOSC is not used
' ....0 Secondary oscillator is shut off if no other sources are requesting it.
' .....1 PRISD: Primary Oscillator Drive Circuit Shutdown = Oscillator drive circuit on
' ......1 MFINTOSC is stable
' .......1 LFINTOSC is stable
'------------------------------------------------------------------------------------------------------------------------
'setup I/O pins

'PORTA...................

ANSELA = %00000111
' 0 Unimplemented: Read as ‘0’
' .0 Unimplemented: Read as ‘0’
' ..0 RA5 is digital
' ...0 Unimplemented: Read as ‘0’
' ....1 RA3 is analog AN3 = BUFFERED LIGHT SIG4
' .....1 RA2 is analog AN2 = BUFFERED LIGHT SIG3
' ......1 RA1 is analog AN1 = BUFFERED LIGHT SIG2
' .......1 RA0 is analog AN0 = BUFFERED LIGHT SIG1

TRISA = %00111111
' 0 RA7 output = SELECT1
' .0 RA6 output = SELECT2
' ..1 RA5 input = MOTION INPUT STATUS
' ...1 RA4 input = SWITCH STATUS
' ....1 RA3 input = BUFFERED LIGHT SIG4
' .....1 RA2 input = BUFFERED LIGHT SIG3
' ......1 RA1 input = BUFFERED LIGHT SIG2
' .......1 RA0 input = BUFFERED LIGHT SIG1

LATA.7 = 1
LATA.6 = 1

'PORTB...................

ANSELB = %00000000
' 0 RB7 is digital = PGD
' .0 RB6 is digital = PGC
' ..0 RB5 is digital
' ...0 RB4 is digital
' ....0 RB3 is digital
' .....0 RB2 is digital
' ......0 RB1 is digital
' .......0 RB0 is digital

TRISB = %11111111
' 1 RB7 input = PGD
' .1 RB6 input = PGC
' ..1 RB5 input = DIP3
' ...1 RB4 input = DIP2
' ....1 RB3 input = DIP1
' .....1 RB2 input = TEST CH4 button
' ......1 RB1 input = TEST CH3 button
' .......1 RB0 input = TEST CH2 button

WPUB = %00111111
' 0 RB7 weak pullup disabled = PGD
' .0 RB6 weak pullup disabled = PGC
' ..1 RB5 weak pullup enabled
' ...1 RB4 weak pullup enabled
' ....1 RB3 weak pullup enabled
' .....1 RB2 weak pullup enabled
' ......1 RB1 weak pullup enabled
' .......1 RB0 weak pullup enabled

IOCB = 0 'disable interrupt on change


'PORTC...................

ANSELC = %00000000
' 0 RC7 is digital
' .0 RC6 is digital
' ..0 RC5 is digital
' ...0 RC4 is digital
' ....0 RC3 is digital
' .....0 RC2 is digital
' ......0 RC1 is digital
' .......0 RC0 is digital

TRISC = %10010000
' 1 RC7 input = RX1
' .0 RC6 output = TX1
' ..0 RC5 output = SDO
' ...1 RC4 input = SDI
' ....0 RC3 output = SCK
' .....0 RC2 output = LED
' ......0 RC1 output = CSDAC2
' .......0 RC0 output = CSDAC1

LATC.2 = 1
LATC.1 = 1
LATC.0 = 1

'PORTD...................

ANSELD = %00000000
' 0 RD7 is digital
' .0 RD6 is digital
' ..1 RD5 is analog AN25 = MAX4 POT
' ...1 RD4 is analog AN24 = MAX3 POT
' ....1 RD3 is analog AN23 = MAX2 POT
' .....1 RD2 is analog AN22 = MAX1 POT
' ......1 RD1 is analog AN21 = MIN4 POT
' .......1 RD0 is analog AN20 = MIN3 POT

TRISD = %10111111
' 1 RD7 input = RX2
' .0 RD6 output = TX2
' ..1 RD5 input = AN25 = MAX4 POT
' ...1 RD4 input = AN24 = MAX3 POT
' ....1 RD3 input = AN23 = MAX2 POT
' .....1 RD2 input = AN22 = MAX1 POT
' ......1 RD1 input = AN21 = MIN4 POT
' .......1 RD0 input = AN20 = MIN3 POT


'PORTE...................

ANSELE = %00000011
' ....0 RE3 is digital = TEST CH1 button
' .....0 RE2 is digital = interrupt output
' ......1 RE1 is analog AN6 = MIN2 POT
' .......1 RE0 is analog AN5 = MIN1 POT

TRISE = %10001011
' 1 weak pullup enabled on RE3
' ....1 RE3 input = digital = TEST CH1
' .....0 RE2 output = for test purposes
' ......1 RE1 input = AN6 = MIN2 POT
' .......1 RE0 input = AN5 = MIN1 POT
'------------------------------------------------------------------------------------------------------------------------
'setup A/D converter

ADCON1 = %00000000
' 0 Selects the special trigger from CCP5
' .000 bit 6-4 Unimplemented: Read as ‘0’
' ....00 A/D VREF+ connected to internal signal, AVDD
' ......00 A/D VREF- connected to internal signal, AVSS

ADCON2 = %10111101
' 1 ADFM=right justified, ADRESH contains the 2 most significant bits ADRESL contains the 8 least significant bits
' .0 Unimplemented
' ..111 A/D Acquisition time = 20 TAD
' .....101 A/D Conversion Clock = FOSC/16

ADCON0 = %0000001 'a/d is enabled
'------------------------------------------------------------------------------------------------------------------------
'setup timer0 (UNUSED)
'
' T0CON = %XXXXXXXX
' 1 TMR0ON Enable Timer0
' .0 T08BIT Timer0 is configured as an 16-bit timer/counter
' ..0 T0CS Internal instruction cycle clock (CLKOUT)
' ...1 T0SE Increment on high-to-low transition on T0CKI pin
' ....0 PSA Timer0 prescaler is assigned. Timer0 clock input comes from prescaler output.
' 1 = TImer0 prescaler is NOT assigned. Timer0 clock input bypasses prescaler.
' 0 = Timer0 prescaler is assigned. Timer0 clock input comes from prescaler output.
' .....xxx T0PS<2:0> 111 = 1:256 prescale value'
' 110 = 1:128 prescale value
' 101 = 1:64 prescale value
' 100 = 1:32 prescale value
' 011 = 1:16 prescale value
' 010 = 1:8 prescale value
' 001 = 1:4 prescale value
' 000 = 1:2 prescale value
'------------------------------------------------------------------------------------------------------------------------
'setup timer2
'Fosc/4 with prescaler=16 AND postscaler of 10 yields 25,000 Hz, count of 250 gives interrupt every hundreth of a second

PR2 = 249 'Timer2 Period Register
T2CON = %01001110
'
' bit 7 Unimplemented: Read as ‘0’
' bit 6-3 T2OUTPS<3:0>: TimerX Output Postscaler Select bits
' 0000 = 1:1 Postscaler
' 0001 = 1:2 Postscaler
' 0010 = 1:3 Postscaler
' 0011 = 1:4 Postscaler
' 0100 = 1:5 Postscaler
' 0101 = 1:6 Postscaler
' 0110 = 1:7 Postscaler
' 0111 = 1:8 Postscaler
' 1000 = 1:9 Postscaler
' 1001 = 1:10 Postscaler
' 1010 = 1:11 Postscaler
' 1011 = 1:12 Postscaler
' 1100 = 1:13 Postscaler
' 1101 = 1:14 Postscaler
' 1110 = 1:15 Postscaler
' 1111 = 1:16 Postscaler
' bit 2 TMR2ON: Timer2 On bit
' 1 = Timer2 is on
' 0 = Timer2 is off
' bit 1-0 T2xCKPS<1:0>: Timer2-type Clock Prescale Select bits
' 00 = Prescaler is 1
' 01 = Prescaler is 4
' 1x = Prescaler is 16
'------------------------------------------------------------------------------------------------------------------------
;setup registers for MSSP1..........................
SSP1CON1 = %00100010
; 0....... WCOL: Write Collision Detect bit 0=No collision
; 0...... SSPOV: Receive Overflow Indicator bit 0 = No overflow
; 1..... SSPEN: Master Synchronous Serial Port Enable bit
; 1 = Enables serial port and configures SCK1, SDO1, SDI1 and SS1 as serial port pins
; 0.... CKP: Clock Polarity Select 0 = Idle state for clock is a low level
; 0010 SSPM<3:0>: Master Synchronous Serial Port Mode Select bits
; 0010 = SPI Master mode, clock = FOSC/64

SSP1STAT = %01000000
; 0....... SMP: Sample bit 0 = Input data sampled at middle of data output time
; 1...... CKE: SPI Clock Select bit
; 1 = Transmit occurs on transition from active to Idle clock state
; 0 = Transmit occurs on transition from Idle to active clock state
; NOTE: found that 0 or 1 seems to work if using MSSP1
; but only 1 works with re-mapped MSSP2
; 0..... Used in I2C™ mode only.
; 0.... Used in I2C™ mode only.
; 0... Used in I2C™ mode only.
; 0.. Used in I2C™ mode only.
; 0 BF: Buffer Full Status bit 0 = Receive not complete, SSPxBUF is empty
'------------------------------------------------------------------------------------------------------------------------
;initialize parameters



;*********************************
;TEST FOR CALLING SUBROUTINES

GOSUB TEST1
;GOSUB TEST2

;*********************************


RS232RECD = 0
EXITCAL = 0
ANALOG = 0

TIMERFLAGS = 0
TIMECTR0 = 0
TIMECTR1 = 0
TIMECTR2 = 0
TIMECTR3 = 0
TIMECTR4 = 0
TIMECTR5 = 0
TIMECTR6 = 0
TIMECTR7 = 0

TIMECTR0 = 1000 : TIMERFLAGS.0 = 1
TIMECTR1 = 1000 : TIMERFLAGS.1 = 1
TIMECTR2 = 1000 : TIMERFLAGS.2 = 1
TIMECTR3 = 1000 : TIMERFLAGS.3 = 1
TIMECTR4 = 1000 : TIMERFLAGS.4 = 1
TIMECTR5 = 1000 : TIMERFLAGS.5 = 1
TIMECTR6 = 1000 : TIMERFLAGS.6 = 1
TIMECTR7 = 1000 : TIMERFLAGS.7 = 1

POTMIN1 = 0
POTMIN2 = 0
POTMIN3 = 0
POTMIN4 = 0

POTMAX1 = 0
POTMAX2 = 0
POTMAX3 = 0
POTMAX4 = 0

LIGHT1 = 0
LIGHT2 = 0
LIGHT3 = 0
LIGHT4 = 0

ANALOGCAL1 = 65535
ANALOGCAL2 = 65535
ANALOGCAL3 = 65535
ANALOGCAL4 = 65535

CALBYTE = 0

ANALOGOUT1 = 0
ANALOGOUT2 = 0
ANALOGOUT3 = 0
ANALOGOUT4 = 0
;GOSUB SETANALOG1
;GOSUB SETANALOG2
;GOSUB SETANALOG3
;GOSUB SETANALOG4

INPUTS.9 = 0
INPUTS.10 = 0
INPUTS.11 = 0
INPUTS.12 = 0
INPUTS.13 = 0
INPUTS.14 = 0
INPUTS.15 = 0

ZONE1 = 20
ZONE2 = 40
ZONE3 = 60

TIMEHYS = 10

SSPEN = 0 ' disable/enable SSP to reset MSSP port
PAUSE 2
SSPEN = 1

'check EEPROM for cal values dac_a
READ 0, EEPROMCODE
IF EEPROMCODE = $55AA THEN
READ 2, EEPROMCAL
IF EEPROMCAL > 1000 AND EEPROMCAL < 1500 THEN
CALBYTE.0 = 1
ANALOGCAL1 = EEPROMCAL
ENDIF
ENDIF

'check EEPROM for cal values dac_b
READ 10, EEPROMCODE
IF EEPROMCODE = $55AA THEN
READ 12, EEPROMCAL
IF EEPROMCAL > 1000 AND EEPROMCAL < 1500 THEN
CALBYTE.1 = 1
ANALOGCAL2 = EEPROMCAL
ENDIF
ENDIF

'check EEPROM for cal values dac_c
READ 20, EEPROMCODE
IF EEPROMCODE = $55AA THEN
READ 22, EEPROMCAL
IF EEPROMCAL > 1000 AND EEPROMCAL < 1500 THEN
CALBYTE.2 = 1
ANALOGCAL3 = EEPROMCAL
ENDIF
ENDIF

'check EEPROM for cal values dac_d
READ 30, EEPROMCODE
IF EEPROMCODE = $55AA THEN
READ 32, EEPROMCAL
IF EEPROMCAL > 1000 AND EEPROMCAL < 1500 THEN
CALBYTE.3 = 1
ANALOGCAL4 = EEPROMCAL
ENDIF
ENDIF
'------------------------------------------------------------------------------------------------------------------------
'enable necessary interrupts

'PIE1: PERIPHERAL INTERRUPT ENABLE (FLAG) REGISTER 1
PIE1 = %00000010
' 0 Unimplemented: Read as ‘0’.
' .0 A/D Converter Interrupt disabled
' ..0 Enables the EUSART1 receive interrupt
' ...0 Disables the EUSART1 transmit interrupt
' ....0 Disables the MSSP1 interrupt
' .....0 Disables the CCP1 interrupt
' ......1 Enables the TMR2 to PR2 match interrupt
' .......0 Disables the TMR1 overflow interrupt

'PIE2: PERIPHERAL INTERRUPT ENABLE (FLAG) REGISTER 2
PIE2 = 0 'all of these interrupts disabled

'PIE3: PERIPHERAL INTERRUPT ENABLE (FLAG) REGISTER 3
PIE3 = 0 'all of these interrupts disabled

'PIE4: PERIPHERAL INTERRUPT ENABLE (FLAG) REGISTER 4
PIE3 = 0 'all of these interrupts disabled

INTCON = %11000000
'bit 7 GIE/GIEH: Global Interrupt Enable bit 1 = Enables all unmasked interrupts
'bit 6 PEIE/GIEL: Peripheral Interrupt Enable bit (including timer2)
'bit 5 TMR0IE: TMR0 Overflow Interrupt Enable bit 1 = Enables the TMR0 overflow interrupt
'bit 4 INT0IE: INT0 External Interrupt Enable bit
'bit 3 RBIE: Port B Interrupt-On-Change (IOCx) Interrupt Enable bit
'bit 2 TMR0IF: TMR0 Overflow Interrupt Flag bit
'bit 1 INT0IF: INT0 External Interrupt Flag bit
'bit 0 RBIF: Port B Interrupt-On-Change (IOCx) Interrupt Flag bit

INTCON2 = %00000100
'bit 7 RBPU: PORTB Pull-up Enable bit 0 = PORTB pull-ups are enabled
'bit 6 INTEDG0: External Interrupt 0 Edge Select bit
'bit 5 INTEDG1: External Interrupt 1 Edge Select bit
'bit 4 INTEDG2: External Interrupt 2 Edge Select bit
'bit 3 Unimplemented: Read as ‘0’
'bit 2 TMR0IP: TMR0 Overflow Interrupt Priority bit 1 =High priority
'bit 1 Unimplemented: Read as ‘0’
'bit 0 RBIP: RB Port Change Interrupt Priority bit

INTCON3 = %00000000
'bit 7 INT2IP: INT2 External Interrupt Priority bit
'bit 6 INT1IP: INT1 External Interrupt Priority bit
'bit 5 Unimplemented: Read as ‘0’
'bit 4 INT2IE: INT2 External Interrupt Enable bit
'bit 3 INT1IE: INT1 External Interrupt Enable bit
'bit 2 Unimplemented: Read as ‘0’
'bit 1 INT2IF: INT2 External Interrupt Flag bit
'bit 0 INT1IF: INT1 External Interrupt Flag bit
'------------------------------------------------------------------------------------------------------------------------

;***************************************
;********** M A I N L O O P **********
;***************************************

MAINLOOP:

GOSUB CHARRECEIVED

'when INTRCOUNT = 100 we are at the one second boundary
IF INTRCOUNT < 100 THEN GOTO MAINLOOP

INTRCOUNT = 0

IF CALBYTE < 15 THEN
IF PORTC.2 = 0 THEN
LATC.2 = 1
GOTO MAIN2
ELSE
LATC.2 = 0
GOTO MAIN2
ENDIF
ENDIF

MAIN2:
IF TIMECTR0 > 0 THEN TIMECTR0 = TIMECTR0 - 1
IF TIMECTR1 > 0 THEN TIMECTR1 = TIMECTR1 - 1
IF TIMECTR2 > 0 THEN TIMECTR2 = TIMECTR2 - 1
IF TIMECTR3 > 0 THEN TIMECTR3 = TIMECTR3 - 1
IF TIMECTR4 > 0 THEN TIMECTR4 = TIMECTR4 - 1
IF TIMECTR5 > 0 THEN TIMECTR5 = TIMECTR5 - 1
IF TIMECTR6 > 0 THEN TIMECTR6 = TIMECTR6 - 1
IF TIMECTR7 > 0 THEN TIMECTR7 = TIMECTR7 - 1
;................................................. .................................................. .....................
LATE.2 = 1

'send data
;................................................. .................................................. .....................
'send timer0
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["A"] : PAUSE 2
HSEROUT [TIMECTR0.LOWBYTE] : PAUSE 2
HSEROUT [TIMECTR0.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send timer1
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["B"] : PAUSE 2
HSEROUT [TIMECTR1.LOWBYTE] : PAUSE 2
HSEROUT [TIMECTR1.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send timer2
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["C"] : PAUSE 2
HSEROUT [TIMECTR2.LOWBYTE] : PAUSE 2
HSEROUT [TIMECTR2.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send timer3
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["D"] : PAUSE 2
HSEROUT [TIMECTR3.LOWBYTE] : PAUSE 2
HSEROUT [TIMECTR3.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send timer4
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["E"] : PAUSE 2
HSEROUT [TIMECTR4.LOWBYTE] : PAUSE 2
HSEROUT [TIMECTR4.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send timer5
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["F"] : PAUSE 2
HSEROUT [TIMECTR5.LOWBYTE] : PAUSE 2
HSEROUT [TIMECTR5.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send timer6
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["G"] : PAUSE 2
HSEROUT [TIMECTR6.LOWBYTE] : PAUSE 2
HSEROUT [TIMECTR6.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send timer7
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["H"] : PAUSE 2
HSEROUT [TIMECTR7.LOWBYTE] : PAUSE 2
HSEROUT [TIMECTR7.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send timerflags
GOSUB CHARRECEIVED
TEMP = RS232RECD
HSEROUT [":"] : PAUSE 2
HSEROUT ["I"] : PAUSE 2
HSEROUT [TEMP.LOWBYTE] : PAUSE 2
HSEROUT [TEMP.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send light sensor1
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["J"] : PAUSE 2
HSEROUT [LIGHT1.LOWBYTE] : PAUSE 2
HSEROUT [LIGHT1.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send light sensor2
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["K"] : PAUSE 2
HSEROUT [LIGHT2.LOWBYTE] : PAUSE 2
HSEROUT [LIGHT2.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send light sensor3
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["L"] : PAUSE 2
HSEROUT [LIGHT3.LOWBYTE] : PAUSE 2
HSEROUT [LIGHT3.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send light sensor4
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["M"] : PAUSE 2
HSEROUT [LIGHT4.LOWBYTE] : PAUSE 2
HSEROUT [LIGHT4.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send potmin1
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["N"] : PAUSE 2
HSEROUT [POTMIN1.LOWBYTE] : PAUSE 2
HSEROUT [POTMIN1.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send potmin2
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["O"] : PAUSE 2
HSEROUT [POTMIN2.LOWBYTE] : PAUSE 2
HSEROUT [POTMIN2.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send potmin3
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["P"] : PAUSE 2
HSEROUT [POTMIN3.LOWBYTE] : PAUSE 2
HSEROUT [POTMIN3.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send potmin4
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["Q"] : PAUSE 2
HSEROUT [POTMIN4.LOWBYTE] : PAUSE 2
HSEROUT [POTMIN4.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send potmax1
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["R"] : PAUSE 2
HSEROUT [POTMAX1.LOWBYTE] : PAUSE 2
HSEROUT [POTMAX1.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send potmax2
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["S"] : PAUSE 2
HSEROUT [POTMAX2.LOWBYTE] : PAUSE 2
HSEROUT [POTMAX2.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send potmax3
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["T"] : PAUSE 2
HSEROUT [POTMAX3.LOWBYTE] : PAUSE 2
HSEROUT [POTMAX3.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send potmax4
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["U"] : PAUSE 2
HSEROUT [POTMAX4.LOWBYTE] : PAUSE 2
HSEROUT [POTMAX4.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send analogout1
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["V"] : PAUSE 2
HSEROUT [ANALOGOUT1.LOWBYTE] : PAUSE 2
HSEROUT [ANALOGOUT1.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send analogout2
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["W"] : PAUSE 2
HSEROUT [ANALOGOUT2.LOWBYTE] : PAUSE 2
HSEROUT [ANALOGOUT2.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send analogout3
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["X"] : PAUSE 2
HSEROUT [ANALOGOUT3.LOWBYTE] : PAUSE 2
HSEROUT [ANALOGOUT3.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send analogout4
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["Y"] : PAUSE 2
HSEROUT [ANALOGOUT4.LOWBYTE] : PAUSE 2
HSEROUT [ANALOGOUT4.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send analogoutcal1
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["Z"] : PAUSE 2
HSEROUT [ANALOGCAL1.LOWBYTE] : PAUSE 2
HSEROUT [ANALOGCAL1.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send analogoutcal2
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["a"] : PAUSE 2
HSEROUT [ANALOGCAL2.LOWBYTE] : PAUSE 2
HSEROUT [ANALOGCAL2.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send analogoutcal3
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["b"] : PAUSE 2
HSEROUT [ANALOGCAL3.LOWBYTE] : PAUSE 2
HSEROUT [ANALOGCAL3.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send analogoutcal4
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["c"] : PAUSE 2
HSEROUT [ANALOGCAL4.LOWBYTE] : PAUSE 2
HSEROUT [ANALOGCAL4.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send inputs
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["d"] : PAUSE 2
HSEROUT [INPUTS.LOWBYTE] : PAUSE 2
HSEROUT [INPUTS.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send zone1
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["e"] : PAUSE 2
HSEROUT [ZONE1.LOWBYTE] : PAUSE 2
HSEROUT [ZONE1.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send zone2
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["f"] : PAUSE 2
HSEROUT [ZONE2.LOWBYTE] : PAUSE 2
HSEROUT [ZONE2.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send zone3
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["g"] : PAUSE 2
HSEROUT [ZONE3.LOWBYTE] : PAUSE 2
HSEROUT [ZONE3.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'send time hysteresis
GOSUB CHARRECEIVED
HSEROUT [":"] : PAUSE 2
HSEROUT ["h"] : PAUSE 2
HSEROUT [TIMEHYS.LOWBYTE] : PAUSE 2
HSEROUT [TIMEHYS.HIGHBYTE] : PAUSE 2
HSEROUT ["!"] : PAUSE 2
;................................................. .................................................. .....................
'read inputs..........
' BIT 0 = CH1 TEST PB = RE3 on when = 0
' BIT 1 = CH2 TEST PB = RB0 on when = 0
' BIT 2 = CH3 TEST PB = RB1 on when = 0
' BIT 3 = CH4 TEST PB = RB2 on when = 0
' BIT 4 = DIP1 = RB3 on when = 0
' BIT 5 = DIP2 = RB4 on when = 0
' BIT 6 = DIP3 = RB5 on when = 0
' BIT 7 = AUX SW INPUT = RA4 on when = 1
' BIT 8 = MOTION INPUT = RA5 on when = 1
; BIT 9 = SYSTEM MODE 0= normal 1= cal (set by external RS232 command)

INPUTS.0 = PORTE.3
INPUTS.1 = PORTB.0
INPUTS.2 = PORTB.1
INPUTS.3 = PORTB.2
INPUTS.4 = PORTB.3
INPUTS.5 = PORTB.4
INPUTS.6 = PORTB.5
INPUTS.7 = PORTA.4
INPUTS.8 = PORTA.5
;................................................. .................................................. .....................
'read light sensor 1 on AN0 = RA0 pin 2
ADCON0 = %00000011
' 0 bit 7 Unimplemented: Read as ‘0’
' .00000 = AN0
' ......1 bit 1 GO/DONE: A/D Conversion Status bit
' 1 = A/D conversion cycle in progress
' Setting this bit starts an A/D conversion cycle.
' This bit is automatically cleared by hardware when
' the A/D conversion has completed.
' 0 = A/D conversion completed/not in progress
' .......1 bit 0 ADON: ADC Enable bit
' 1 = ADC is enabled
' 0 = ADC is disabled and consumes no operating current

ADLOOP1:
PAUSE 5
If ADCON0.1 = 1 Then GOTO ADLOOP1 'Wait for low on bit-1 of ADCON0, conversion finished

ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
ANALOG.LOWBYTE = ADRESL 'LOW byte of result
TEMPLONG1=ANALOG*100
TEMPLONG2=TEMPLONG1/1023
LIGHT1 = TEMPLONG2
;................................................. .................................................. .....................
'read light sensor 2 on AN1 = RA1 pin 3
ADCON0 = %00000111
' 0 bit 7 Unimplemented: Read as ‘0’
' .00001 = AN1
' ......1 bit 1 GO/DONE: A/D Conversion Status bit
' 1 = A/D conversion cycle in progress
' Setting this bit starts an A/D conversion cycle.
' This bit is automatically cleared by hardware when
' the A/D conversion has completed.
' 0 = A/D conversion completed/not in progress
' .......1 bit 0 ADON: ADC Enable bit
' 1 = ADC is enabled
' 0 = ADC is disabled and consumes no operating current

ADLOOP2:
PAUSE 5
If ADCON0.1 = 1 Then GOTO ADLOOP2 'Wait for low on bit-1 of ADCON0, conversion finished

ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
ANALOG.LOWBYTE = ADRESL 'LOW byte of result
TEMPLONG1=ANALOG*100
TEMPLONG2=TEMPLONG1/1023
LIGHT2 = TEMPLONG2
;................................................. .................................................. .....................
'read light sensor 3 on AN2 = RA2 pin 4
ADCON0 = %00001011
' 0 bit 7 Unimplemented: Read as ‘0’
' .00010 = AN2
' ......1 bit 1 GO/DONE: A/D Conversion Status bit
' 1 = A/D conversion cycle in progress
' Setting this bit starts an A/D conversion cycle.
' This bit is automatically cleared by hardware when
' the A/D conversion has completed.
' 0 = A/D conversion completed/not in progress
' .......1 bit 0 ADON: ADC Enable bit
' 1 = ADC is enabled
' 0 = ADC is disabled and consumes no operating current

ADLOOP3:
PAUSE 5
If ADCON0.1 = 1 Then GOTO ADLOOP3 'Wait for low on bit-1 of ADCON0, conversion finished

ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
ANALOG.LOWBYTE = ADRESL 'LOW byte of result
TEMPLONG1=ANALOG*100
TEMPLONG2=TEMPLONG1/1023
LIGHT3 = TEMPLONG2

GOSUB CHARRECEIVED
;................................................. .................................................. .....................
'read light sensor 4 on AN3 = RA3 pin 5
ADCON0 = %00001111
' 0 bit 7 Unimplemented: Read as ‘0’
' .00011 = AN3
' ......1 bit 1 GO/DONE: A/D Conversion Status bit
' 1 = A/D conversion cycle in progress
' Setting this bit starts an A/D conversion cycle.
' This bit is automatically cleared by hardware when
' the A/D conversion has completed.
' 0 = A/D conversion completed/not in progress
' .......1 bit 0 ADON: ADC Enable bit
' 1 = ADC is enabled
' 0 = ADC is disabled and consumes no operating current

ADLOOP4:
PAUSE 5
If ADCON0.1 = 1 Then GOTO ADLOOP4 'Wait for low on bit-1 of ADCON0, conversion finished

ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
ANALOG.LOWBYTE = ADRESL 'LOW byte of result
TEMPLONG1=ANALOG*100
TEMPLONG2=TEMPLONG1/1023
LIGHT4 = TEMPLONG2
;................................................. .................................................. .....................
'read POTMIN1 on AN5 = RE0 pin 8
ADCON0 = %00010111
' 0 bit 7 Unimplemented: Read as ‘0’
' .00101 = AN5
' ......1 bit 1 GO/DONE: A/D Conversion Status bit
' 1 = A/D conversion cycle in progress
' Setting this bit starts an A/D conversion cycle.
' This bit is automatically cleared by hardware when
' the A/D conversion has completed.
' 0 = A/D conversion completed/not in progress
' .......1 bit 0 ADON: ADC Enable bit
' 1 = ADC is enabled
' 0 = ADC is disabled and consumes no operating current

ADLOOP5:
PAUSE 5
If ADCON0.1 = 1 Then GOTO ADLOOP5 'Wait for low on bit-1 of ADCON0, conversion finished

ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
ANALOG.LOWBYTE = ADRESL 'LOW byte of result
TEMPLONG1=ANALOG*100
TEMPLONG2=TEMPLONG1/1023
POTMIN1 = TEMPLONG2
;................................................. .................................................. .....................
'read POTMIN2 on AN6 = RE1 pin 9
ADCON0 = %00011011
' 0 bit 7 Unimplemented: Read as ‘0’
' .00110 = AN6
' ......1 bit 1 GO/DONE: A/D Conversion Status bit
' 1 = A/D conversion cycle in progress
' Setting this bit starts an A/D conversion cycle.
' This bit is automatically cleared by hardware when
' the A/D conversion has completed.
' 0 = A/D conversion completed/not in progress
' .......1 bit 0 ADON: ADC Enable bit
' 1 = ADC is enabled
' 0 = ADC is disabled and consumes no operating current

ADLOOP6:
PAUSE 5
If ADCON0.1 = 1 Then GOTO ADLOOP6 'Wait for low on bit-1 of ADCON0, conversion finished

ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
ANALOG.LOWBYTE = ADRESL 'LOW byte of result
TEMPLONG1=ANALOG*100
TEMPLONG2=TEMPLONG1/1023
POTMIN2 = TEMPLONG2

GOSUB CHARRECEIVED
;................................................. .................................................. .....................
'read POTMIN3 on AN20 = RD0 pin 19
ADCON0 = %01010011
' 0 bit 7 Unimplemented: Read as ‘0’
' .10100 = AN20
' ......1 bit 1 GO/DONE: A/D Conversion Status bit
' 1 = A/D conversion cycle in progress
' Setting this bit starts an A/D conversion cycle.
' This bit is automatically cleared by hardware when
' the A/D conversion has completed.
' 0 = A/D conversion completed/not in progress
' .......1 bit 0 ADON: ADC Enable bit
' 1 = ADC is enabled
' 0 = ADC is disabled and consumes no operating current

ADLOOP7:
PAUSE 5
If ADCON0.1 = 1 Then GOTO ADLOOP7 'Wait for low on bit-1 of ADCON0, conversion finished

ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
ANALOG.LOWBYTE = ADRESL 'LOW byte of result
TEMPLONG1=ANALOG*100
TEMPLONG2=TEMPLONG1/1023
POTMIN3 = TEMPLONG2
;................................................. .................................................. .....................
'read POTMIN4 on AN21 = RD1 pin 20
ADCON0 = %01010111
' 0 bit 7 Unimplemented: Read as ‘0’
' .10101 = AN21
' ......1 bit 1 GO/DONE: A/D Conversion Status bit
' 1 = A/D conversion cycle in progress
' Setting this bit starts an A/D conversion cycle.
' This bit is automatically cleared by hardware when
' the A/D conversion has completed.
' 0 = A/D conversion completed/not in progress
' .......1 bit 0 ADON: ADC Enable bit
' 1 = ADC is enabled
' 0 = ADC is disabled and consumes no operating current

ADLOOP8:
PAUSE 5
If ADCON0.1 = 1 Then GOTO ADLOOP8 'Wait for low on bit-1 of ADCON0, conversion finished

ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
ANALOG.LOWBYTE = ADRESL 'LOW byte of result
TEMPLONG1=ANALOG*100
TEMPLONG2=TEMPLONG1/1023
POTMIN4 = TEMPLONG2
;................................................. .................................................. .....................
'read POTMAX1 on AN22 = RD2 pin 21
ADCON0 = %01011011
' 0 bit 7 Unimplemented: Read as ‘0’
' .10110 = AN22
' ......1 bit 1 GO/DONE: A/D Conversion Status bit
' 1 = A/D conversion cycle in progress
' Setting this bit starts an A/D conversion cycle.
' This bit is automatically cleared by hardware when
' the A/D conversion has completed.
' 0 = A/D conversion completed/not in progress
' .......1 bit 0 ADON: ADC Enable bit
' 1 = ADC is enabled
' 0 = ADC is disabled and consumes no operating current

ADLOOP9:
PAUSE 5
If ADCON0.1 = 1 Then GOTO ADLOOP9 'Wait for low on bit-1 of ADCON0, conversion finished

ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
ANALOG.LOWBYTE = ADRESL 'LOW byte of result
TEMPLONG1=ANALOG*100
TEMPLONG2=TEMPLONG1/1023
POTMAX1 = TEMPLONG2

GOSUB CHARRECEIVED
;................................................. .................................................. .....................
'read POTMAX2 on AN23 = RD3 pin 22
ADCON0 = %01011111
' 0 bit 7 Unimplemented: Read as ‘0’
' .10111 = AN23
' ......1 bit 1 GO/DONE: A/D Conversion Status bit
' 1 = A/D conversion cycle in progress
' Setting this bit starts an A/D conversion cycle.
' This bit is automatically cleared by hardware when
' the A/D conversion has completed.
' 0 = A/D conversion completed/not in progress
' .......1 bit 0 ADON: ADC Enable bit
' 1 = ADC is enabled
' 0 = ADC is disabled and consumes no operating current

ADLOOP10:
PAUSE 5
If ADCON0.1 = 1 Then GOTO ADLOOP10 'Wait for low on bit-1 of ADCON0, conversion finished

ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
ANALOG.LOWBYTE = ADRESL 'LOW byte of result
TEMPLONG1=ANALOG*100
TEMPLONG2=TEMPLONG1/1023
POTMAX2 = TEMPLONG2
;................................................. .................................................. .....................
'read POTMAX3 on AN24 = RD4 pin 27
ADCON0 = %01100011
' 0 bit 7 Unimplemented: Read as ‘0’
' .11000 = AN24
' ......1 bit 1 GO/DONE: A/D Conversion Status bit
' 1 = A/D conversion cycle in progress
' Setting this bit starts an A/D conversion cycle.
' This bit is automatically cleared by hardware when
' the A/D conversion has completed.
' 0 = A/D conversion completed/not in progress
' .......1 bit 0 ADON: ADC Enable bit
' 1 = ADC is enabled
' 0 = ADC is disabled and consumes no operating current

ADLOOP11:
PAUSE 5
If ADCON0.1 = 1 Then GOTO ADLOOP11 'Wait for low on bit-1 of ADCON0, conversion finished

ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
ANALOG.LOWBYTE = ADRESL 'LOW byte of result
TEMPLONG1=ANALOG*100
TEMPLONG2=TEMPLONG1/1023
POTMAX3 = TEMPLONG2
;................................................. .................................................. .....................
'read POTMAX4 on AN25 = RD5 pin 28
ADCON0 = %01100111
' 0 bit 7 Unimplemented: Read as ‘0’
' .11001 = AN25
' ......1 bit 1 GO/DONE: A/D Conversion Status bit
' 1 = A/D conversion cycle in progress
' Setting this bit starts an A/D conversion cycle.
' This bit is automatically cleared by hardware when
' the A/D conversion has completed.
' 0 = A/D conversion completed/not in progress
' .......1 bit 0 ADON: ADC Enable bit
' 1 = ADC is enabled
' 0 = ADC is disabled and consumes no operating current

ADLOOP12:
PAUSE 5
If ADCON0.1 = 1 Then GOTO ADLOOP12 'Wait for low on bit-1 of ADCON0, conversion finished

ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
ANALOG.LOWBYTE = ADRESL 'LOW byte of result
TEMPLONG1=ANALOG*100
TEMPLONG2=TEMPLONG1/1023
POTMAX4 = TEMPLONG2

LATE.2 = 0

GOTO MAINLOOP
'------------------------------------------------------------------------------------------------------------------------
TEST1:
RETURN
'------------------------------------------------------------------------------------------------------------------------
;here a character was received via RS232
CHARRECEIVED:
IF RS232RECD = 0 THEN RETURN

'enter CAL mode?
IF RS232RECD = "A" THEN

INPUTS.9 = 1 'set flag to in cal mode

EXITCAL = 0

If CALBYTE.0 = 1 THEN
ANALOGOUT1 = ANALOGCAL1
ELSE
ANALOGOUT1 = 2540
ENDIF

If CALBYTE.1 = 1 THEN
ANALOGOUT2 = ANALOGCAL2
ELSE
ANALOGOUT2 = 2540
ENDIF

If CALBYTE.2 = 1 THEN
ANALOGOUT3 = ANALOGCAL3
ELSE
ANALOGOUT3 = 2540
ENDIF

If CALBYTE.3 = 1 THEN
ANALOGOUT4 = ANALOGCAL4
ELSE
ANALOGOUT4 = 2540
ENDIF

RETURN
ENDIF

'increment analogout1 in cal mode?
IF RS232RECD = "B" AND INPUTS.9 = 1 THEN
ANALOGOUT1 = ANALOGOUT1 + 1
IF ANALOGOUT1 > 2740 THEN ANALOGOUT1 = 2740
IF ANALOGOUT1 < 2340 THEN ANALOGOUT1 = 2340
RETURN
ENDIF

'decrement analogout1 in cal mode?
IF RS232RECD = "b" AND INPUTS.9 = 1 THEN
ANALOGOUT1 = ANALOGOUT1 - 1
IF ANALOGOUT1 > 2740 THEN ANALOGOUT1 = 2740
IF ANALOGOUT1 < 2340 THEN ANALOGOUT1 = 2340
RETURN
ENDIF

'increment analogout2 in cal mode?
IF RS232RECD = "C" AND INPUTS.9 = 1 THEN
ANALOGOUT2 = ANALOGOUT2 + 1
IF ANALOGOUT2 > 2740 THEN ANALOGOUT2 = 2740
IF ANALOGOUT2 < 2340 THEN ANALOGOUT2 = 2340
RETURN
ENDIF

'decrement analogout2 in cal mode?
IF RS232RECD = "c" AND INPUTS.9 = 1 THEN
ANALOGOUT2 = ANALOGOUT2 - 1
IF ANALOGOUT2 > 2740 THEN ANALOGOUT2 = 2740
IF ANALOGOUT2 < 2340 THEN ANALOGOUT2 = 2340
RETURN
ENDIF

'increment analogout3 in cal mode?
IF RS232RECD = "D" AND INPUTS.9 = 1 THEN
ANALOGOUT3 = ANALOGOUT3 + 1
IF ANALOGOUT3 > 2740 THEN ANALOGOUT3 = 2740
IF ANALOGOUT3 < 2340 THEN ANALOGOUT3 = 2340
RETURN
ENDIF

'decrement analogout3 in cal mode?
IF RS232RECD = "d" AND INPUTS.9 = 1 THEN
ANALOGOUT3 = ANALOGOUT3 - 1
IF ANALOGOUT3 > 2740 THEN ANALOGOUT3 = 2740
IF ANALOGOUT3 < 2340 THEN ANALOGOUT3 = 2340
RETURN
ENDIF

'increment analogout4 in cal mode?
IF RS232RECD = "E" AND INPUTS.9 = 1 THEN
ANALOGOUT4 = ANALOGOUT4 + 1
IF ANALOGOUT4 > 2740 THEN ANALOGOUT4 = 2740
IF ANALOGOUT4 < 2340 THEN ANALOGOUT4 = 2340
RETURN
ENDIF

'decrement analogout4 in cal mode?
IF RS232RECD = "e" AND INPUTS.9 = 1 THEN
ANALOGOUT4 = ANALOGOUT4 - 1
IF ANALOGOUT4 > 2740 THEN ANALOGOUT4 = 2740
IF ANALOGOUT4 < 2340 THEN ANALOGOUT4 = 2340
RETURN
ENDIF

'increment zone3 in cal mode?
IF RS232RECD = "F" AND INPUTS.9 = 1 THEN
ZONE3 = ZONE3 + 1
IF ZONE3 > 100 THEN ZONE3 = 100
IF ZONE3 < ZONE2+5 THEN ZONE3 = ZONE2+5
RETURN
ENDIF

'decrement zone3 in cal mode?
IF RS232RECD = "f" AND INPUTS.9 = 1 THEN
ZONE3 = ZONE3 - 1
IF ZONE3 > 100 THEN ZONE3 = 100
IF ZONE3 < ZONE2+5 THEN ZONE3 = ZONE2+5
RETURN
ENDIF

'increment zone2 in cal mode?
IF RS232RECD = "G" AND INPUTS.9 = 1 THEN
ZONE2 = ZONE2 + 1
IF ZONE2 > ZONE3-5 THEN ZONE2 = ZONE3-5
IF ZONE2 < ZONE1+5 THEN ZONE2 = ZONE1+5
RETURN
ENDIF

'decrement zone2 in cal mode?
IF RS232RECD = "g" AND INPUTS.9 = 1 THEN
ZONE2 = ZONE2 - 1
IF ZONE2 > ZONE3-5 THEN ZONE2 = ZONE3-5
IF ZONE2 < ZONE1+5 THEN ZONE2 = ZONE1+5
RETURN
ENDIF

'increment zone1 in cal mode?
IF RS232RECD = "H" AND INPUTS.9 = 1 THEN
ZONE1 = ZONE1 + 1
IF ZONE1 > ZONE2-5 THEN ZONE1 = ZONE2-5
IF ZONE1 < 5 THEN ZONE1 = 5
RETURN
ENDIF

'decrement zone1 in cal mode?
IF RS232RECD = "h" AND INPUTS.9 = 1 THEN
ZONE1 = ZONE1 - 1
IF ZONE1 > ZONE2-5 THEN ZONE1 = ZONE2-5
IF ZONE1 < 5 THEN ZONE1 = 5
RETURN
ENDIF

'increment time hysteresis in cal mode?
IF RS232RECD = "I" AND INPUTS.9 = 1 THEN
TIMEHYS = TIMEHYS + 1
IF TIMEHYS > 300 THEN TIMEHYS = 300
IF TIMEHYS < 1 THEN TIMEHYS = 1
RETURN
ENDIF

'decrement time hysteresis in cal mode?
IF RS232RECD = "i" AND INPUTS.9 = 1 THEN
TIMEHYS = TIMEHYS - 1
IF TIMEHYS > 300 THEN TIMEHYS = 300
IF TIMEHYS < 1 THEN TIMEHYS = 1
RETURN
ENDIF

'exit cal mode?
IF RS232RECD = "Z" AND INPUTS.9 = 1 THEN
EXITCAL = 1
RETURN
ENDIF

RETURN
'------------------------------------------------------------------------------------------------------------------------
TEST2:
RETURN
'------------------------------------------------------------------------------------------------------------------------
'analog output 1 DAC1-A
SETANALOG1:

CSDAC1 = 0

DACBUFFER= ANALOGOUT1
DACBUFFER.15 = 0 'bit 15 1=Write to DACb 0=Write to DACa
DACBUFFER.14 = 0 'bit 14 VREF Input Buffer Control bit 1=Buffered 0=Unbuffered
DACBUFFER.13 = 1 'bit 13 GA: Output Gain Selection bit 1=1x 0=2x
DACBUFFER.12 = 1 'bit 12 SHDN: Output Shutdown Control bit 1=VOUT is available 0=Shutdown

SPI_BUFFER = DACBUFFER.HIGHBYTE
SP_INT_FLAG = 0
WHILE SP_INT_FLAG = 0 : WEND

SPI_BUFFER = DACBUFFER.LOWBYTE
SP_INT_FLAG = 0
WHILE SP_INT_FLAG = 0 : WEND

CSDAC1 = 1 ;disable DAC0

RETURN
'------------------------------------------------------------------------------------------------------------------------
'analog output 2 DAC1-B
SETANALOG2:

CSDAC1 = 0 'enable DAC chip1

DACBUFFER= ANALOGOUT2
DACBUFFER.15 = 1 'bit 15 1=Write to DACb 0=Write to DACa
DACBUFFER.14 = 0 'bit 14 VREF Input Buffer Control bit 1=Buffered 0=Unbuffered
DACBUFFER.13 = 1 'bit 13 GA: Output Gain Selection bit 1=1x 0=2x
DACBUFFER.12 = 1 'bit 12 SHDN: Output Shutdown Control bit 1=VOUT is available 0=Shutdown

SPI_BUFFER = DACBUFFER.HIGHBYTE
SP_INT_FLAG = 0
WHILE SP_INT_FLAG = 0 : WEND

SPI_BUFFER = DACBUFFER.LOWBYTE
SP_INT_FLAG = 0
WHILE SP_INT_FLAG = 0 : WEND

CSDAC1 = 1 ;disable DAC chip1

RETURN

END

MarkEngineer
- 1st December 2014, 14:32
OK Without changing any code I got the program to work. All I did was rearrange the subroutines. Is it possible that one of the subroutines was at a code page boundary?

Demon
- 1st December 2014, 15:59
I'm not familiar with this routine at the bottom, but won't this run forever or does an interrupt engage?


SP_INT_FLAG = 0
WHILE SP_INT_FLAG = 0 : WEND

Robert

MarkEngineer
- 2nd December 2014, 13:17
That code is writing to a Microchip MCP4922 DAC on the SPI bus.
SP_INT_FLAG VAR PIR1.3 which is SSP1IF indicating the SPI write was completed by the micro.

I suppose it could be an infinite loop if the micro fails to write to the SPI bus, but unlikely.