📄 sss.txt
字号:
'first try basic/assembler jet engine control unit
'all the time-critical subroutines (interrupts) are written in assembler
'the more complex functions (math etc) are in basic for comfort
'functions of first version:
'-evaluates single channel (throttle)
'-monitors RPM, EGT, Supply voltage
'-uses acceleration ramp and predefined values for engine control
'-monitors for missing/unplausible ppm signal
'-incorporates basic safety functions
'define all i/o pin functions. all functions are positive logic except otherwise noted
egtin var porta.0 'exhaust gas temperature input
tambin var porta.1 'ambient temperature input (currently not used)
vccin var porta.2 'supply voltage monitoring input
rpmin var porta.4 'rpm signal counter input
ignout var portb.0 'ignition output - reverse logic (currently not used)
lightout var portb.1 'warning/status light output
gasout var portb.2 'solenoid propane valve output (currently not used)
thrtlin var portb.4 'throttle ppm input - reverse logic
cntlin var portb.5 'control ppm input - reverse logic (currently not used)
strtout var portc.1 'starter motor pwm output (currently not used)
pumpout var portc.2 'fuel pump pwm output
i2cscl var portc.3 'serial clock for i2c bus (currently not used)
i2csda var portc.4 'serial data for i2c bus (currently not used)
232txd var portc.6 'rs232 transmit data line
232rxd var portc.7 'rs232 receive data line
equ rbbak ; zustand von port b t-1
equ cntl1 ; kanalz鋒ler 1 low
equ cnth1 ; kanalz鋒ler 1 high
equ cntl1bk ; kanalz鋒ler 1 low t-1
equ cnth1bk ; kanalz鋒ler 1 high t-1
equ cntl2 ; kanalz鋒ler 2 low
equ cnth2 ; kanalz鋒ler 2 high
equ cntl2bk ; kanalz鋒ler 2 low t-1
equ cnth2bk ; kanalz鋒ler 2 high t-1
equ chn1 ; kanal schub
equ chn1bk ; kanal schub t-1
equ chn2 ; kanal status
equ chn2bk ; kanal status t-1
equ scalemul ; skalierungsmultiplikator f黵 pulsdauer
equ sclofsl ; skalierungsoffset low f黵 pulsdauer
equ sclofsh ; skalierungsoffset high f黵 pulsdauer
goto start 'skip around interrupt handler
'*********start of interrupt service routine**********************
define inthand isr 'define interrupt handler
asm 'start assembly language
isr movwf wsave ;save machine registers
swapf STATUS, W ;
clrf STATUS ;
movwf ssave ;
movf PCLATH, W ;
movwf psave ;
;determine source of interrupt
btfsc INTCON,T0IF ;
goto emgstop ; -> severe overspeed - do emergency stop
btfsc INTCON,RBIF ;
goto rcpls ; -> r/c-pulse length determination
btfsc PIR1,TMR1IF ;
goto tick ; -> do everything that needs to be done periodically
btfsc PIR1,RCIF ;
goto commrx ; -> communications receive routine
btfsc pir1,txif ;
goto commtx ; -> communications transmit routine
btfsc pir1,adif ;
goto adisr ; -> a/d converter interrupt service routine
;emergency stop is executed in main program, the isr only sets the appropriate flag
emgstop bsf flag,stop ; set engine stop flag
goto endisr ; -> endisr
;auswertung der rc-pulsl鋘gen auf port b.4 und 5
;rc1 (kanal schub) wird mit 16bit ausgewertet und auf 8bit skaliert.
;rc2 (kanal status) wird mit 16bit ausgewertet und auf 8bit reduziert.
;beim 黚erlauf des z鋒lers werden die werte verworfen, um zeit zu sparen.
rcpls bcf INTCON,RBIF ; clear interrupt flag
movf PORTB,0 ; load port b
xorwf rbbak,1 ; xor (port b, port b[t-1])
btfsc rbbak,4 ; level of throttle channel changed?
goto rc1 ; (yes) -> rc1
btfsc rbbak,5 ; level of status channel changed?
goto rc2 ; (yes) -> rc2
goto endrc ; -> endrc
rc1 btfss thrtlin ; throttle level = 0 ?
goto rc1l ; (yes) -> rc1l
bcf T1CON,TMR1ON ; stop timer 1
movf TMR1L,0 ; load timer 1,l
movwf cntl1 ; store to channel counter t,l
movf TMR1H,0 ; load timer 1,h
movwf cnth1 ; store to channel counter t,h
bsf T1CON,TMR1ON ; start timer 1
movf cntl1bk,0 ; subtract counter readings of rising and
subwf cntl1,1 ; falling edge to get duration of ppm pulse.
btfss STATUS,C ; if wrap-around occurred between the two
incf cnth1bk,1 ; redings, the result is negative but this
movf cnth1bk,0 ; doesn't matter due to the 2's complement
subwf cnth1,1 ; method of subtraction.
goto out1 ; (yes) -> out1
rc1l bcf T1CON,TMR1ON ; stop timer 1
movf TMR1L,0 ; load timer 1,l
movwf cntl1bk ; store to channel counter t-1,l
movf TMR1H,0 ; load timer 1,h
movwf cnth1bk ; store to channel counter t-1,h
bsf T1CON,TMR1ON ; start timer 1
goto endrc ; -> endrc
rc2 btfss thrtlin ; throttle level = 0 ?
goto rc2l ; (yes) -> rc1l
bcf T1CON,TMR1ON ; stop timer 1
movf TMR1L,0 ; load timer 1,l
movwf cntl2 ; store to channel counter t,l
movf TMR1H,0 ; load timer 1,h
movwf cnth2 ; store to channel counter t,h
bsf T1CON,TMR1ON ; start timer 1
movf cntl2bk,0 ; load channel counter t-1,l
subwf cntl2,1 ; cntl1 = cntl1 - cntl1bk
btfss STATUS,C ; result negative ?
incf cnth2bk,1 ; (yes) cnth1bk = cnth1bk + 1
movf cnth2bk,0 ; load channel counter t-1,h
subwf cnth2,1 ; cnth1 = cnth1 - cnth1bk - \c
goto out2 ; (yes) -> out2
rc2l bcf T1CON,TMR1ON ; stop timer 1
movf TMR1L,0 ; load timer 1,l
movwf cntl2bk ; store to channel counter t-1,l
movf TMR1H,0 ; load timer 1,h
movwf cnth2bk ; store to channel counter t-1,h
bsf T1CON,TMR1ON ; start timer 1
goto endrc ; -> endrc
; here the raw pulse length values are made available to the main control
; program, as well the mean "jitter" and repetition rate are evaluated to
; determine the signal quality.
out1 movf cntl1,0 ; load channel counter t,l
subwf rcrawl1,1 ; rcrawl1 = rcrawl1 - cntl1
btfss STATUS,C ; result negative ?
incf rcrawh1,1 ; (yes) rcrawh1 = rcrawh1 + 1
movf cnth1,0 ; load channel counter t,h
subwf rcrawh1,1 ; rcrawh1 = rcrawh1 - cnth1 - \c
btfsc STATUS,C ; result positive?
goto posdif1 ; (yes) -> posdif1
comf rcrawh1,1 ; complement rcrawh1
incf rcrawh1,1 ; rcrawh1 = rcrawh1 + 1
comf rcrawl1,1 ; complement rcrawl1
incf rcrawl1,1 ; rcrawl1 = rcrawl1 + 1
btfsc status,c ; carry set?
incf rcrawh1,1 ; (yes) rcrawh1 = rcrawh1 + 1
posdif1 movf rcrawl1,0 ; load rcrawl1
addwf rcdifl1,1 ; rcdifl1 = rcdifl1 + rcrawl1
btfsc status,c ; carry set?
incf rcrawh1,1 ; rcrwah1 = rcrawh1 + 1
movf rcrawh1,0 ; load rcrawh1
addwf rcdifh1,1 ; rcdifh1 = rcdifh1 + rcrawh1 + c
movf cntl1,0 ; load cntl1
movwf rcrawl1 ; rcrawl1 = cntl1 (for export)
movf cnth1,0 ; load cnth1
movwf rcrawh1 ; rcrawh1 = cnth1 (for export)
incf ppmcnt1,1 ; ppmcnt1 = ppmcnt1 + 1
goto endrc ; -> endrc
out2 movf cntl2,0 ; load channel counter t,l
subwf rcrawl2,1 ; rcrawl2 = rcrawl2 - cntl2
btfss STATUS,C ; result negative ?
incf rcrawh2,1 ; (yes) rcrawh2 = rcrawh2 + 1
movf cnth2,0 ; load channel counter t,h
subwf rcrawh2,1 ; rcrawh2 = rcrawh2 - cnth2 - \c
btfsc STATUS,C ; result positive?
goto posdif2 ; (yes) -> posdif2
comf rcrawh2,1 ; complement rcrawh2
incf rcrawh2,1 ; rcrawh1 = rcrawh2 + 1
comf rcrawl2,1 ; complement rcrawl2
incf rcrawl2,1 ; rcrawl1 = rcrawl2 + 1
btfsc status,c ; carry set?
incf rcrawh2,1 ; (yes) rcrawh1 = rcrawh2 + 1
posdif2 movf rcrawl2,0 ; load rcrawl2
addwf rcdifl2,1 ; rcdifl2 = rcdifl2 + rcrawl2
btfsc status,c ; carry set?
incf rcrawh2,1 ; rcrwah2 = rcrawh2 + 1
movf rcrawh2,0 ; load rcrawh2
addwf rcdifh2,1 ; rcdifh2 = rcdifh2 + rcrawh2 + c
movf cntl2,0 ; load cntl2
movwf rcrawl2 ; rcrawl2 = cntl2 (for export)
movf cnth2,0 ; load cnth2
movwf rcrawh2 ; rcrawh2 = cnth2 (for export)
incf ppmcnt2,1 ; ppmcnt2 = ppmcnt2 + 1
endrc movf PORTB,0 ; load port b
movwf rbbak ; store to rbbak
goto endisr ; -> endisr
; tick stores the rpm counter value into rpmcnt to make it available to the main
; program and sets the tmrof flag to notify to the main program (basic) that
; a new set of pwm values needs to be calculated
tick bcf pir1,tmr1if ; clear timer 1 interrupt flag
movf tmr0,w ; move timer 0 contents
movwf rpmcnt ; to rpmcnt
clrf tmr0 ; reset timer 0
bcf t0if ; clear timer 0 interrupt flag
bsf flag,tmrof ; set timer1 overflow flag
goto endisr ; -> endisr
; the communications receive routine sets the appropriate flag to enter interactive mode
commrx bcf pir1,rcif ; clear rxd interrupt flag
bsf flag,rxflag ; set receive flag
goto endisr ; -> endisr
; the communications transmit routine should (once it's finished) circulate through the
; diagnostic parameters to be transmitted to the host or display unit. but not yet ;-)
commtx bcf pir1,txif ; clear txd interrupt flag
bsf flag,txflag ; set transmit flag
goto endisr ; -> endisr
; adisr will cycle through the analog inputs and load the appropriate a/d results into
; variables to transfer them to the main program.
adisr bcf pir1,adif ; clear a/d interrupt flag
egt movf adcnt,w ; egt routine (adc channel 0)
xorlw 'h0000' ;
btfss status,z ;
goto amb ;
movf adresh,w ;
movwf egth ;
bsf status,rp0 ; register bank 1
movf adresl,w ;
movwf egtl ;
bcf status,rp0 ; register bank 0
amb movf adcnt,w ; tamb routine (adc channel 1)
xorlw 'h0008' ;
btfss status,z ;
goto vbat ;
movf adresh,w ;
movwf ambh ;
bsf status,rp0 ; register bank 1
movf adresl,w ;
movwf ambl ;
bcf status,rp0 ; register bank 0
vbat movf adcnt,w ; vbat routine (adc channel 2)
xorlw 'h0010' ;
btfss status,z ;
goto exad ;
movf adresh,w ;
movwf vbath ;
bsf status,rp0 ; register bank 1
movf adresl,w ;
movwf vbatl ;
bcf status,rp0 ; register bank 0
exad movlw 'h0008' ;
addwf adcnt,f ; adcnt = adcnt + 8
movf adcnt,w ;
xorlw 'h0018' ;
btfsc status,z ;
clrf adcnt ; if adcnt = 18h then adcnt = 0
movlw 'h00c7' ;
andwf adcon0,f ; clear chs0-chs2 of adcon0
movf adcnt,w ;
iorwf adcon0,f ; set chs0-chs2 of adcon0 according to adcnt
bsf adcon0,go ; start new a/d conversion
; goto endisr ; -> endisr
endisr movf psave,W ; restore saved registers
movwf PCLATH ;
swapf ssave,W ;
movwf STATUS ;
swapf wsave, F ;
swapf wsave, W ;
retfie ; Return from interrupt
endasm
'*********end of interrupt service routine************************
'initialisation is written in assembler because it isn't any more complicated
'but results in much more compact code than in basic
asm
init movlw 'h0001' ;
movwf PORTB ; ignition and transistors off
movlw 'h00d8 ;
movwf PORTC ; pwm transistors off
bsf STATUS,RP0 ; select register bank 1
movlw 'h00ff' ;
movwf TRISA ; set port a as input
movlw 'h0030' ;
movwf TRISB ; set port b 0-3,6,7 as output; 4,5 as input
movlw 'h00d8' ;
movwf TRISC ; set port c 0-2,5 as output; 3,4,6,7 as input
movlw 'h003f' ;
movwf OPTION ; attach presc to wdt 1:128, activate rb pull-up, timer 0 external
movlw 'h0071' ;
movwf PIE1 ; activate timer 1, a/d, usart rx/tx interrupts
clrf PIE2 ; deactivate timer 2 interrupt
movlw 'h00ff' ;
movwf PR2 ; set pwm module to 10 bit resolution
movlw 'h0002' ;
movwf TXSTA ; ser. async., low speed, txd off
movlw 'h000c' ;
movwf SPBRG ; set baud-rate to 9.615 (fosc = 8Mhz)
movlw 'h0082' ;
movwf ADCON1 ; set ra0-ra3,ra5 as analog input, vdd as reference
bcf STATUS,RP0 ; select register bank 0
clrf TMR0 ; clear timer 0
movlw 'h0068' ;
movwf INTCON ; activate peripheral, timer 0, portb interrupts
clrf PIR1 ; clear peripheral interrupt flags
movlw 'h0011' ;
movwf T1CON ; set timer 1 presc. to 1:2, clk source internally, start timer 1
movlw 'h0005' ;
movwf T2CON ; set timer 2 presc. to 1:4, start timer 2
clrf CCPR1L ; clear pwm1.2-9 (fuel pump off)
clrf CCPR2L ; clear pwm2.2-9 (engine starter off)
movlw 'h000f' ;
movwf CCP1CON ; clear pwm1.0-1, start pwm
movwf CCP2CON ; clear pwm2.0-1, start pwm
; movlw 'h003b' ;
; movwf SSPCON ; iic-modus initialisieren und aktivieren
movlw 'h00a0' ;
movwf RCSTA ; set serial receiver to 8bit, activate serial port
movlw 'h0085' ;
movwf ADCON0 ; initialise a/d converter and start first conversion
bsf INTCON,GIE ; activate all interrupts (and off we go...)
endasm
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -