⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sss.txt

📁 pic系列单片机得控制程序 主要进行温度采集和转换控制
💻 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 + -