Things are working, kinda
Here is my latest code. All this really does is check for switches and disable drives, and shift PORTa to PORTc every 5 uS. It also sends a servo pulse out every 20mS with a pulse time sweeping from 1-2 ms just for testing purposes.
Right now, everything seems to work, but I need to remove the RED line from the interupt. When I comment it out, it seems to hang in the interupt and never leave. Uncomment and it works again. I have been struggling with this for a week, so I figured I would just ask and get the answer.
Code:
' Name : Interface card.pbp
' Compiler : PICBASIC PRO Compiler 2.6A
' Assembler : MPASM
' Target PIC : 16F1947
' Hardware : PIMill Interface
' Oscillator : internal
' Keywords :
' Description : PICBASIC PRO program to interface parallel port
' to 4 stepper drives and limit switches
'
'
'
'
' Configure ports
'
'
ANSELA = %00000000 'port A all digital
ANSELE = %00000000 'port E all digital
ANSELF = %00000000 'port F all digital
ANSELG = %00000000 'port G all digital
CM1CON0 = %00000000 'No comparaters
CM1CON1 = %00000000
CM2CON0 = %00000000
CM2CON1 = %00000000
' preload latches before setting direction
LATB = %00000000
LATC = %00000000
LATD = %00010000 'LED's 0 for red, 1 FOR GREEN should start red
LATF = %00001111 ' low nibble is drive enable. 1 disables
LATG = %00000000
' I/O direction
TRISA = %11111111'step and dir inputs
TRISB = %11000001'7-0 icsp,icsp,h4o,h3o,h2o,h1o,estopO,enable In
TRISC = %00000000'step and dir outputs
TRISD = %00000000'led6,i2c,i2c,led5,led4,led3,led2,led1
TRISE = %11111111'ls4,lsh4.ls3,lsh3,ls2,lsh2,ls1,lsh1
TRISF = %00010000'spindle dir,servo out,dac out,flood input,4en,3en,2en,1en
TRISG = %11100111'x,x,icsp/mclr,rly2,rly1,Rx2,Tx2,DI
'REMOVE THIS LINE IF NOT SETTING THE CONFIGS IN CODE SPACE
@ __config _CONFIG1,_FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
@ __config _CONFIG2,_WRT_OFF & _VCAPEN_OFF & _PLLEN_ON & _STVREN_OFF & _BORV_25 & _LVP_OFF
'Internal osc setup
OSCCON = %11110000 'clock is 8 meg. turn on PLL for 32 meg clock
DEFINE OSC 32
'Variables
LED0 VAR PORTD.0 ' Assign name "LED" to PORTD
LED1 VAR PORTD.1
LED2 VAR PORTD.2
LED3 VAR PORTD.3
LED4 VAR PORTD.4
LED5 VAR PORTD.7
SERVO VAR PORTF.6
CNT VAR BYTE
MYFLAGS VAR BYTE
COUNTUP VAR MYFLAGS.0
COUNTDN VAR MYFLAGS.1
MS VAR MYFLAGS.2
ENALL VAR PORTB.0
TEMPF VAR BYTE
FRAMECOUNT VAR BYTE
POS VAR BYTE
EN1 VAR PORTF.0
EN2 VAR PORTF.1
EN3 VAR PORTF.2
EN4 VAR PORTF.3
COUNTUP = 1
COUNTDN = 0
POS = 1
FRAMECOUNT = 0
MS = 0
CNT = 0
'5.0 uSec OR 200,000 Hz INTERRUPTS
'PRELOAD 39 PR = NUMBER OF CYCLES-1
'INT HANDLER COMPLIMENTS OF DARREL TAYLOR
PRELOAD VAR byte
PRELOAD = 39 ' FROM TESTING TO FIND THE RIGHT NUMBER
PR2 = PRELOAD
PIE1.1 = 1 ; Enable Timer2 interrupts
INTCON.6 = 1 ; enable PEIE
INTCON.7 = 1 ; enable GIE
T2CON = %00000100 ; Start Timer2
DEFINE INTHAND _FiveMicroSec
'---[TMR2 - interrupt handler]--------------------------------------------------
FiveMicroSec:
LATF = LATF ^ 1 ; TOGGLE EN1
CNT =CNT+1
PORTC = PORTA
PIR1.1 = 0 ; clear the interrupt flag
@ NOP
@ RETFIE
Main: 'DO WHATEVER YOU WANT HERE
IF ENALL = 0 THEN
GOTO NOTREADY
ELSE
GOTO READY
ENDIF
READYRETURN:
IF CNT >= 200 THEN
' TOGGLE EN2
TOGGLE LED5
CNT=0
FRAMECOUNT = FRAMECOUNT + 1
MS = 1
ENDIF
IF FRAMECOUNT >=20 THEN
FRAMECOUNT = 0
MS=0
HIGH SERVO
IF COUNTUP THEN POS = POS + 1
IF COUNTDN THEN POS = POS - 1
ENDIF
' TOGGLE LED2
IF PORTE != $FF THEN SWITCHHIT
GOTO SERVOCHECK
GOTO Main
SERVOCHECK:
IF MS =1 THEN
IF CNT >= POS THEN
LOW SERVO
MS =0
IF (COUNTUP = 1) AND (POS=199) THEN
COUNTUP = 0
COUNTDN = 1
ELSE
IF POS = 1 THEN
COUNTUP = 1
COUNTDN = 0
ENDIF
ENDIF
ENDIF
ENDIF
GOTO MAIN
SWITCHHIT:
PORTF = PORTF | $0F
IF (PORTE = 253) OR (PORTE = 254) THEN LED0 = 0
IF (PORTE = 247) OR (PORTE = 251) THEN LED1 = 0
IF (PORTE = 223) OR (PORTE = 239) THEN LED2 = 0
IF (PORTE = 127) OR (PORTE = 191) THEN LED3 = 0
' ELSE PORTE = PORTE |$0F
GOTO MAIN
NOTREADY:
PORTD = PORTD & $F0
PORTF = PORTF | $0F
IF ENALL = 0 THEN NOTREADY
PORTD = PORTD | $0F
PORTF = PORTF & $F0
GOTO MAIN
READY:
PORTF = PORTF & $F0
PORTD = PORTD | $0F
GOTO READYRETURN
I think I found the problem
I think I have found the problem with interupt. When the interupt hangs and won't leave, it seems BSR=5, when this happens PIR1.1 doesn't get cleared so it just re-enters the int. So the question is, why doesn't PBP make sure the BSR=0 before it tries to PIR1.1=0?
Or the bigger question is why does it work for Darrel???
I am posting the program as it is right now, I am using MPLAB, chooseing MPLAB SIM from the debugger menu. then choose the >> not > to animate the program. With this you can see it enter the interupt and leave. I left it running for about 30 min without issue. rem the LAT line and instant hang. sometimes it takes a few times through to get stuck.
PLEASE, can I get a few people to try this so at least I will know I am not going crazy!!
Code:
' Name : Interface card.pbp
' Compiler : PICBASIC PRO Compiler 2.6A
' Assembler : MPASM
' Target PIC : 16F1947
' Hardware : PIMill Interface
' Oscillator : internal
' Keywords :
' Description : PICBASIC PRO program to interface parallel port
' to 4 stepper drives and limit switches
'
'
'
'
' Configure ports
'
'
ANSELA = %00000000 'port A all digital
ANSELE = %00000000 'port E all digital
ANSELF = %00000000 'port F all digital
ANSELG = %00000000 'port G all digital
CM1CON0 = %00000000 'No comparaters
CM1CON1 = %00000000
CM2CON0 = %00000000
CM2CON1 = %00000000
' preload latches before setting direction
LATB = %00000000
LATC = %00000000
LATD = %00010000 'LED's 0 for red, 1 FOR GREEN should start red
LATF = %00001111 ' low nibble is drive enable. 1 disables
LATG = %00000000
' I/O direction
TRISA = %11111111'step and dir inputs
TRISB = %11000001'7-0 icsp,icsp,h4o,h3o,h2o,h1o,estopO,enable In
TRISC = %00000000'step and dir outputs
TRISD = %00000000'led6,i2c,i2c,led5,led4,led3,led2,led1
TRISE = %11111111'ls4,lsh4.ls3,lsh3,ls2,lsh2,ls1,lsh1
TRISF = %10010000'manual ready,servo out,dac out,flood input,4en,3en,2en,1en
TRISG = %11100111'x,x,icsp/mclr,rly2,rly1,Rx2,Tx2,SPINDLE ON
'REMOVE THIS LINE IF NOT SETTING THE CONFIGS IN CODE SPACE
@ __config _CONFIG1,_FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
@ __config _CONFIG2,_WRT_OFF & _VCAPEN_OFF & _PLLEN_ON & _STVREN_OFF & _BORV_25 & _LVP_OFF
'Internal osc setup
OSCCON = %11110000 'clock is 8 meg. turn on PLL for 32 meg clock
DEFINE OSC 32
DEFINE NO_CLRWDT 1
'Variables
'Port assignments
'------------------port B
ENALL VAR PORTB.0
ESTOPO VAR PORTB.1
HO1 VAR PORTB.2
HO2 VAR PORTB.3
HO3 VAR PORTB.4
HO4 VAR PORTB.5
'------------------port D
LED0 VAR PORTD.0
LED1 VAR PORTD.1
LED2 VAR PORTD.2
LED3 VAR PORTD.3
LED4 VAR PORTD.4
LED5 VAR PORTD.7
'------------------port F
EN1 VAR PORTF.0
EN2 VAR PORTF.1
EN3 VAR PORTF.2
EN4 VAR PORTF.3
DIGIN VAR PORTF.5
SERVO VAR PORTF.6
MANREADY VAR PORTF.7
'------------------port G
SPINON VAR PORTG.0
RLY1 VAR PORTG.3
RLY2 VAR PORTG.4
'---------------------Bytes
CNT VAR BYTE
FRAMECT VAR BYTE
POS VAR BYTE
MYFLAGS VAR BYTE
PRELOAD VAR BYTE
SPEED VAR BYTE
DUMRUN VAR BYTE
'---------------------Bits
COUNTUP VAR MYFLAGS.0
COUNTDN VAR MYFLAGS.1
MS VAR MYFLAGS.2
LIMIT VAR MYFLAGS.3
DRIVEON VAR MYFLAGS.4
HOMED VAR MYFLAGS.5
'---------------------INIT VARIABLE VALUE
COUNTUP = 1
COUNTDN = 0
POS = 127
FRAMECT = 0
MS = 0
HOMED = 0
CNT = 0
SPEED = 0
PRELOAD = 39 'PRELOAD 39 PR = NUMBER OF CYCLES-1
'5.0 uSec OR 200,000 Hz INTERRUPTS
'INT HANDLER COMPLIMENTS OF DARREL TAYLOR
PR2 = PRELOAD
PIE1.1 = 1 ; Enable Timer2 interrupts
INTCON.6 = 1 ; enable PEIE
INTCON.7 = 1 ; enable GIE
T2CON = %00000100 ; Start Timer2
DEFINE INTHAND _FiveMicroSec
GOTO START
START:
GOSUB NOTREADY
Main: 'DO WHATEVER YOU WANT HERE
IF DRIVEON = 0 THEN
GOSUB CHECKREADY
ENDIF
IF (ENALL = 0) AND (DRIVEON = 1) THEN
GOSUB NOTREADY
ENDIF
IF (MANREADY = 0) AND (DRIVEON = 1) THEN
GOSUB NOTREADY
ENDIF
IF (LIMIT = 1) AND (PORTE = $FF) THEN
GOSUB READY
ENDIF
IF SPINON THEN
SPEED=POS
RLY1 = 1
ELSE
SPEED = 0
RLY1 = 0
ENDIF
IF DIGIN THEN
RLY2 = 1
ELSE
RLY2 = 0
ENDIF
READYRETURN:
IF CNT >= 200 THEN
TOGGLE LED5
CNT=0
FRAMECT = FRAMECT + 1
MS = 1
ENDIF
IF FRAMECT >=20 THEN
FRAMECT = 0
MS=0
HIGH SERVO
ENDIF
IF PORTE != $FF THEN
GOSUB SWITCHHIT
ENDIF
GOSUB SERVOCHECK
GOTO Main
SERVOCHECK:
IF MS =1 THEN
IF CNT >= SPEED THEN
LOW SERVO
MS =0
ENDIF
ENDIF
RETURN
SWITCHHIT:
IF HOMED=0 THEN
GOTO HOMESWITCH
ENDIF
ESTOPO = 1
PORTF = PORTF | $0F
IF (PORTE = 253) OR (PORTE = 254) THEN LED0 = 0
IF (PORTE = 247) OR (PORTE = 251) THEN LED1 = 0
IF (PORTE = 223) OR (PORTE = 239) THEN LED2 = 0
IF (PORTE = 127) OR (PORTE = 191) THEN LED3 = 0
LIMIT = 1
DRIVEON = 0
RETURN
HOMESWITCH:
IF PORTE = 253 THEN HO1=1
IF PORTE = 247 THEN HO2=1
IF PORTE = 223 THEN HO3=1
IF PORTE = 127 THEN HO4=1
IF PORTE = 85 THEN HOMED = 1
RETURN
NOTREADY:
PORTD = PORTD & $F0
PORTF = PORTF | $0F
DRIVEON = 0
HOMED = 0
RETURN
CHECKREADY:
IF ENALL = 0 THEN RETURN
IF MANREADY = 0 THEN RETURN
IF LIMIT = 1 THEN RETURN
READY:
PORTD = PORTD | $0F
PORTF = PORTF & $F0
DRIVEON = 1
LIMIT = 0
RETURN
'---[TMR2 - interrupt handler]--------------------------------------------------
FiveMicroSec:
LATF = LATF ^ 32 ; TOGGLE DAC
CNT =CNT+1
PORTC = PORTA
PIR1.1 = 0 ; clear the interrupt flag
@ RETFIE