I am facing an error when I try to make a hex file from asm with 16f628 microcontroller.
Althought the hex is compiled directly from the bas file, when I try to built the asm file, I get the
error: Chip model not specified! GCBASIC cannot continue.
Now, I don't want to built the bas file direclty because there is probably some bug with the registers' addresses that the compiler designates, and some addresses overlap, so I want to correct them and then build the corrected assembly file.
Has anybody faced the same problem?
Thanks in advance for any help.
Nikolas
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you. I am glad to be here.
The code is about 1,2k. I quote it bellow.
As you can see there are a lot of overlapping registers and that cause the program to run unexpectably at some points.
As far as it concern the format, I tried to format the code as in MPLAB, i.e. no # before include or without the brackets, but I get the saem error.
;Program compiled by Great Cow BASIC (0.9 11/5/2014)
;Need help? See the GCBASIC forums at http://sourceforge.net/projects/gcbasic/forums,
;check the documentation or email w_cholmondeley at users dot sourceforge dot net.
;********************************************************************************
;Set up the assembler options (Chip type, clock source, other bits and pieces)
LIST p=16F628, r=DEC
include <P16F628.inc>
__CONFIG _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON
;********************************************************************************
;Set aside memory locations for variables
DELAYTEMP EQU 112
DELAYTEMP2 EQU 113
SYSDIVMULTA EQU 119
SYSDIVMULTA_H EQU 120
SYSDIVMULTB EQU 123
SYSDIVMULTB_H EQU 124
SYSDIVMULTX EQU 114
SYSDIVMULTX_H EQU 115
SysBYTETempA EQU 117
SysBYTETempB EQU 121
SysByteTempX EQU 112
SysDivLoop EQU 116
SysSTATUS EQU 127
SysW EQU 126
SysWORDTempA EQU 117
SysWORDTempA_H EQU 118
SysWORDTempB EQU 121
SysWORDTempB_H EQU 122
SysWORDTempX EQU 112
SysWORDTempX_H EQU 113
SysWaitTempMS EQU 114
SysWaitTempMS_H EQU 115
SysWaitTempUS EQU 117
SysWaitTempUS_H EQU 118
ADD_REG EQU 32
DATA1 EQU 33
DATA2 EQU 34
DATA3 EQU 35
DATA4 EQU 36
DATA5 EQU 37
DATA_COUNT EQU 38
HSERRECEIVE EQU 39
INDEX EQU 40
POSITION EQU 41
POSITION_H EQU 42
POSITION1 EQU 43
POSITION2 EQU 44
POSITION3 EQU 45
POSITION4 EQU 46
POSITION5 EQU 47
POSITION_A EQU 48
POSITION_B EQU 49
POSITION_C EQU 50
POSITION_D EQU 51
RS232_BUFFER EQU 52
SERDATA EQU 53
SYSBITVAR0 EQU 54
SYSREPEATTEMP1 EQU 55
SYSREPEATTEMP1_H EQU 56
SYSREPEATTEMP2 EQU 57
SYSREPEATTEMP2_H EQU 58
SaveDelayTemp2 EQU 59
SavePCLATH EQU 60
SaveSysByteTempA EQU 61
SaveSysByteTempB EQU 62
SaveSysByteTempX EQU 63
SaveSysTemp1 EQU 64
SaveSysTemp2 EQU 65
SaveSysTemp3 EQU 66
SaveSysTemp4 EQU 67
SaveSysTemp5 EQU 68
SaveSysWaitTempMS EQU 69
SaveSysWaitTempMS_H EQU 70
SysIntOffCount EQU 71
SysTemp1 EQU 74
SysTemp1_H EQU 75
SysTemp2 EQU 76
SysTemp3 EQU 77
SysTemp4 EQU 78
SysTemp5 EQU 79
SysTemp5_H EQU 80
TEMP EQU 81
TEMP_H EQU 82
TMR0PRES EQU 83
TMR0SOURCE EQU 84
;********************************************************************************
;Vectors
ORG 0
goto BASPROGRAMSTART
ORG 4
Interrupt
;********************************************************************************
;Save Context
movwf SysW
swapf STATUS,W
movwf SysSTATUS
banksel STATUS
incf SysIntOffCount,F
;Store system variables
movf SysWaitTempMS,W
movwf SaveSysWaitTempMS
movf SysWaitTempMS_H,W
movwf SaveSysWaitTempMS_H
movf SysByteTempX,W
movwf SaveSysByteTempX
movf SysTemp2,W
movwf SaveSysTemp2
movf SysByteTempA,W
movwf SaveSysByteTempA
movf SysByteTempB,W
movwf SaveSysByteTempB
movf SysTemp3,W
movwf SaveSysTemp3
movf SysTemp4,W
movwf SaveSysTemp4
movf SysTemp1,W
movwf SaveSysTemp1
movf SysTemp5,W
movwf SaveSysTemp5
movf DelayTemp2,W
movwf SaveDelayTemp2
movf PCLATH,W
movwf SavePCLATH
clrf PCLATH
;On Interrupt handlers
banksel PIE1
btfss PIE1,RCIE
goto NotRCIF
banksel PIR1
btfss PIR1,RCIF
goto NotRCIF
call RS232_IN
bcf PIR1,RCIF
goto INTERRUPTDONE
NotRCIF
btfss INTCON,T0IE
goto NotT0IF
btfss INTCON,T0IF
goto NotT0IF
banksel STATUS
call MOTOR_JAM
bcf INTCON,T0IF
goto INTERRUPTDONE
NotT0IF
;User Interrupt routine
INTERRUPTDONE
;Restore Context
;Restore system variables
banksel SAVESYSWAITTEMPMS
movf SaveSysWaitTempMS,W
movwf SysWaitTempMS
movf SaveSysWaitTempMS_H,W
movwf SysWaitTempMS_H
movf SaveSysByteTempX,W
movwf SysByteTempX
movf SaveSysTemp2,W
movwf SysTemp2
movf SaveSysByteTempA,W
movwf SysByteTempA
movf SaveSysByteTempB,W
movwf SysByteTempB
movf SaveSysTemp3,W
movwf SysTemp3
movf SaveSysTemp4,W
movwf SysTemp4
movf SaveSysTemp1,W
movwf SysTemp1
movf SaveSysTemp5,W
movwf SysTemp5
movf SaveDelayTemp2,W
movwf DelayTemp2
movf SavePCLATH,W
movwf PCLATH
clrf SysIntOffCount
swapf SysSTATUS,W
movwf STATUS
swapf SysW,F
swapf SysW,W
retfie
;********************************************************************************
;Start of program memory page 0
ORG 88
BASPROGRAMSTART
;Call initialisation routines
call INITSYS
call INITUSART
;Enable interrupts
bsf INTCON,GIE
bsf INTCON,PEIE
clrf SysIntOffCount
;Automatic pin direction setting
banksel TRISB
bsf TRISB,7
bcf TRISB,3
bsf TRISB,0
bcf TRISA,4
;Start of the main program
;#DEFINE CTS PORTB.3
;#DEFINE CTS_Z PORTA.5
;DIM X_REG AS BIT
;DIM HOME_FLAG AS BIT
;DIM MOVE_FLAG AS BIT
;DIM SIGN AS BIT
;DIM EMERG_FLAG AS BIT
;DIM DATA5 AS BYTE
;DIM DATA4 AS BYTE
;DIM DATA3 AS BYTE
;DIM DATA2 AS BYTE
;DIM DATA1 AS BYTE
;DIM POSITION AS WORD
;DIM POSITION1 AS BYTE
;DIM POSITION2 AS BYTE
;DIM POSITION3 AS BYTE
;DIM POSITION4 AS BYTE
;DIM POSITION5 AS BYTE
;DIM INDEX AS BYTE
;DIM RS232_BUFFER AS BYTE
;DIM ADD_REG AS BYTE
;DIM TEMP AS WORD
;DIM POSITION_A AS BYTE
;DIM POSITION_B AS BYTE
;DIM POSITION_C AS BYTE
;DIM POSITION_D AS BYTE
;DIM DATA_COUNT AS BYTE
;ADD_REG=252
movlw 252
banksel ADD_REG
movwf ADD_REG
;SET X_REG OFF
bcf SYSBITVAR0,0
;DATA_COUNT=0X00
clrf DATA_COUNT
;DATA3=0X00
clrf DATA3
;DATA2=0X00
clrf DATA2
;DATA1=0X00
clrf DATA1
;TRISA= 0B11100000
movlw 224
banksel TRISA
movwf TRISA
;TRISB= 0B11110011
movlw 243
movwf TRISB
;PORTA=0B00000000
banksel PORTA
clrf PORTA
;PORTB=0B00000000
clrf PORTB
;SET HOME_FLAG OFF
bcf SYSBITVAR0,1
;SET MOVE_FLAG OFF
bcf SYSBITVAR0,2
;SET EMERG_FLAG OFF
bcf SYSBITVAR0,4
;DO UNTIL PORTB.0=0
SysDoLoop_S1
btfss PORTB,0
goto SysDoLoop_E1
;LOOP
goto SysDoLoop_S1
SysDoLoop_E1
;WAIT 100 MS
movlw 100
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;DO UNTIL PORTB.0=1
SysDoLoop_S2
btfsc PORTB,0
goto SysDoLoop_E2
;LOOP
goto SysDoLoop_S2
SysDoLoop_E2
;#DEFINE USART_BAUD_RATE 9600
;ON INTERRUPT USARTRX1READY CALL RS232_IN
banksel PIE1
bsf PIE1,RCIE
;INITTIMER0 OSC, PS0_256
movlw 1
banksel TMR0SOURCE
movwf TMR0SOURCE
movlw 7
movwf TMR0PRES
call INITTIMER0
;ON INTERRUPT TIMER0OVERFLOW CALL MOTOR_JAM
bsf INTCON,T0IE
;SET PORTA.4 OFF
bcf PORTA,4
;SET CTS OFF
bcf PORTB,3
MAIN
;IF MOVE_FLAG=0 AND CTS_Z=1 THEN
clrf SysByteTempX
btfss SYSBITVAR0,2
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp1
clrf SysByteTempX
btfsc PORTA,5
comf SysByteTempX,F
movf SysTemp1,W
andwf SysByteTempX,W
movwf SysTemp2
btfsc SysTemp2,0
;SET CTS ON
bsf PORTB,3
;END IF
;IF MOVE_FLAG=0 AND CTS_Z=0 THEN
clrf SysByteTempX
btfss SYSBITVAR0,2
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp1
clrf SysByteTempX
btfss PORTA,5
comf SysByteTempX,F
movf SysTemp1,W
andwf SysByteTempX,W
movwf SysTemp2
btfss SysTemp2,0
goto ENDIF2
;WAIT 1 MS
movlw 1
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;SET CTS OFF
bcf PORTB,3
;END IF
ENDIF2
;IF HOME_FLAG=1 THEN
btfsc SYSBITVAR0,1
;CALL HOME
call HOME
;END IF
;IF MOVE_FLAG=1 THEN
btfsc SYSBITVAR0,2
;CALL MOVE
call MOVE
;END IF
;IF EMERG_FLAG=1 THEN
btfss SYSBITVAR0,4
goto ENDIF5
;SET CTS ON
bsf PORTB,3
;PORTA=0
clrf PORTA
;WAIT 100 US
movlw 33
movwf DELAYTEMP
DelayUS1
decfsz DELAYTEMP,F
goto DelayUS1
;PORTA=0B00010101
movlw 21
movwf PORTA
;WAIT 100 US
movlw 33
movwf DELAYTEMP
DelayUS2
decfsz DELAYTEMP,F
goto DelayUS2
;PORTA=0
clrf PORTA
;DO UNTIL PORTB.0=0
SysDoLoop_S3
btfss PORTB,0
goto SysDoLoop_E3
;PORTA=0
clrf PORTA
;LOOP
goto SysDoLoop_S3
SysDoLoop_E3
;WAIT 100 MS
movlw 100
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;DO UNTIL PORTB.0=1
SysDoLoop_S4
btfsc PORTB,0
goto SysDoLoop_E4
;LOOP
goto SysDoLoop_S4
SysDoLoop_E4
;SET EMERG_FLAG OFF
bcf SYSBITVAR0,4
;CALL HOME
call HOME
;END IF
ENDIF5
;GOTO MAIN
goto MAIN
;END
goto BASPROGRAMEND
BASPROGRAMEND
sleep
goto BASPROGRAMEND
;********************************************************************************
Delay_MS
incf SysWaitTempMS_H, F
DMS_START
movlw 142
movwf DELAYTEMP2
DMS_OUTER
movlw 1
movwf DELAYTEMP
DMS_INNER
decfsz DELAYTEMP, F
goto DMS_INNER
decfsz DELAYTEMP2, F
goto DMS_OUTER
decfsz SysWaitTempMS, F
goto DMS_START
decfsz SysWaitTempMS_H, F
goto DMS_START
return
;********************************************************************************
HOME
;SET CTS ON
bsf PORTB,3
HOME1
;PORTA=0B00010110
movlw 22
movwf PORTA
;IF EMERG_FLAG=1 THEN
btfss SYSBITVAR0,4
goto ENDIF18
;SET HOME_FLAG OFF
bcf SYSBITVAR0,1
;RETURN
return
;END IF
ENDIF18
;IF PORTB.7=0 AND PORTB.6=0 AND PORTB.5=1 THEN
clrf SysByteTempX
btfss PORTB,7
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp2
clrf SysByteTempX
btfss PORTB,6
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp3
clrf SysByteTempX
btfsc PORTB,5
comf SysByteTempX,F
movf SysTemp2,W
andwf SysTemp3,W
movwf SysTemp4
andwf SysByteTempX,W
movwf SysTemp2
btfsc SysTemp2,0
;GOTO HOME2
goto HOME2
;END IF
;GOTO HOME1
goto HOME1
HOME2
;IF EMERG_FLAG=1 THEN
btfss SYSBITVAR0,4
goto ENDIF20
;SET HOME_FLAG OFF
bcf SYSBITVAR0,1
;RETURN
return
;END IF
ENDIF20
;PORTA=0B00010000
movlw 16
movwf PORTA
;WAIT 100 US
movlw 33
movwf DELAYTEMP
DelayUS11
decfsz DELAYTEMP,F
goto DelayUS11
;PORTA=0B00010101;FRENO
movlw 21
movwf PORTA
;WAIT 100 US
movlw 33
movwf DELAYTEMP
DelayUS12
decfsz DELAYTEMP,F
goto DelayUS12
;PORTA=0B00000000
clrf PORTA
;INDEX=0
clrf INDEX
;WAIT 1000 MS
movlw 232
movwf SysWaitTempMS
movlw 3
movwf SysWaitTempMS_H
call Delay_MS
;DO WHILE INDEX<2
SysDoLoop_S9
movlw 2
subwf INDEX,W
btfsc STATUS, C
goto SysDoLoop_E9
;IF EMERG_FLAG=1 THEN
btfss SYSBITVAR0,4
goto ENDIF21
;SET HOME_FLAG OFF
bcf SYSBITVAR0,1
;RETURN
return
;END IF
ENDIF21
;PORTA=0B00011001
movlw 25
movwf PORTA
;IF PORTB.6=1 AND PORTB.7=1 AND PORTB.5=1 THEN
clrf SysByteTempX
btfsc PORTB,6
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp2
clrf SysByteTempX
btfsc PORTB,7
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp3
clrf SysByteTempX
btfsc PORTB,5
comf SysByteTempX,F
movf SysTemp2,W
andwf SysTemp3,W
movwf SysTemp4
andwf SysByteTempX,W
movwf SysTemp2
btfsc SysTemp2,0
;INDEX=INDEX+1
incf INDEX,F
;END IF
;LOOP
goto SysDoLoop_S9
SysDoLoop_E9
;PORTA=0B00010000
movlw 16
movwf PORTA
;WAIT 100 US
movlw 33
movwf DELAYTEMP
DelayUS13
decfsz DELAYTEMP,F
goto DelayUS13
;PORTA=0B00010101
movlw 21
movwf PORTA
;WAIT 100 US
movlw 33
movwf DELAYTEMP
DelayUS14
decfsz DELAYTEMP,F
goto DelayUS14
;PORTA=0B00000000
clrf PORTA
;POSITION1=0
clrf POSITION1
;POSITION2=0
clrf POSITION2
;POSITION3=0
clrf POSITION3
;POSITION4=0
clrf POSITION4
;POSITION5=0
clrf POSITION5
;SET HOME_FLAG OFF
bcf SYSBITVAR0,1
;DO WHILE CTS_Z=1
SysDoLoop_S10
btfss PORTA,5
goto SysDoLoop_E10
;LOOP
goto SysDoLoop_S10
SysDoLoop_E10
;WAIT 1 MS
movlw 1
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;SET CTS OFF
bcf PORTB,3
return
;********************************************************************************
;Overloaded signature: BYTE:
HSERRECEIVE165
;If USARTHasData Then
btfss PIR1,RCIF
goto ENDIF41
;SerData = RCREG
movf RCREG,W
movwf SERDATA
;End if
ENDIF41
;If OERR Then
btfss RCSTA,OERR
goto ENDIF42
;Set CREN Off
bcf RCSTA,CREN
;Set CREN On
bsf RCSTA,CREN
;End If
ENDIF42
return
;********************************************************************************
HSERSEND
;HSerSendBlocker
;TXREG = SerData
movf SERDATA,W
movwf TXREG
return
;********************************************************************************
INITSYS
;CMCON = 7
movlw 7
movwf CMCON
;PORTA = 0
clrf PORTA
;PORTB = 0
clrf PORTB
return
;********************************************************************************
INITTIMER0
;SInitTimer0
goto SINITTIMER0
;********************************************************************************
INITUSART
;SPBRG = SPBRGL_TEMP
movlw 25
banksel SPBRG
movwf SPBRG
;BRGH = BRGH_TEMP
bsf TXSTA,BRGH
;Set SYNC Off
bcf TXSTA,SYNC
;Set SPEN On
banksel RCSTA
bsf RCSTA,SPEN
;Set CREN On
bsf RCSTA,CREN
;Set TXEN On
banksel TXSTA
bsf TXSTA,TXEN
banksel STATUS
return
;********************************************************************************
MOTOR_JAM
;PORTA=0
clrf PORTA
;SET MOVE_FLAG OFF
bcf SYSBITVAR0,2
;SET HOME_FLAG OFF
bcf SYSBITVAR0,1
;SET PIE1.RCIE OFF
banksel PIE1
bcf PIE1,RCIE
;HSERSEND ADD_REG
banksel ADD_REG
movf ADD_REG,W
movwf SERDATA
call HSERSEND
;HSERSEND 200
movlw 200
movwf SERDATA
goto HSERSEND
;********************************************************************************
MOVE
;SET CTS ON
bsf PORTB,3
;IF EMERG_FLAG=1 THEN
btfss SYSBITVAR0,4
goto ENDIF6
;SET MOVE_FLAG OFF
bcf SYSBITVAR0,2
;RETURN
return
;END IF
ENDIF6
;TEMP=DATA1*2000+DATA2*200+DATA3*20+DATA4*2+DATA5
movf DATA1,W
movwf SysWORDTempA
clrf SysWORDTempA_H
movlw 208
movwf SysWORDTempB
movlw 7
movwf SysWORDTempB_H
call SysMultSub16
movf SysWORDTempX,W
movwf SysTemp1
movf SysWORDTempX_H,W
movwf SysTemp1_H
movf DATA2,W
movwf SysBYTETempA
movlw 200
movwf SysBYTETempB
call SysMultSub
movf SysBYTETempX,W
movwf SysTemp2
movf DATA3,W
movwf SysBYTETempA
movlw 20
movwf SysBYTETempB
call SysMultSub
movf SysBYTETempX,W
movwf SysTemp3
bcf STATUS,C
rlf DATA4,W
movwf SysTemp4
movf SysTemp2,W
addwf SysTemp1,W
movwf SysTemp5
movlw 0
btfsc STATUS,C
addlw 1
addwf SysTemp1_H,W
movwf SysTemp5_H
movf SysTemp3,W
addwf SysTemp5,W
movwf SysTemp1
movlw 0
btfsc STATUS,C
addlw 1
addwf SysTemp5_H,W
movwf SysTemp1_H
movf SysTemp4,W
addwf SysTemp1,W
movwf SysTemp5
movlw 0
btfsc STATUS,C
addlw 1
addwf SysTemp1_H,W
movwf SysTemp5_H
movf DATA5,W
addwf SysTemp5,W
movwf TEMP
movlw 0
btfsc STATUS,C
addlw 1
addwf SysTemp5_H,W
movwf TEMP_H
;IF SIGN=1 THEN
btfss SYSBITVAR0,3
goto ELSE7_1
;CALL MOVE_BACK
call MOVE_BACK
;ELSE
goto ENDIF7
ELSE7_1
;CALL MOVE_FORW
call MOVE_FORW
;END IF
ENDIF7
;PORTA=0B00000000
clrf PORTA
;POSITION_A= POSITION % 2000
movf POSITION,W
movwf SysWORDTempA
movf POSITION_H,W
movwf SysWORDTempA_H
movlw 208
movwf SysWORDTempB
movlw 7
movwf SysWORDTempB_H
call SysDivSub16
movf SysWORDTempX,W
movwf POSITION_A
;POSITION1=(POSITION-POSITION_A)/2000
subwf POSITION,W
movwf SysTemp1
movlw 0
btfss STATUS,C
addlw 1
subwf POSITION_H,W
movwf SysTemp1_H
movf SysTemp1,W
movwf SysWORDTempA
movf SysTemp1_H,W
movwf SysWORDTempA_H
movlw 208
movwf SysWORDTempB
movlw 7
movwf SysWORDTempB_H
call SysDivSub16
movf SysWORDTempA,W
movwf POSITION1
;POSITION_B = POSITION1 % 200
movwf SysBYTETempA
movlw 200
movwf SysBYTETempB
call SysDivSub
movf SysBYTETempX,W
movwf POSITION_B
;POSITION2=(POSITION_A-POSITION_B)/200
subwf POSITION_A,W
movwf SysTemp2
movwf SysBYTETempA
movlw 200
movwf SysBYTETempB
call SysDivSub
movf SysBYTETempA,W
movwf POSITION2
;POSITION_C=POSITION_B % 20
movf POSITION_B,W
movwf SysBYTETempA
movlw 20
movwf SysBYTETempB
call SysDivSub
movf SysBYTETempX,W
movwf POSITION_C
;POSITION3=(POSITION_B - POSITION_C)/20
subwf POSITION_B,W
movwf SysTemp2
movwf SysBYTETempA
movlw 20
movwf SysBYTETempB
call SysDivSub
movf SysBYTETempA,W
movwf POSITION3
;POSITION_D=POSITION_C % 2
clrf POSITION_D
btfsc POSITION_C,0
incf POSITION_D,F
;POSITION4=(POSITION_C-POSITION_D)/2
movf POSITION_D,W
subwf POSITION_C,W
movwf SysTemp2
bcf STATUS,C
rrf SysTemp2,W
movwf POSITION4
;POSITION5=POSITION_D/1
movf POSITION_D,W
movwf POSITION5
;SET MOVE_FLAG OFF
bcf SYSBITVAR0,2
;HSERSEND ADD_REG
movf ADD_REG,W
movwf SERDATA
call HSERSEND
;WAIT 10 MS
movlw 10
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;HSERSEND POSITION1
movf POSITION1,W
movwf SERDATA
call HSERSEND
;WAIT 10 MS
movlw 10
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;HSERSEND POSITION2
movf POSITION2,W
movwf SERDATA
call HSERSEND
;WAIT 10 MS
movlw 10
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;HSERSEND POSITION3
movf POSITION3,W
movwf SERDATA
call HSERSEND
;WAIT 10 MS
movlw 10
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;HSERSEND POSITION4
movf POSITION4,W
movwf SERDATA
call HSERSEND
;WAIT 10 MS
movlw 10
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;HSERSEND POSITION5
movf POSITION5,W
movwf SERDATA
call HSERSEND
;WAIT 10 MS
movlw 10
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;SET X_REG OFF
bcf SYSBITVAR0,0
;IF CTS_Z=0 THEN
btfsc PORTA,5
goto ENDIF8
;WAIT 1 MS
movlw 1
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;SET CTS OFF
bcf PORTB,3
;END IF
ENDIF8
return
;********************************************************************************
MOVE_BACK
;REPEAT TEMP
movf TEMP,W
movwf SysRepeatTemp1
movf TEMP_H,W
movwf SysRepeatTemp1_H
movf SYSREPEATTEMP1,W
movwf SysWORDTempA
movf SYSREPEATTEMP1_H,W
movwf SysWORDTempA_H
movlw 1
movwf SysWORDTempB
clrf SysWORDTempB_H
call SysCompLessThan16
btfsc SysByteTempX,0
goto SysRepeatLoopEnd1
movf SYSREPEATTEMP1,F
btfss STATUS, Z
incf SysRepeatTemp1_H,F
SysRepeatLoop1
;IF EMERG_FLAG=1 THEN
btfss SYSBITVAR0,4
goto ENDIF11
;SET MOVE_FLAG OFF
bcf SYSBITVAR0,2
;EXIT SUB
return
;END IF
ENDIF11
;IF PORTB.7=0 THEN
btfsc PORTB,7
goto ENDIF12
;PORTA=0B00010110
movlw 22
movwf PORTA
;TMR0=0
clrf TMR0
;SET INTCON.T0IE ON
bsf INTCON,T0IE
;DO UNTIL PORTB.7=1
SysDoLoop_S5
btfsc PORTB,7
goto SysDoLoop_E5
;LOOP
goto SysDoLoop_S5
SysDoLoop_E5
;SET INTCON.T0IE OFF
bcf INTCON,T0IE
;PORTA = 0B00010000
movlw 16
movwf PORTA
;PORTA = 0B00011010
movlw 26
movwf PORTA
;WAIT 100 US
movlw 33
movwf DELAYTEMP
DelayUS3
decfsz DELAYTEMP,F
goto DelayUS3
;PORTA = 0B00000000
clrf PORTA
;WAIT 100 US
movlw 33
movwf DELAYTEMP
DelayUS4
decfsz DELAYTEMP,F
goto DelayUS4
;GOTO CONTINUE_BACK_1
goto CONTINUE_BACK_1
;END IF
ENDIF12
;IF PORTB.7=1 THEN
btfss PORTB,7
goto ENDIF13
;PORTA=0B00010110
movlw 22
movwf PORTA
;TMR0=0
clrf TMR0
;SET INTCON.T0IE ON
bsf INTCON,T0IE
;DO UNTIL PORTB.7=0
SysDoLoop_S6
btfss PORTB,7
goto SysDoLoop_E6
;LOOP
goto SysDoLoop_S6
SysDoLoop_E6
;SET INTCON.T0IE OFF
bcf INTCON,T0IE
;PORTA = 0B00010000
movlw 16
movwf PORTA
;PORTA = 0B00011010
movlw 26
movwf PORTA
;WAIT 100 US
movlw 33
movwf DELAYTEMP
DelayUS5
decfsz DELAYTEMP,F
goto DelayUS5
;PORTA = 0B00000000
clrf PORTA
;WAIT 100 US
movlw 33
movwf DELAYTEMP
DelayUS6
decfsz DELAYTEMP,F
goto DelayUS6
;GOTO CONTINUE_BACK_1
goto CONTINUE_BACK_1
;END IF
ENDIF13
CONTINUE_BACK_1
;POSITION=POSITION-1
movlw 1
subwf POSITION,F
movlw 0
btfss STATUS,C
addlw 1
subwf POSITION_H,F
;END REPEAT
decfsz SysRepeatTemp1,F
goto SysRepeatLoop1
decfsz SysRepeatTemp1_H,F
goto SysRepeatLoop1
SysRepeatLoopEnd1
return
;********************************************************************************
MOVE_FORW
;REPEAT TEMP
movf TEMP,W
movwf SysRepeatTemp2
movf TEMP_H,W
movwf SysRepeatTemp2_H
movf SYSREPEATTEMP2,W
movwf SysWORDTempA
movf SYSREPEATTEMP2_H,W
movwf SysWORDTempA_H
movlw 1
movwf SysWORDTempB
clrf SysWORDTempB_H
call SysCompLessThan16
btfsc SysByteTempX,0
goto SysRepeatLoopEnd2
movf SYSREPEATTEMP2,F
btfss STATUS, Z
incf SysRepeatTemp2_H,F
SysRepeatLoop2
;IF EMERG_FLAG=1 THEN
btfss SYSBITVAR0,4
goto ENDIF15
;SET MOVE_FLAG OFF
bcf SYSBITVAR0,2
;EXIT SUB
return
;END IF
ENDIF15
;IF PORTB.7=0 THEN
btfsc PORTB,7
goto ENDIF16
;PORTA=0B00011001
movlw 25
movwf PORTA
;DO UNTIL PORTB.7=1
SysDoLoop_S7
btfsc PORTB,7
goto SysDoLoop_E7
;LOOP
goto SysDoLoop_S7
SysDoLoop_E7
;TMR0=0
clrf TMR0
;SET INTCON.T0IE ON
bsf INTCON,T0IE
;SET INTCON.T0IE OFF
bcf INTCON,T0IE
;PORTA = 0B00010000
movlw 16
movwf PORTA
;PORTA = 0B00011010
movlw 26
movwf PORTA
;WAIT 100 US
movlw 33
movwf DELAYTEMP
DelayUS7
decfsz DELAYTEMP,F
goto DelayUS7
;PORTA = 0B00000000
clrf PORTA
;WAIT 100 US
movlw 33
movwf DELAYTEMP
DelayUS8
decfsz DELAYTEMP,F
goto DelayUS8
;GOTO CONTINUE_FORW_1
goto CONTINUE_FORW_1
;END IF
ENDIF16
;IF PORTB.7=1 THEN
btfss PORTB,7
goto ENDIF17
;PORTA=0B00011001
movlw 25
movwf PORTA
;TMR0=0
clrf TMR0
;SET INTCON.T0IE ON
bsf INTCON,T0IE
;DO UNTIL PORTB.7=0
SysDoLoop_S8
btfss PORTB,7
goto SysDoLoop_E8
;LOOP
goto SysDoLoop_S8
SysDoLoop_E8
;SET INTCON.T0IE OFF
bcf INTCON,T0IE
;PORTA = 0B00010000
movlw 16
movwf PORTA
;PORTA = 0B00011010
movlw 26
movwf PORTA
;WAIT 100 US
movlw 33
movwf DELAYTEMP
DelayUS9
decfsz DELAYTEMP,F
goto DelayUS9
;PORTA = 0B00000000
clrf PORTA
;WAIT 100 US
movlw 33
movwf DELAYTEMP
DelayUS10
decfsz DELAYTEMP,F
goto DelayUS10
;GOTO CONTINUE_FORW_1
goto CONTINUE_FORW_1
;END IF
ENDIF17
CONTINUE_FORW_1
;POSITION=POSITION+1
incf POSITION,F
btfsc STATUS,Z
incf POSITION_H,F
;END REPEAT
decfsz SysRepeatTemp2,F
goto SysRepeatLoop2
decfsz SysRepeatTemp2_H,F
goto SysRepeatLoop2
SysRepeatLoopEnd2
return
;********************************************************************************
RS232_IN
;SET CTS ON
bsf PORTB,3
;HSERRECEIVE RS232_BUFFER
call HSERRECEIVE165
movf SERDATA,W
movwf RS232_BUFFER
;IF RS232_BUFFER=0XFF THEN
incf RS232_BUFFER,W
btfss STATUS, Z
goto ENDIF23
;SET CTS ON
bsf PORTB,3
;SET MOVE_FLAG OFF
bcf SYSBITVAR0,2
;SET HOME_FLAG OFF
bcf SYSBITVAR0,1
;SET EMERG_FLAG ON
bsf SYSBITVAR0,4
;RETURN
return
;END IF
ENDIF23
;IF RS232_BUFFER=0XFE THEN
movlw 254
subwf RS232_BUFFER,W
btfss STATUS, Z
goto ENDIF24
;HOME_FLAG=1
bsf SYSBITVAR0,1
;MOVE_FLAG=0
bcf SYSBITVAR0,2
;SET CTS ON
bsf PORTB,3
;RETURN
return
;END IF
ENDIF24
;IF RS232_BUFFER = ADD_REG THEN
movf ADD_REG,W
subwf RS232_BUFFER,W
btfss STATUS, Z
goto ENDIF25
;SET X_REG ON
bsf SYSBITVAR0,0
;DATA_COUNT=6
movlw 6
movwf DATA_COUNT
;WAIT 1 MS
movlw 1
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;SET CTS OFF
bcf PORTB,3
;RETURN
return
;END IF
ENDIF25
;IF X_REG=1 AND RS232_BUFFER=0XAA AND DATA_COUNT=6 THEN
clrf SysByteTempX
btfsc SYSBITVAR0,0
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp2
movf RS232_BUFFER,W
movwf SysBYTETempA
movlw 170
movwf SysBYTETempB
call SysCompEqual
movf SysByteTempX,W
movwf SysTemp3
movf DATA_COUNT,W
movwf SysBYTETempA
movlw 6
movwf SysBYTETempB
call SysCompEqual
movf SysTemp2,W
andwf SysTemp3,W
movwf SysTemp4
andwf SysByteTempX,W
movwf SysTemp2
btfss SysTemp2,0
goto ENDIF26
;SET SIGN ON
bsf SYSBITVAR0,3
;DATA_COUNT=DATA_COUNT-1
decf DATA_COUNT,F
;WAIT 1 MS
movlw 1
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;SET CTS OFF
bcf PORTB,3
;RETURN
return
;END IF
ENDIF26
;IF X_REG=1 AND RS232_BUFFER=0XCC AND DATA_COUNT=6 THEN
clrf SysByteTempX
btfsc SYSBITVAR0,0
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp2
movf RS232_BUFFER,W
movwf SysBYTETempA
movlw 204
movwf SysBYTETempB
call SysCompEqual
movf SysByteTempX,W
movwf SysTemp3
movf DATA_COUNT,W
movwf SysBYTETempA
movlw 6
movwf SysBYTETempB
call SysCompEqual
movf SysTemp2,W
andwf SysTemp3,W
movwf SysTemp4
andwf SysByteTempX,W
movwf SysTemp2
btfss SysTemp2,0
goto ENDIF27
;SET SIGN OFF
bcf SYSBITVAR0,3
;DATA_COUNT=DATA_COUNT-1
decf DATA_COUNT,F
;WAIT 1 MS
movlw 1
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;SET CTS OFF
bcf PORTB,3
;RETURN
return
;END IF
ENDIF27
;IF X_REG=1 AND DATA_COUNT=5 AND RS232_BUFFER<10 THEN
clrf SysByteTempX
btfsc SYSBITVAR0,0
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp2
movf DATA_COUNT,W
movwf SysBYTETempA
movlw 5
movwf SysBYTETempB
call SysCompEqual
movf SysByteTempX,W
movwf SysTemp3
movf RS232_BUFFER,W
movwf SysBYTETempA
movlw 10
movwf SysBYTETempB
call SysCompLessThan
movf SysTemp2,W
andwf SysTemp3,W
movwf SysTemp4
andwf SysByteTempX,W
movwf SysTemp2
btfss SysTemp2,0
goto ENDIF28
;DATA1=RS232_BUFFER
movf RS232_BUFFER,W
movwf DATA1
;DATA_COUNT=DATA_COUNT-1
decf DATA_COUNT,F
;WAIT 1 MS
movlw 1
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;SET CTS OFF
bcf PORTB,3
;RETURN
return
;END IF
ENDIF28
;IF X_REG=1 AND DATA_COUNT=4 AND RS232_BUFFER<10 THEN
clrf SysByteTempX
btfsc SYSBITVAR0,0
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp2
movf DATA_COUNT,W
movwf SysBYTETempA
movlw 4
movwf SysBYTETempB
call SysCompEqual
movf SysByteTempX,W
movwf SysTemp3
movf RS232_BUFFER,W
movwf SysBYTETempA
movlw 10
movwf SysBYTETempB
call SysCompLessThan
movf SysTemp2,W
andwf SysTemp3,W
movwf SysTemp4
andwf SysByteTempX,W
movwf SysTemp2
btfss SysTemp2,0
goto ENDIF29
;DATA2=RS232_BUFFER
movf RS232_BUFFER,W
movwf DATA2
;DATA_COUNT=DATA_COUNT-1
decf DATA_COUNT,F
;WAIT 1 MS
movlw 1
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;SET CTS OFF
bcf PORTB,3
;RETURN
return
;END IF
ENDIF29
;IF X_REG=1 AND DATA_COUNT=3 AND RS232_BUFFER<10 THEN
clrf SysByteTempX
btfsc SYSBITVAR0,0
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp2
movf DATA_COUNT,W
movwf SysBYTETempA
movlw 3
movwf SysBYTETempB
call SysCompEqual
movf SysByteTempX,W
movwf SysTemp3
movf RS232_BUFFER,W
movwf SysBYTETempA
movlw 10
movwf SysBYTETempB
call SysCompLessThan
movf SysTemp2,W
andwf SysTemp3,W
movwf SysTemp4
andwf SysByteTempX,W
movwf SysTemp2
btfss SysTemp2,0
goto ENDIF30
;DATA3=RS232_BUFFER
movf RS232_BUFFER,W
movwf DATA3
;DATA_COUNT=DATA_COUNT-1
decf DATA_COUNT,F
;WAIT 1 MS
movlw 1
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;SET CTS OFF
bcf PORTB,3
;RETURN
return
;END IF
ENDIF30
;IF X_REG=1 AND DATA_COUNT=2 AND RS232_BUFFER<10 THEN
clrf SysByteTempX
btfsc SYSBITVAR0,0
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp2
movf DATA_COUNT,W
movwf SysBYTETempA
movlw 2
movwf SysBYTETempB
call SysCompEqual
movf SysByteTempX,W
movwf SysTemp3
movf RS232_BUFFER,W
movwf SysBYTETempA
movlw 10
movwf SysBYTETempB
call SysCompLessThan
movf SysTemp2,W
andwf SysTemp3,W
movwf SysTemp4
andwf SysByteTempX,W
movwf SysTemp2
btfss SysTemp2,0
goto ENDIF31
;DATA4=RS232_BUFFER
movf RS232_BUFFER,W
movwf DATA4
;DATA_COUNT=DATA_COUNT-1
decf DATA_COUNT,F
;WAIT 1 MS
movlw 1
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;SET CTS OFF
bcf PORTB,3
;RETURN
return
;END IF
ENDIF31
;IF X_REG=1 AND DATA_COUNT=1 AND RS232_BUFFER<10 THEN
clrf SysByteTempX
btfsc SYSBITVAR0,0
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp2
movf DATA_COUNT,W
movwf SysBYTETempA
movlw 1
movwf SysBYTETempB
call SysCompEqual
movf SysByteTempX,W
movwf SysTemp3
movf RS232_BUFFER,W
movwf SysBYTETempA
movlw 10
movwf SysBYTETempB
call SysCompLessThan
movf SysTemp2,W
andwf SysTemp3,W
movwf SysTemp4
andwf SysByteTempX,W
movwf SysTemp2
btfss SysTemp2,0
goto ENDIF32
;DATA5=RS232_BUFFER
movf RS232_BUFFER,W
movwf DATA5
;DATA_COUNT=DATA_COUNT-1
decf DATA_COUNT,F
;SET CTS ON
bsf PORTB,3
;SET MOVE_FLAG ON
bsf SYSBITVAR0,2
;SET X_REG OFF
bcf SYSBITVAR0,0
;RETURN
return
;END IF
ENDIF32
;IF RS232_BUFFER=0XFA THEN
movlw 250
subwf RS232_BUFFER,W
btfss STATUS, Z
goto ENDIF33
;SET CTS ON
bsf PORTB,3
;WAIT 1 MS
movlw 1
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;DO WHILE CTS_Z=1
SysDoLoop_S11
btfss PORTA,5
goto SysDoLoop_E11
;SET CTS ON
bsf PORTB,3
;LOOP
goto SysDoLoop_S11
SysDoLoop_E11
;WAIT 1 MS
movlw 1
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;SET CTS OFF
bcf PORTB,3
;RETURN
return
;END IF
ENDIF33
;IF RS232_BUFFER<>0XFF OR RS232_BUFFER<>ADD_REG OR RS232_BUFFER<>0XFE AND DATA_COUNT=0 OR X_REG=0 THEN
movf RS232_BUFFER,W
movwf SysBYTETempA
movlw 255
movwf SysBYTETempB
call SysCompEqual
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp2
movf RS232_BUFFER,W
movwf SysBYTETempA
movf ADD_REG,W
movwf SysBYTETempB
call SysCompEqual
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp3
movf RS232_BUFFER,W
movwf SysBYTETempA
movlw 254
movwf SysBYTETempB
call SysCompEqual
comf SysByteTempX,F
movf SysByteTempX,W
movwf SysTemp4
movf DATA_COUNT,W
movwf SysBYTETempA
clrf SysBYTETempB
call SysCompEqual
movf SysByteTempX,W
movwf SysTemp1
clrf SysByteTempX
btfss SYSBITVAR0,0
comf SysByteTempX,F
movf SysTemp2,W
iorwf SysTemp3,W
movwf SysTemp5
iorwf SysTemp4,W
movwf SysTemp2
andwf SysTemp1,W
movwf SysTemp3
iorwf SysByteTempX,W
movwf SysTemp2
btfss SysTemp2,0
goto ENDIF34
;SET CTS ON
bsf PORTB,3
;WAIT 1 MS
movlw 1
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;DO WHILE CTS_Z=1
SysDoLoop_S12
btfss PORTA,5
goto SysDoLoop_E12
;SET CTS ON
bsf PORTB,3
;LOOP
goto SysDoLoop_S12
SysDoLoop_E12
;WAIT 1 MS
movlw 1
movwf SysWaitTempMS
clrf SysWaitTempMS_H
call Delay_MS
;SET CTS OFF
bcf PORTB,3
;RETURN
return
;END IF
ENDIF34
return
;********************************************************************************
SINITTIMER0
;OPTION_REG = OPTION_REG AND 192
movlw 192
banksel OPTION_REG
andwf OPTION_REG,F
;SET OPTION_REG.PSA OFF
bcf OPTION_REG,PSA
;if TMR0Source = Osc THEN SET OPTION_REG.T0SE OFF
banksel TMR0SOURCE
decf TMR0SOURCE,W
btfss STATUS, Z
goto ENDIF35
banksel OPTION_REG
bcf OPTION_REG,T0SE
ENDIF35
;if TMR0Source = Ext THEN SET OPTION_REG.T0SE ON
movlw 2
banksel TMR0SOURCE
subwf TMR0SOURCE,W
btfss STATUS, Z
goto ENDIF36
banksel OPTION_REG
bsf OPTION_REG,T0SE
ENDIF36
;clrwdt
clrwdt
;OPTION_REG = OPTION_REG OR TMR0Pres
banksel OPTION_REG
movf OPTION_REG,W
banksel TMR0PRES
iorwf TMR0PRES,W
banksel OPTION_REG
movwf OPTION_REG
banksel STATUS
return
;********************************************************************************
SYSCOMPEQUAL
;Dim SysByteTempA, SysByteTempB, SysByteTempX as byte
;clrf SysByteTempX
clrf SYSBYTETEMPX
;movf SysByteTempA, W
movf SYSBYTETEMPA, W
;subwf SysByteTempB, W
subwf SYSBYTETEMPB, W
;btfsc STATUS, Z
btfsc STATUS, Z
;comf SysByteTempX,F
comf SYSBYTETEMPX,F
return
;********************************************************************************
SYSCOMPEQUAL16
;dim SysWordTempA as word
;dim SysWordTempB as word
;dim SysByteTempX as byte
;clrf SysByteTempX
clrf SYSBYTETEMPX
;movf SysWordTempA, W
movf SYSWORDTEMPA, W
;subwf SysWordTempB, W
subwf SYSWORDTEMPB, W
;btfss STATUS, Z
btfss STATUS, Z
;return
return
;movf SysWordTempA_H, W
movf SYSWORDTEMPA_H, W
;subwf SysWordTempB_H, W
subwf SYSWORDTEMPB_H, W
;btfss STATUS, Z
btfss STATUS, Z
;return
return
;comf SysByteTempX,F
comf SYSBYTETEMPX,F
return
;********************************************************************************
SYSCOMPLESSTHAN
;Dim SysByteTempA, SysByteTempB, SysByteTempX as byte
;clrf SysByteTempX
clrf SYSBYTETEMPX
;bsf STATUS, C
bsf STATUS, C
;movf SysByteTempB, W
movf SYSBYTETEMPB, W
;subwf SysByteTempA, W
subwf SYSBYTETEMPA, W
;btfss STATUS, C
btfss STATUS, C
;comf SysByteTempX,F
comf SYSBYTETEMPX,F
return
;********************************************************************************
SYSCOMPLESSTHAN16
;dim SysWordTempA as word
;dim SysWordTempB as word
;dim SysByteTempX as byte
;clrf SysByteTempX
clrf SYSBYTETEMPX
;movf SysWordTempA_H,W
movf SYSWORDTEMPA_H,W
;subwf SysWordTempB_H,W
subwf SYSWORDTEMPB_H,W
;btfss STATUS,C
btfss STATUS,C
;return
return
;movf SysWordTempB_H,W
movf SYSWORDTEMPB_H,W
;subwf SysWordTempA_H,W
subwf SYSWORDTEMPA_H,W
;btfss STATUS,C
btfss STATUS,C
;goto SCLT16True
goto SCLT16TRUE
;movf SysWordTempB,W
movf SYSWORDTEMPB,W
;subwf SysWordTempA,W
subwf SYSWORDTEMPA,W
;btfsc STATUS,C
btfsc STATUS,C
;return
return
SCLT16TRUE
;comf SysByteTempX,F
comf SYSBYTETEMPX,F
return
;********************************************************************************
SYSDIVSUB
;dim SysByteTempA as byte
;dim SysByteTempB as byte
;dim SysByteTempX as byte
;SysByteTempX = 0
clrf SYSBYTETEMPX
;SysDivLoop = 8
movlw 8
movwf SYSDIVLOOP
SYSDIV8START
;bcf STATUS, C
bcf STATUS, C
;rlf SysByteTempA, F
rlf SYSBYTETEMPA, F
;rlf SysByteTempX, F
rlf SYSBYTETEMPX, F
;movf SysByteTempB, W
movf SYSBYTETEMPB, W
;subwf SysByteTempX, F
subwf SYSBYTETEMPX, F
;bsf SysByteTempA, 0
bsf SYSBYTETEMPA, 0
;btfsc STATUS, C
btfsc STATUS, C
;goto Div8NotNeg
goto DIV8NOTNEG
;bcf SysByteTempA, 0
bcf SYSBYTETEMPA, 0
;movf SysByteTempB, W
movf SYSBYTETEMPB, W
;addwf SysByteTempX, F
addwf SYSBYTETEMPX, F
DIV8NOTNEG
;decfsz SysDivLoop, F
decfsz SYSDIVLOOP, F
;goto SysDiv8Start
goto SYSDIV8START
return
;********************************************************************************
SYSDIVSUB16
;dim SysWordTempA as word
;dim SysWordTempB as word
;dim SysWordTempX as word
;dim SysDivMultA as word
;dim SysDivMultB as word
;dim SysDivMultX as word
;SysDivMultA = SysWordTempA
movf SYSWORDTEMPA,W
movwf SYSDIVMULTA
movf SYSWORDTEMPA_H,W
movwf SYSDIVMULTA_H
;SysDivMultB = SysWordTempB
movf SYSWORDTEMPB,W
movwf SYSDIVMULTB
movf SYSWORDTEMPB_H,W
movwf SYSDIVMULTB_H
;SysDivMultX = 0
clrf SYSDIVMULTX
clrf SYSDIVMULTX_H
;if SysDivMultB = 0 then
movf SYSDIVMULTB,W
movwf SysWORDTempA
movf SYSDIVMULTB_H,W
movwf SysWORDTempA_H
clrf SysWORDTempB
clrf SysWORDTempB_H
call SysCompEqual16
btfss SysByteTempX,0
goto ENDIF39
;SysWordTempA = 0
clrf SYSWORDTEMPA
clrf SYSWORDTEMPA_H
;exit sub
return
;end if
ENDIF39
;SysDivLoop = 16
movlw 16
movwf SYSDIVLOOP
SYSDIV16START
;set C off
bcf STATUS,C
;Rotate SysDivMultA Left
rlf SYSDIVMULTA,F
rlf SYSDIVMULTA_H,F
;Rotate SysDivMultX Left
rlf SYSDIVMULTX,F
rlf SYSDIVMULTX_H,F
;SysDivMultX = SysDivMultX - SysDivMultB
movf SYSDIVMULTB,W
subwf SYSDIVMULTX,F
movf SYSDIVMULTB_H,W
btfss STATUS,C
addlw 1
subwf SYSDIVMULTX_H,F
;Set SysDivMultA.0 On
bsf SYSDIVMULTA,0
;If C Off Then
btfsc STATUS,C
goto ENDIF40
;Set SysDivMultA.0 Off
bcf SYSDIVMULTA,0
;SysDivMultX = SysDivMultX + SysDivMultB
movf SYSDIVMULTB,W
addwf SYSDIVMULTX,F
movf SYSDIVMULTB_H,W
btfsc STATUS,C
addlw 1
addwf SYSDIVMULTX_H,F
;End If
ENDIF40
;decfsz SysDivLoop, F
decfsz SYSDIVLOOP, F
;goto SysDiv16Start
goto SYSDIV16START
;SysWordTempA = SysDivMultA
movf SYSDIVMULTA,W
movwf SYSWORDTEMPA
movf SYSDIVMULTA_H,W
movwf SYSWORDTEMPA_H
;SysWordTempX = SysDivMultX
movf SYSDIVMULTX,W
movwf SYSWORDTEMPX
movf SYSDIVMULTX_H,W
movwf SYSWORDTEMPX_H
return
;********************************************************************************
SYSMULTSUB
;dim SysByteTempA as byte
;dim SysByteTempB as byte
;dim SysByteTempX as byte
;clrf SysByteTempX
clrf SYSBYTETEMPX
MUL8LOOP
;movf SysByteTempA, W
movf SYSBYTETEMPA, W
;btfsc SysByteTempB, 0
btfsc SYSBYTETEMPB, 0
;addwf SysByteTempX, F
addwf SYSBYTETEMPX, F
;bcf STATUS, C
bcf STATUS, C
;rrf SysByteTempB, F
rrf SYSBYTETEMPB, F
;bcf STATUS, C
bcf STATUS, C
;rlf SysByteTempA, F
rlf SYSBYTETEMPA, F
;movf SysByteTempB, F
movf SYSBYTETEMPB, F
;btfss STATUS, Z
btfss STATUS, Z
;goto MUL8LOOP
goto MUL8LOOP
return
;********************************************************************************
SYSMULTSUB16
;dim SysWordTempA as word
;dim SysWordTempB as word
;dim SysWordTempX as word
;dim SysDivMultA as word
;dim SysDivMultB as word
;dim SysDivMultX as word
;SysDivMultA = SysWordTempA
movf SYSWORDTEMPA,W
movwf SYSDIVMULTA
movf SYSWORDTEMPA_H,W
movwf SYSDIVMULTA_H
;SysDivMultB = SysWordTempB
movf SYSWORDTEMPB,W
movwf SYSDIVMULTB
movf SYSWORDTEMPB_H,W
movwf SYSDIVMULTB_H
;SysDivMultX = 0
clrf SYSDIVMULTX
clrf SYSDIVMULTX_H
MUL16LOOP
;IF SysDivMultB.0 ON then SysDivMultX += SysDivMultA
btfss SYSDIVMULTB,0
goto ENDIF37
movf SYSDIVMULTA,W
addwf SYSDIVMULTX,F
movf SYSDIVMULTA_H,W
btfsc STATUS,C
addlw 1
addwf SYSDIVMULTX_H,F
ENDIF37
;set STATUS.C OFF
bcf STATUS,C
;rotate SysDivMultB right
rrf SYSDIVMULTB_H,F
rrf SYSDIVMULTB,F
;set STATUS.C off
bcf STATUS,C
;rotate SysDivMultA left
rlf SYSDIVMULTA,F
rlf SYSDIVMULTA_H,F
;if SysDivMultB > 0 then goto MUL16LOOP
movf SYSDIVMULTB,W
movwf SysWORDTempB
movf SYSDIVMULTB_H,W
movwf SysWORDTempB_H
clrf SysWORDTempA
clrf SysWORDTempA_H
call SysCompLessThan16
btfsc SysByteTempX,0
goto MUL16LOOP
;SysWordTempX = SysDivMultX
movf SYSDIVMULTX,W
movwf SYSWORDTEMPX
movf SYSDIVMULTX_H,W
movwf SYSWORDTEMPX_H
return
;********************************************************************************
END
Last edit: Anobium 2014-08-20
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you. I am glad to be here.
The code is about 1,2k. I quote it bellow.
As you can see there are a lot of overlapping registers and that cause the program to run unexpectably at some points.
As far as it concern the format, I tried to format the code as in MPLAB, i.e. no # before include or without the brackets, but I get the saem error.
In fact, I am trying to compile the asm file, through GCB@syn.
I am compiling the basic file, and then I am trying to compile the produced asm file, because I want to correct the variables' addresses.
Please note that the if I compile the basic file, it will produce the HEX file, but since there is the addresses issue, I want to make the corrections to the ASM file and then compile the ASM file and then is when I get the error.
Perhaps, instead of trying to compile the ASM, file there is some way to alter the adrresses that the compiler asserts to the variables?
I tried to define the variables' address with inline assembly(see bolt text: asm DATA5 equ 0x23), but the compiler will designate the address by its on and then it will insert my equ instruction, thus it will set the variable in two different addresses.
DIM X_REG AS BIT
DIM HOME_FLAG AS BIT
DIM MOVE_FLAG AS BIT
DIM SIGN AS BIT
DIM EMERG_FLAG AS BIT
DIM DATA5 AS BYTE asm DATA5 equ 0x23
DIM DATA4 AS BYTE
DIM DATA3 AS BYTE
DIM DATA2 AS BYTE
DIM DATA1 AS BYTE
DIM POSITION AS WORD
DIM POSITION1 AS BYTE
DIM POSITION2 AS BYTE
DIM POSITION3 AS BYTE
DIM POSITION4 AS BYTE
DIM POSITION5 AS BYTE
DIM INDEX AS BYTE
DIM RS232_BUFFER AS BYTE
DIM ADD_REG AS BYTE
DIM TEMP AS WORD
DIM DATA_COUNT AS BYTE
ADD_REG=252
SET X_REG OFF
DATA_COUNT=0X00
DATA3=0X00
DATA2=0X00
DATA1=0X00
TRISA= 0B11100000
TRISB= 0B11110011
PORTA=0B00000000
PORTB=0B00000000
SET HOME_FLAG OFF
SET MOVE_FLAG OFF
SET EMERG_FLAG OFF
DO UNTIL PORTB.0=0
LOOP
WAIT 100 MS
DO UNTIL PORTB.0=1
LOOP
"#DEFINE USART_BAUD_RATE 9600"
ON INTERRUPT USARTRX1READY CALL RS232_IN
INITTIMER0 OSC, PS0_256
ON INTERRUPT TIMER0OVERFLOW CALL MOTOR_JAM
SET PORTA.4 OFF
SET CTS OFF
MAIN:
IF MOVE_FLAG=0 AND CTS_Z=1 THEN
SET CTS ON
END IF
IF MOVE_FLAG=0 AND CTS_Z=0 THEN
WAIT 1 MS
SET CTS OFF
END IF
IF HOME_FLAG=1 THEN
CALL HOME
END IF
IF MOVE_FLAG=1 THEN
CALL MOVE
END IF
IF EMERG_FLAG=1 THEN
SET CTS ON
PORTA=0
WAIT 100 US
PORTA=0B00010101
WAIT 100 US
PORTA=0
DO UNTIL PORTB.0=0
PORTA=0
LOOP
WAIT 100 MS
DO UNTIL PORTB.0=1
LOOP
SET EMERG_FLAG OFF
CALL HOME
END IF
GOTO MAIN
SUB MOVE
SET CTS ON
IF EMERG_FLAG=1 THEN
SET MOVE_FLAG OFF
RETURN
END IF
TEMP=DATA1*2000+DATA2*200+DATA3*20+DATA4*2+DATA5
IF SIGN=1 THEN
CALL MOVE_BACK
ELSE
CALL MOVE_FORW
END IF
PORTA=0B00000000
POSITION_A= POSITION % 2000
POSITION1=(POSITION-POSITION_A)/2000
POSITION_B = POSITION1 % 200
POSITION2=(POSITION_A-POSITION_B)/200
POSITION_C=POSITION_B % 20
POSITION3=(POSITION_B - POSITION_C)/20
POSITION_D=POSITION_C % 2
POSITION4=(POSITION_C-POSITION_D)/2
POSITION5=POSITION_D/1
SET MOVE_FLAG OFF
HSERSEND ADD_REG
WAIT 10 MS
HSERSEND POSITION1
WAIT 10 MS
HSERSEND POSITION2
WAIT 10 MS
HSERSEND POSITION3
WAIT 10 MS
HSERSEND POSITION4
WAIT 10 MS
HSERSEND POSITION5
WAIT 10 MS
SET X_REG OFF
IF CTS_Z=0 THEN
WAIT 1 MS
SET CTS OFF
END IF
END SUB
SUB MOVE_BACK
REPEAT TEMP
IF EMERG_FLAG=1 THEN
SET MOVE_FLAG OFF
EXIT SUB
END IF
IF PORTB.7=0 THEN
PORTA=0B00010110
TMR0=0
SET INTCON.T0IE ON
DO UNTIL PORTB.7=1
LOOP
SET INTCON.T0IE OFF
PORTA = 0B00010000
PORTA = 0B00011010
WAIT 100 US
PORTA = 0B00000000
WAIT 100 US
GOTO CONTINUE_BACK_1
END IF
IF PORTB.7=1 THEN
PORTA=0B00010110
TMR0=0
SET INTCON.T0IE ON
DO UNTIL PORTB.7=0
LOOP
SET INTCON.T0IE OFF
PORTA = 0B00010000
PORTA = 0B00011010
WAIT 100 US
PORTA = 0B00000000
WAIT 100 US
GOTO CONTINUE_BACK_1
END IF
CONTINUE_BACK_1:
POSITION=POSITION-1
END REPEAT
END SUB
SUB MOVE_FORW
REPEAT TEMP
IF EMERG_FLAG=1 THEN
SET MOVE_FLAG OFF
EXIT SUB
END IF
IF PORTB.7=0 THEN
PORTA=0B00011001
DO UNTIL PORTB.7=1
LOOP
TMR0=0
SET INTCON.T0IE ON
SET INTCON.T0IE OFF
PORTA = 0B00010000
PORTA = 0B00011010
WAIT 100 US
PORTA = 0B00000000
WAIT 100 US
GOTO CONTINUE_FORW_1
END IF
IF PORTB.7=1 THEN
PORTA=0B00011001
TMR0=0
SET INTCON.T0IE ON
DO UNTIL PORTB.7=0
LOOP
SET INTCON.T0IE OFF
PORTA = 0B00010000
PORTA = 0B00011010
WAIT 100 US
PORTA = 0B00000000
WAIT 100 US
GOTO CONTINUE_FORW_1
END IF
CONTINUE_FORW_1:
POSITION=POSITION+1
END REPEAT
END SUB
SUB HOME
SET CTS ON
HOME1:
PORTA=0B00010110
IF EMERG_FLAG=1 THEN
SET HOME_FLAG OFF
RETURN
END IF
IF PORTB.7=0 AND PORTB.6=0 AND PORTB.5=1 THEN
GOTO HOME2
END IF
GOTO HOME1
HOME2:
IF EMERG_FLAG=1 THEN
SET HOME_FLAG OFF
RETURN
END IF
PORTA=0B00010000
WAIT 100 US
PORTA=0B00010101;FRENO
WAIT 100 US
PORTA=0B00000000
INDEX=0
WAIT 1000 MS
DO WHILE INDEX<2
IF EMERG_FLAG=1 THEN
SET HOME_FLAG OFF
RETURN
END IF
PORTA=0B00011001
IF PORTB.6=1 AND PORTB.7=1 AND PORTB.5=1 THEN
INDEX=INDEX+1
END IF
LOOP
PORTA=0B00010000
WAIT 100 US
PORTA=0B00010101
WAIT 100 US
PORTA=0B00000000
POSITION1=0
POSITION2=0
POSITION3=0
POSITION4=0
POSITION5=0
SET HOME_FLAG OFF
DO WHILE CTS_Z=1
LOOP
WAIT 1 MS
SET CTS OFF
END SUB
SUB RS232_IN
SET CTS ON
HSERRECEIVE RS232_BUFFER
IF RS232_BUFFER=0XFF THEN
SET CTS ON
SET MOVE_FLAG OFF
SET HOME_FLAG OFF
SET EMERG_FLAG ON
RETURN
END IF
IF RS232_BUFFER=0XFE THEN
HOME_FLAG=1
MOVE_FLAG=0
SET CTS ON
RETURN
END IF
IF RS232_BUFFER = ADD_REG THEN
SET X_REG ON
DATA_COUNT=6
WAIT 1 MS
SET CTS OFF
RETURN
END IF
IF X_REG=1 AND RS232_BUFFER=0XAA AND DATA_COUNT=6 THEN
SET SIGN ON
DATA_COUNT=DATA_COUNT-1
WAIT 1 MS
SET CTS OFF
RETURN
END IF
IF X_REG=1 AND RS232_BUFFER=0XCC AND DATA_COUNT=6 THEN
SET SIGN OFF
DATA_COUNT=DATA_COUNT-1
WAIT 1 MS
SET CTS OFF
RETURN
END IF
IF X_REG=1 AND DATA_COUNT=5 AND RS232_BUFFER<10 THEN
DATA1=RS232_BUFFER
DATA_COUNT=DATA_COUNT-1
WAIT 1 MS
SET CTS OFF
RETURN
END IF
IF X_REG=1 AND DATA_COUNT=4 AND RS232_BUFFER<10 THEN
DATA2=RS232_BUFFER
DATA_COUNT=DATA_COUNT-1
WAIT 1 MS
SET CTS OFF
RETURN
END IF
IF X_REG=1 AND DATA_COUNT=3 AND RS232_BUFFER<10 THEN
DATA3=RS232_BUFFER
DATA_COUNT=DATA_COUNT-1
WAIT 1 MS
SET CTS OFF
RETURN
END IF
IF X_REG=1 AND DATA_COUNT=2 AND RS232_BUFFER<10 THEN
DATA4=RS232_BUFFER
DATA_COUNT=DATA_COUNT-1
WAIT 1 MS
SET CTS OFF
RETURN
END IF
IF X_REG=1 AND DATA_COUNT=1 AND RS232_BUFFER<10 THEN
DATA5=RS232_BUFFER
DATA_COUNT=DATA_COUNT-1
SET CTS ON
SET MOVE_FLAG ON
SET X_REG OFF
RETURN
END IF
IF RS232_BUFFER=0XFA THEN
SET CTS ON
WAIT 1 MS
DO WHILE CTS_Z=1
SET CTS ON
LOOP
WAIT 1 MS
SET CTS OFF
RETURN
END IF
IF RS232_BUFFER<>0XFF OR RS232_BUFFER<>ADD_REG OR RS232_BUFFER<>0XFE AND DATA_COUNT=0 OR X_REG=0 THEN
SET CTS ON
WAIT 1 MS
DO WHILE CTS_Z=1
SET CTS ON
LOOP
WAIT 1 MS
SET CTS OFF
RETURN
END IF
END SUB
SUB MOTOR_JAM
PORTA=0
SET MOVE_FLAG OFF
SET HOME_FLAG OFF
SET PIE1.RCIE OFF
HSERSEND ADD_REG
HSERSEND 200
END SUB
END
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am sure why you want to predetermine your memory addresses - can you share your thoughts?
But, if you want to specific an memory location please see below the line DIM DATA5 AS BYTE at 0x23.
#CHIP 16F628
#CONFIG OSC=INT, BODEN_ON, PWRT_ON
#DEFINE CTS PORTB.3
#DEFINE CTS_Z PORTA.5
DIM X_REG AS BIT
DIM HOME_FLAG AS BIT
DIM MOVE_FLAG AS BIT
DIM SIGN AS BIT
DIM EMERG_FLAG AS BIT
DIM DATA5 AS BYTE at 0x23
...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I wasn't aware of that way to designate a memmory address, thank you for letting me know, but still it's not a solution.
My problem isn't that I want to use specific adressess for my registers, rather that I want to correct the addresses that the compiler gives to its own registers for delays, etc. and that's why I posted about the compiler error I get.
If you get a look at the ASM (below), that the compiler produces for the basic program I posted, there are almost no single registers, most registers have the same memory address, and thas has as result that the program responds unexpectedly or fails.
Since I cannot predetermine which addresses the compiler will give to its own registers, I am trying to corect them at the ASM file and the compile the corrected asm, but when I compile the ASM file I get the error I posted it first place.
I don't know if I explained it in an undestandable way. Please let me know if you want any additional information.
Thank you. I do not understand what is the root cause of the error that is causing you to define your own address scheme. You can determine every address if really needed by redefining the memory addressing across all of GCB but that would make a very specific chip solution of GCB.
So, I think, that I do not understand the why you want to do this. If there is an error then we should resolve the root cause of the issue. Help me understand.
A few comments on the GCB that I WOULD change as your current code may not operate as expected.
TEMP=DATA12000+DATA2200+DATA320+DATA42+DATA5 change this to a single instruction per line, to
TEMP=DATA12000
TEMP=TEMP + (DATA2200)
etc.
Use multi lines for instances like
-- IF RS232_BUFFER<>0XFF OR RS232_BUFFER<>ADD_REG OR RS232_BUFFER<>0XFE AND DATA_COUNT=0 OR X_REG=0 THEN
-- IF X_REG=1 AND RS232_BUFFER=0XAA AND DATA_COUNT=6 THEN
Let me know, help to listen and help. :-)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The program is controlling an axis of a CNC. It get directions from serial port and then moves to desired position which is aquired by external linear encoder. Now the "conflicting" regisrters cause sometimes unpredicted or non stop movement.
It is my understanding that either the delay goes too high between subsequent checks or something similar. I havent pointed out which exact overlap causes the problem, but I am thinking that if for instance I have a delay of 1ms, and then delaytemp (address 112) is loaded e.g with 1, and then after an interrupt it gets the value of e.g. SysByteTempX (also address 112) that hold 255, then automaticaly the delay is multiplied. Thus, I was thinking that if I correct the addreess that compiler assert in the asm file (since I cannot do it in the basic file), the program should work fine.
How would it be possible to redefine the memory addressing? Perhaps, I could backup the original file that maps the memory and use the altered one with the corrected addresses only for that instance.
Also, I don't know if you are developer of the GCB, but what I have figured out is that the compiler is trying to use the mapped adresses of the RAM (i.e. the ones that are accessed from all memory banks) to avoid checking the bank each time it wants to read the register content. Now, I believe that the developers have assigned those specific adrresses for each function. In this case with PIC16F268, that has 16 bytes of mapped addresses and the compiler needs more than those it re-assigns the same address for diferent register.
I don't know if the above help any more to get some conclusion.
I will try your comments to see if there will be any impovement.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I forgot to ask you. Do you have any idea why I get that error when I am compiling the ASM file?
I have also copied the inc file to the Great Cow Basic folder, but still gives the chip not specified error.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Interesting problems. Very interesting. I build a Five Asix robot two years ago and had lot of similar issues.
Looking at your code I would think you are simply missing data instructions. I would change the interrupt to a buffer ring and then handle consumption of the data within the main body of the code. So, essentially, get in and out of the interrupt as fast as practical - you have (from my experience) too much code and therefore time in the interrupt routine.
Now, to answer your explicit questions. I will get you an answer as I cannot figure out how these address are being assigned. Two of the variables are assigned in system.h but there is a bank of reused memory locations as you state. Leave that with me please.
And the ASM error. Have you tried compiling in MPLAB? This works for me with Uppercase detection turn off.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I don't think I am missing incoming data because I have implemented hardware hanshacking and also the reason I am doing all that check within the interrupt is because I have three axis in total with independent controllers which run quite similar programs.
If you can see at the program, upon the UART interrupt occurs the microcontroller dissables data transmition from the PC (CTS line is set off)so until any of the controllers can accept data the CTS is held low.
Of course I don't know if the PC manages to send additional data before it reads the CTS line, but for that reason I have added some delay to the PC before it will send the next data package, plus I instruct the PC to wait until it reads back the position of each axis before it proceeds.
I haven't tried a buffer ring but I think I whould have to make additional checks to determine if the incoming data is for the specific microcontroller or for some other axis.
Since I will have to read all data first, then determine if it is for that microcontroller and if they have correct format, that might cause some problem in case one microcontroller get correct data, but some other gets wrong data.
I will give it a try with the MPLAB, but I think I will have to rewritew all numbers because as I can recall MPLAB doesn't recognize the raw numbers in decimal format but need to be writen as d'number', also since I will change the addresses I will have to add some code to the assembly to check the memory bank before I access the registers.
If you are a developer of the GCB I have to congratulate you about that effort and good work. It's a great tools. I don't think I could manage to write all that code in assembly or if it eventually would work.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
@Nikolas. I have been thinking. Let me look at your latest GCB code. Post as an attachment and I will code review for you.
I am thinking that you do need a state engine to make this work correctly. When I build my five axis robot with serial as the communications methods I had lots of issues with synchronisation and control of the comms lines. I used CTS/RTS also. It should be possible to create a solution where timing is only controlled from the main body of the program to prevent timing loops being interrupted by incoming data.
If you have moved on (code wise) then ignore me! :-)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
What exactly do you mean with the term state engine?
I am attaching the code.
There some alterations, but in general is almost the same.
As I was checking the assembly code, I realized that if some how I manage to minimize the variables that need to be stored temporally while the program services the interrupt, I will get rid off of the conflicting addresses issue.
Simultaneously I am working at the PC program, because I am having some issues with communication in general.
I think that PCs are not very "willing" to work with serial port in simple terms but rather in complicate fashion.
Once again, thank you very much for your help. I really appreciate it.
I was thinking the same about the interrupt. Minimal code, minimise usage. I can easily see cases where the interrupt is simply overwriting other variables. Timing needs to pushed into a stack and popped back to keep your code/approach stable. OK. I will have to look tomorrow. Lots of people visiting today! Do you want to repost code tomorrow?
I will send you my Serial Comms program. It is written in PERL, so, you can easily change. I used a text program for my XYZAB axis then processed so PERL could manage the comms between the robot and the computer. Interested in this PERL approach/code?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am not familiar with PERL, but if it easy understandable such basic, i.e the command are quite straight foreword, so that I can make transpose to basic it would be more than welcome.
I will repost the code tomorrow with any alteration I make do.
It is Friday so for the hobbyists is time to get that microcontroller running...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello Anobium.
Sorry, for not replying earlier but during weekend I couldn't load the page and from Monday I had a busy week in work.
I have re attached the code. I have made some alteration that reduce the code within the interrupt, actually it reduced the code for 200bytes aprox. but no luck with the overlapping registers.
If you have any suggestion the are over welcome.
This uses create a buffer of incoming RS232 data. Then when a byte arrives your code simply handles as you have coded. The benefit should be that the interrupt will not mess with your timing variables.
This creates a buffer of incoming RS232 data. Then, when a byte arrives your code simply handles as you have coded. The benefit should be that the interrupt will not mess with your timing variables.
Sorry for the late response. I was away for my work and didn't have time to respond.
The approach with your code, althought is more stable considering that the interrupt service routine is very short, in my instance has a kind of "flaw" since there are instances that there might be some special single byte commands between normal data. In such case the mcu won't be aware of that because it will wait for all data to arrive before it makes the check. Since there won't be any more in comming data, the microcontroller won't respond.
I solved my issue by changing the addresses in the asm file and added some bank select directives when reading and writing to those registers, just to avoid any unesired resets.
Perhaps, I will retry your approach by modifing the PC program to send multi byte commands instead of single bytes for special functions.
Thank you very much for all your help and yor effort to improve my code.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello,
I am facing an error when I try to make a hex file from asm with 16f628 microcontroller.
Althought the hex is compiled directly from the bas file, when I try to built the asm file, I get the
error: Chip model not specified! GCBASIC cannot continue.
Now, I don't want to built the bas file direclty because there is probably some bug with the registers' addresses that the compiler designates, and some addresses overlap, so I want to correct them and then build the corrected assembly file.
Has anybody faced the same problem?
Thanks in advance for any help.
Nikolas
Welcome to GCB.
Can you post your ASM file? This can work if the ASM is formatted correctly.
Dear Anobium,
Thank you. I am glad to be here.
The code is about 1,2k. I quote it bellow.
As you can see there are a lot of overlapping registers and that cause the program to run unexpectably at some points.
As far as it concern the format, I tried to format the code as in MPLAB, i.e. no # before include or without the brackets, but I get the saem error.
Last edit: Anobium 2014-08-20
Dear Anobium,
Thank you. I am glad to be here.
The code is about 1,2k. I quote it bellow.
As you can see there are a lot of overlapping registers and that cause the program to run unexpectably at some points.
As far as it concern the format, I tried to format the code as in MPLAB, i.e. no # before include or without the brackets, but I get the saem error.
Last edit: Anobium 2014-08-20
I am really sorry. i am not that kenn with forums, I wanted to make a correction and re-posted the whole message by mistake.
I am sorry too. I thought you were compiling ASM within GCB not using Great Cow Basic.
Please post your GCB source file. That should tell us where the issue is.
Bellow is the basic file.
In fact, I am trying to compile the asm file, through GCB@syn.
I am compiling the basic file, and then I am trying to compile the produced asm file, because I want to correct the variables' addresses.
Please note that the if I compile the basic file, it will produce the HEX file, but since there is the addresses issue, I want to make the corrections to the ASM file and then compile the ASM file and then is when I get the error.
Perhaps, instead of trying to compile the ASM, file there is some way to alter the adrresses that the compiler asserts to the variables?
I tried to define the variables' address with inline assembly(see bolt text: asm DATA5 equ 0x23), but the compiler will designate the address by its on and then it will insert my equ instruction, thus it will set the variable in two different addresses.
"#CHIP 16F628"
"#CONFIG OSC=INT, BODEN_ON, PWRT_ON"
"#DEFINE CTS PORTB.3"
"#DEFINE CTS_Z PORTA.5"
DIM X_REG AS BIT
DIM HOME_FLAG AS BIT
DIM MOVE_FLAG AS BIT
DIM SIGN AS BIT
DIM EMERG_FLAG AS BIT
DIM DATA5 AS BYTE
asm DATA5 equ 0x23
DIM DATA4 AS BYTE
DIM DATA3 AS BYTE
DIM DATA2 AS BYTE
DIM DATA1 AS BYTE
DIM POSITION AS WORD
DIM POSITION1 AS BYTE
DIM POSITION2 AS BYTE
DIM POSITION3 AS BYTE
DIM POSITION4 AS BYTE
DIM POSITION5 AS BYTE
DIM INDEX AS BYTE
DIM RS232_BUFFER AS BYTE
DIM ADD_REG AS BYTE
DIM TEMP AS WORD
DIM DATA_COUNT AS BYTE
ADD_REG=252
SET X_REG OFF
DATA_COUNT=0X00
DATA3=0X00
DATA2=0X00
DATA1=0X00
TRISA= 0B11100000
TRISB= 0B11110011
PORTA=0B00000000
PORTB=0B00000000
SET HOME_FLAG OFF
SET MOVE_FLAG OFF
SET EMERG_FLAG OFF
DO UNTIL PORTB.0=0
LOOP
WAIT 100 MS
DO UNTIL PORTB.0=1
LOOP
"#DEFINE USART_BAUD_RATE 9600"
ON INTERRUPT USARTRX1READY CALL RS232_IN
INITTIMER0 OSC, PS0_256
ON INTERRUPT TIMER0OVERFLOW CALL MOTOR_JAM
SET PORTA.4 OFF
SET CTS OFF
MAIN:
IF MOVE_FLAG=0 AND CTS_Z=1 THEN
SET CTS ON
END IF
IF MOVE_FLAG=0 AND CTS_Z=0 THEN
WAIT 1 MS
SET CTS OFF
END IF
IF HOME_FLAG=1 THEN
CALL HOME
END IF
IF MOVE_FLAG=1 THEN
CALL MOVE
END IF
IF EMERG_FLAG=1 THEN
SET CTS ON
PORTA=0
WAIT 100 US
PORTA=0B00010101
WAIT 100 US
PORTA=0
DO UNTIL PORTB.0=0
PORTA=0
LOOP
WAIT 100 MS
DO UNTIL PORTB.0=1
LOOP
SET EMERG_FLAG OFF
CALL HOME
END IF
GOTO MAIN
SUB MOVE
END SUB
SUB MOVE_BACK
CONTINUE_BACK_1:
END SUB
SUB MOVE_FORW
CONTINUE_FORW_1:
POSITION=POSITION+1
END SUB
SUB HOME
SET CTS ON
HOME1:
PORTA=0B00010110
IF EMERG_FLAG=1 THEN
SET HOME_FLAG OFF
RETURN
END IF
IF PORTB.7=0 AND PORTB.6=0 AND PORTB.5=1 THEN
GOTO HOME2
END IF
GOTO HOME1
HOME2:
IF EMERG_FLAG=1 THEN
SET HOME_FLAG OFF
RETURN
END IF
PORTA=0B00010000
WAIT 100 US
PORTA=0B00010101;FRENO
WAIT 100 US
PORTA=0B00000000
INDEX=0
WAIT 1000 MS
DO WHILE INDEX<2
IF EMERG_FLAG=1 THEN
SET HOME_FLAG OFF
RETURN
END IF
PORTA=0B00011001
IF PORTB.6=1 AND PORTB.7=1 AND PORTB.5=1 THEN
INDEX=INDEX+1
END IF
LOOP
PORTA=0B00010000
WAIT 100 US
PORTA=0B00010101
WAIT 100 US
PORTA=0B00000000
POSITION1=0
POSITION2=0
POSITION3=0
POSITION4=0
POSITION5=0
SET HOME_FLAG OFF
DO WHILE CTS_Z=1
LOOP
WAIT 1 MS
SET CTS OFF
END SUB
SUB RS232_IN
SET CTS ON
HSERRECEIVE RS232_BUFFER
END SUB
SUB MOTOR_JAM
END SUB
END
I am sure why you want to predetermine your memory addresses - can you share your thoughts?
But, if you want to specific an memory location please see below the line DIM DATA5 AS BYTE at 0x23.
I wasn't aware of that way to designate a memmory address, thank you for letting me know, but still it's not a solution.
My problem isn't that I want to use specific adressess for my registers, rather that I want to correct the addresses that the compiler gives to its own registers for delays, etc. and that's why I posted about the compiler error I get.
If you get a look at the ASM (below), that the compiler produces for the basic program I posted, there are almost no single registers, most registers have the same memory address, and thas has as result that the program responds unexpectedly or fails.
Since I cannot predetermine which addresses the compiler will give to its own registers, I am trying to corect them at the ASM file and the compile the corrected asm, but when I compile the ASM file I get the error I posted it first place.
I don't know if I explained it in an undestandable way. Please let me know if you want any additional information.
DELAYTEMP EQU 112
DELAYTEMP2 EQU 113
SYSDIVMULTA EQU 119
SYSDIVMULTA_H EQU 120
SYSDIVMULTB EQU 123
SYSDIVMULTB_H EQU 124
SYSDIVMULTX EQU 114
SYSDIVMULTX_H EQU 115
SysBYTETempA EQU 117
SysBYTETempB EQU 121
SysByteTempX EQU 112
SysDivLoop EQU 116
SysSTATUS EQU 127
SysW EQU 126
SysWORDTempA EQU 117
SysWORDTempA_H EQU 118
SysWORDTempB EQU 121
SysWORDTempB_H EQU 122
SysWORDTempX EQU 112
SysWORDTempX_H EQU 113
SysWaitTempMS EQU 114
SysWaitTempMS_H EQU 115
SysWaitTempUS EQU 117
SysWaitTempUS_H EQU 118
Thank you. I do not understand what is the root cause of the error that is causing you to define your own address scheme. You can determine every address if really needed by redefining the memory addressing across all of GCB but that would make a very specific chip solution of GCB.
So, I think, that I do not understand the why you want to do this. If there is an error then we should resolve the root cause of the issue. Help me understand.
A few comments on the GCB that I WOULD change as your current code may not operate as expected.
TEMP=DATA12000
TEMP=TEMP + (DATA2200)
etc.
-- IF RS232_BUFFER<>0XFF OR RS232_BUFFER<>ADD_REG OR RS232_BUFFER<>0XFE AND DATA_COUNT=0 OR X_REG=0 THEN
-- IF X_REG=1 AND RS232_BUFFER=0XAA AND DATA_COUNT=6 THEN
Let me know, help to listen and help. :-)
Thanks for you willing to help.
The program is controlling an axis of a CNC. It get directions from serial port and then moves to desired position which is aquired by external linear encoder. Now the "conflicting" regisrters cause sometimes unpredicted or non stop movement.
It is my understanding that either the delay goes too high between subsequent checks or something similar. I havent pointed out which exact overlap causes the problem, but I am thinking that if for instance I have a delay of 1ms, and then delaytemp (address 112) is loaded e.g with 1, and then after an interrupt it gets the value of e.g. SysByteTempX (also address 112) that hold 255, then automaticaly the delay is multiplied. Thus, I was thinking that if I correct the addreess that compiler assert in the asm file (since I cannot do it in the basic file), the program should work fine.
How would it be possible to redefine the memory addressing? Perhaps, I could backup the original file that maps the memory and use the altered one with the corrected addresses only for that instance.
Also, I don't know if you are developer of the GCB, but what I have figured out is that the compiler is trying to use the mapped adresses of the RAM (i.e. the ones that are accessed from all memory banks) to avoid checking the bank each time it wants to read the register content. Now, I believe that the developers have assigned those specific adrresses for each function. In this case with PIC16F268, that has 16 bytes of mapped addresses and the compiler needs more than those it re-assigns the same address for diferent register.
I don't know if the above help any more to get some conclusion.
I will try your comments to see if there will be any impovement.
I forgot to ask you. Do you have any idea why I get that error when I am compiling the ASM file?
I have also copied the inc file to the Great Cow Basic folder, but still gives the chip not specified error.
Interesting problems. Very interesting. I build a Five Asix robot two years ago and had lot of similar issues.
Looking at your code I would think you are simply missing data instructions. I would change the interrupt to a buffer ring and then handle consumption of the data within the main body of the code. So, essentially, get in and out of the interrupt as fast as practical - you have (from my experience) too much code and therefore time in the interrupt routine.
Now, to answer your explicit questions. I will get you an answer as I cannot figure out how these address are being assigned. Two of the variables are assigned in system.h but there is a bank of reused memory locations as you state. Leave that with me please.
And the ASM error. Have you tried compiling in MPLAB? This works for me with Uppercase detection turn off.
I don't think I am missing incoming data because I have implemented hardware hanshacking and also the reason I am doing all that check within the interrupt is because I have three axis in total with independent controllers which run quite similar programs.
If you can see at the program, upon the UART interrupt occurs the microcontroller dissables data transmition from the PC (CTS line is set off)so until any of the controllers can accept data the CTS is held low.
Of course I don't know if the PC manages to send additional data before it reads the CTS line, but for that reason I have added some delay to the PC before it will send the next data package, plus I instruct the PC to wait until it reads back the position of each axis before it proceeds.
I haven't tried a buffer ring but I think I whould have to make additional checks to determine if the incoming data is for the specific microcontroller or for some other axis.
Since I will have to read all data first, then determine if it is for that microcontroller and if they have correct format, that might cause some problem in case one microcontroller get correct data, but some other gets wrong data.
I will give it a try with the MPLAB, but I think I will have to rewritew all numbers because as I can recall MPLAB doesn't recognize the raw numbers in decimal format but need to be writen as d'number', also since I will change the addresses I will have to add some code to the assembly to check the memory bank before I access the registers.
If you are a developer of the GCB I have to congratulate you about that effort and good work. It's a great tools. I don't think I could manage to write all that code in assembly or if it eventually would work.
@Nikolas. I have been thinking. Let me look at your latest GCB code. Post as an attachment and I will code review for you.
I am thinking that you do need a state engine to make this work correctly. When I build my five axis robot with serial as the communications methods I had lots of issues with synchronisation and control of the comms lines. I used CTS/RTS also. It should be possible to create a solution where timing is only controlled from the main body of the program to prevent timing loops being interrupted by incoming data.
If you have moved on (code wise) then ignore me! :-)
What exactly do you mean with the term state engine?
I am attaching the code.
There some alterations, but in general is almost the same.
As I was checking the assembly code, I realized that if some how I manage to minimize the variables that need to be stored temporally while the program services the interrupt, I will get rid off of the conflicting addresses issue.
Simultaneously I am working at the PC program, because I am having some issues with communication in general.
I think that PCs are not very "willing" to work with serial port in simple terms but rather in complicate fashion.
Once again, thank you very much for your help. I really appreciate it.
I was thinking the same about the interrupt. Minimal code, minimise usage. I can easily see cases where the interrupt is simply overwriting other variables. Timing needs to pushed into a stack and popped back to keep your code/approach stable. OK. I will have to look tomorrow. Lots of people visiting today! Do you want to repost code tomorrow?
I will send you my Serial Comms program. It is written in PERL, so, you can easily change. I used a text program for my XYZAB axis then processed so PERL could manage the comms between the robot and the computer. Interested in this PERL approach/code?
I am not familiar with PERL, but if it easy understandable such basic, i.e the command are quite straight foreword, so that I can make transpose to basic it would be more than welcome.
I will repost the code tomorrow with any alteration I make do.
It is Friday so for the hobbyists is time to get that microcontroller running...
Hello Anobium.
Sorry, for not replying earlier but during weekend I couldn't load the page and from Monday I had a busy week in work.
I have re attached the code. I have made some alteration that reduce the code within the interrupt, actually it reduced the code for 200bytes aprox. but no luck with the overlapping registers.
If you have any suggestion the are over welcome.
Have a nice day.
Last edit: Nikolas Dimitriadis 2014-08-27
Have a look at this approach.
This uses create a buffer of incoming RS232 data. Then when a byte arrives your code simply handles as you have coded. The benefit should be that the interrupt will not mess with your timing variables.
Let us know the results. :-)
Have a look at this approach.
This creates a buffer of incoming RS232 data. Then, when a byte arrives your code simply handles as you have coded. The benefit should be that the interrupt will not mess with your timing variables.
Let us know the results. :-)
Last edit: Anobium 2014-08-29
Hello Anobium,
Sorry for the late response. I was away for my work and didn't have time to respond.
The approach with your code, althought is more stable considering that the interrupt service routine is very short, in my instance has a kind of "flaw" since there are instances that there might be some special single byte commands between normal data. In such case the mcu won't be aware of that because it will wait for all data to arrive before it makes the check. Since there won't be any more in comming data, the microcontroller won't respond.
I solved my issue by changing the addresses in the asm file and added some bank select directives when reading and writing to those registers, just to avoid any unesired resets.
Perhaps, I will retry your approach by modifing the PC program to send multi byte commands instead of single bytes for special functions.
Thank you very much for all your help and yor effort to improve my code.
Not a problem. Keep at it.
:-)