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

📄 threephaseengine12.asm

📁 microchip公司的PICPIC18F系列芯片固件
💻 ASM
📖 第 1 页 / 共 5 页
字号:

	movlw	MCP3909_L1_STATE		; WREG holds the L1 state for the MCP3909s and is used to
						;  initiate SPI transfer. If WREG is used, must restore

;
; Phase A SPI transfer
;

	movwf	SSPBUF,A			; First SPI transfer (max: 12 instr, min: 12 instr)
	movff	PhA_V_15_8,PhA_V_D1_15_8	; Save most recent voltage and current
	movff	PhA_V_7_0,PhA_V_D1_7_0		;  as values delayed by one sample
	movff	PhA_I_15_8,PhA_I_D1_15_8	;  for CT correction
	movff	PhA_I_7_0,PhA_I_D1_7_0
	nop
	movff	SSPBUF,PhA_V_15_8		; New ADC result for phase A voltage (MSB)
	btfsc	Flags1,DummyVal,A		; Move dummy val, if active
	movff	DUMMY_VAL_V_15_8,PhA_V_15_8

	movwf	SSPBUF,A			; Next SPI transfer (max: 12 instr, min: 12 instr)
	movf	CF_Inc_7_0,W,A			; Make use of the time: add CF increment to
	addwf	CF_Acc_7_0,F,A			;  CF accumulator
	movf	CF_Inc_15_8,W,A
	addwfc	CF_Acc_15_8,F,A
	movf	CF_Inc_23_16,W,A
	addwfc	CF_Acc_23_16,F,A
	movf	CF_Inc_31_24,W,A
	addwfc	CF_Acc_31_24,F,A
	movlw	MCP3909_L1_STATE		; WREG holds the L1 state, restore
	movff	SSPBUF,PhA_V_7_0		; New ADC result for phase A voltage (LSB)
	btfsc	Flags1,DummyVal,A		; Move dummy val, if active
	movff	DUMMY_VAL_V_7_0,PhA_V_7_0

	movwf	SSPBUF,A			; Next SPI transfer (max: 16 instr, min: 12 instr)
	btfss	CF_Acc_31_24,7,A		; Make use of the time, check CF status as follows:
	bra	LPI_CF_chk_carry		;  1) Check if MSB of accumulator is HIGH; if so,
	bcf	CF_PULSE,A			;     CF pulse must be LOW
	nop
	nop					;     CAUTION: nops only execute depending on branch above
	nop
	bra	LPI_CF_end
LPI_CF_chk_carry
	bnc	LPI_CF_no_carry			;  2) Check for an overflow (carry bit HIGH) from
	movf	CF_Pulse_Width_W,W,A		;     the accumulation. If none, branch to decrement below
	btfss	STATUS,Z,A                      ;     If carry, set CF pulse HIGH only if CF_PULSE_WIDTH
	bsf	CF_PULSE,A			;     is non-zero and set remaining time.
	movwf	CF_HIGH_Time_Rem,A
	clrf	CF_HIGH_Time_Rem_Fine,A
	bsf	CF_HIGH_Time_Rem_Fine,3,A
	bra	LPI_CF_end			;     NOTE: this section results in 3 extra instr cycles
LPI_CF_no_carry
	decfsz	CF_HIGH_Time_Rem_Fine,F,A
	bra	LPI_CF_end
	bsf	CF_HIGH_Time_Rem_Fine,3,A
	dcfsnz	CF_HIGH_Time_Rem,F,A		;  3) Decrement time remaining for CF HIGH and
	bcf	CF_PULSE,A			;     set low if time is done
LPI_CF_end
	movlw	MCP3909_L1_STATE		; WREG holds the L1 state, restore
	movff	SSPBUF,PhA_I_15_8		; New ADC result for phase A current (MSB)
	btfsc	Flags1,DummyVal,A		; Move dummy val, if active
	movff	DUMMY_VAL_I_15_8,PhA_I_15_8

	movwf	SSPBUF,A			; Next SPI transfer (max: 14 instr, min: 14 instr)
	movlw	0x80				; If phase A voltage is = -32,768, change to -32,767
	xorwf	PhA_V_15_8,W,A
	iorwf	PhA_V_7_0,W,A
	btfsc	STATUS,Z,A
	incf	PhA_V_7_0,F,A	
	movf	PhA_V_15_8,W,A			; Compare MSB of phase A voltage to running maximum
	btfsc	STATUS,N,A
	comf	PhA_V_15_8,W,A
	cpfsgt	PhA_V_Abs_WMax,A
	movwf	PhA_V_Abs_WMax,A
	movlw	MCP3909_L1_STATE		; WREG holds the L1 state, restore
	movff	SSPBUF,PhA_I_7_0		; New ADC result for phase A current (LSB)
	btfsc	Flags1,DummyVal,A		; Move dummy val, if active
	movff	DUMMY_VAL_I_7_0,PhA_I_7_0

;
;  Phase B SPI transfer
;

#ifdef	ADC_MCP3909
	bsf	MPU_ADC_CSA,A			; Disable phase A I/O by setting its CS* HIGH
	bcf	MPU_ADC_CSB,A			;  and enable phase B I/O by setting its CS* LOW
#else
	bsf	MPU_ADC_CSB,A			; Enable phase B ADC by setting its CS HIGH
	bcf	MPU_ADC_CSA,A			;  and phase A chip select LOW (phase C already LOW)
#endif

	movwf	SSPBUF,A			; Next SPI transfer (max: 12 instr, min: 12 instr)
	movff	PhB_V_15_8,PhB_V_D1_15_8	; Save most recent voltage and current
	movff	PhB_V_7_0,PhB_V_D1_7_0		;  as values delayed by one sample
	movff	PhB_I_15_8,PhB_I_D1_15_8	;  for CT correction
	movff	PhB_I_7_0,PhB_I_D1_7_0
	nop
	movff	SSPBUF,PhB_V_15_8		; New ADC result for phase B voltage (MSB)
	btfsc	Flags1,DummyVal,A		; Move dummy val, if active
	movff	DUMMY_VAL_V_15_8,PhB_V_15_8

	movwf	SSPBUF,A			; Next SPI transfer (max: 14 instr, min: 14 instr)
	movlw	0x80				; If phase A current is = -32,768, change to -32,767
	xorwf	PhA_I_15_8,W,A
	iorwf	PhA_I_7_0,W,A
	btfsc	STATUS,Z,A
	incf	PhA_I_7_0,F,A	
	movf	PhA_I_15_8,W,A			; Compare MSB of phase A current to running maximum
	btfsc	STATUS,N,A
	comf	PhA_I_15_8,W,A
	cpfsgt	PhA_I_Abs_WMax,A
	movwf	PhA_I_Abs_WMax,A
	movlw	MCP3909_L1_STATE		; WREG holds the L1 state, restore
	movff	SSPBUF,PhB_V_7_0		; New ADC result for phase B voltage (LSB)
	btfsc	Flags1,DummyVal,A		; Move dummy val, if active
	movff	DUMMY_VAL_V_7_0,PhB_V_7_0

	movwf	SSPBUF,A			; Next SPI transfer (max: 12 instr, min: 12 instr)
	movf	PhB_V_15_8,W,A			; Compare MSB of phase B voltage to running maximum
	btfsc	STATUS,N,A
	comf	PhB_V_15_8,W,A
	cpfsgt	PhB_V_Abs_WMax,A
	movwf	PhB_V_Abs_WMax,A
	btfsc	PLL_CLD,A			; Make use of dead time: check PLL_CLD and set PLLPhaseLock
	bsf	Flags1,PLLPhaseLock,A		;  flag if PLL_CLD is HIGH
	nop
	movlw	MCP3909_L1_STATE		; WREG holds the L1 state, restore
	movff	SSPBUF,PhB_I_15_8		; New ADC result for phase B current (MSB)
	btfsc	Flags1,DummyVal,A		; Move dummy val, if active
	movff	DUMMY_VAL_I_15_8,PhB_I_15_8

	movwf	SSPBUF,A			; Next SPI transfer (max: 14 instr, min: 14 instr)
	movlw	0x80				; If phase B voltage is = -32,768, change to -32,767
	xorwf	PhB_V_15_8,W,A
	iorwf	PhB_V_7_0,W,A
	btfsc	STATUS,Z,A
	incf	PhB_V_7_0,F,A	
	movf	PhB_I_15_8,W,A			; Compare MSB of phase B voltage to running maximum
	btfsc	STATUS,N,A
	comf	PhB_I_15_8,W,A
	cpfsgt	PhB_I_Abs_WMax,A
	movwf	PhB_I_Abs_WMax,A
	movlw	MCP3909_L1_STATE		; WREG holds the L1 state, restore
	movff	SSPBUF,PhB_I_7_0		; New ADC result for phase B current (LSB)
	btfsc	Flags1,DummyVal,A		; Move dummy val, if active
	movff	DUMMY_VAL_I_7_0,PhB_I_7_0

;
; Phase C SPI transfer
;

#ifdef	ADC_MCP3909
	bsf	MPU_ADC_CSB,A			; Disable phase B I/O by setting its CS* HIGH
	bcf	MPU_ADC_CSC,A			;  and enable phase C I/O by setting its CS* LOW
#else
	bsf	MPU_ADC_CSC,A			; Enable phase C ADC by setting its CS HIGH
	bcf	MPU_ADC_CSB,A			;  and phase B chip select LOW (phase A already LOW)
#endif

	movwf	SSPBUF,A			; Next SPI transfer (max: 12 instr, min: 12 instr)
	movff	PhC_V_15_8,PhC_V_D1_15_8	; Save most recent voltage and current
	movff	PhC_V_7_0,PhC_V_D1_7_0		;  as values delayed by one sample
	movff	PhC_I_15_8,PhC_I_D1_15_8	;  for CT correction
	movff	PhC_I_7_0,PhC_I_D1_7_0
	nop
	movff	SSPBUF,PhC_V_15_8		; New ADC result for phase C voltage (MSB)
	btfsc	Flags1,DummyVal,A		; Move dummy val, if active
	movff	DUMMY_VAL_V_15_8,PhC_V_15_8

	movwf	SSPBUF,A			; Next SPI transfer (max: 12 instr, min: 12 instr)
	movlw	0x80				; If phase B current is = -32,768, change to -32,767
	xorwf	PhB_I_15_8,W,A
	iorwf	PhB_I_7_0,W,A
	btfsc	STATUS,Z,A
	incf	PhB_I_7_0,F,A	
	nop
	nop
	nop
	movlw	MCP3909_L1_STATE		; WREG holds the L1 state, restore
	movff	SSPBUF,PhC_V_7_0		; New ADC result for phase C voltage (LSB)
	btfsc	Flags1,DummyVal,A		; Move dummy val, if active
	movff	DUMMY_VAL_V_7_0,PhC_V_7_0

	movwf	SSPBUF,A			; Next SPI transfer (max: 12 instr, min: 12 instr)
	movf	PhC_V_15_8,W,A			; Compare MSB of phase C voltage to running maximum
	btfsc	STATUS,N,A
	comf	PhC_V_15_8,W,A
	cpfsgt	PhC_V_Abs_WMax,A
	movwf	PhC_V_Abs_WMax,A
	nop
	nop
	nop
	movlw	MCP3909_L1_STATE		; WREG holds the L1 state, restore
	movff	SSPBUF,PhC_I_15_8		; New ADC result for phase C current (MSB)
	btfsc	Flags1,DummyVal,A		; Move dummy val, if active
	movff	DUMMY_VAL_I_15_8,PhC_I_15_8

	movwf	SSPBUF,A			; Next SPI transfer (max: 13 instr, min: 13 instr)
	movlw	0x80				; If phase C voltage is = -32,768, change to -32,767
	xorwf	PhC_V_15_8,W,A
	iorwf	PhC_V_7_0,W,A
	btfsc	STATUS,Z,A
	incf	PhC_V_7_0,F,A	
	movf	PhC_I_15_8,W,A			; Compare MSB of phase C current to running maximum
	btfsc	STATUS,N,A
	comf	PhC_I_15_8,W,A
	cpfsgt	PhC_I_Abs_WMax,A
	movwf	PhC_I_Abs_WMax,A
	movff	SSPBUF,PhC_I_7_0		; New ADC result for phase C current (LSB)
	btfsc	Flags1,DummyVal,A		; Move dummy val, if active
	movff	DUMMY_VAL_I_7_0,PhC_I_7_0


	; Finish up check on phase C current limit: if -32,768, set to -32,767
	movlw	0x80				; If phase C current is = -32,768, change to -32,767
	xorwf	PhC_I_15_8,W,A
	iorwf	PhC_I_7_0,W,A
	btfsc	STATUS,Z,A
	incf	PhC_I_7_0,F,A	

#ifdef	ADC_MCP3909
	; Enable phase A I/O so that next data ready pulse can be seen
	bsf	MPU_ADC_CSC,A			; Disable phase C I/O by setting its CS* HIGH
	bcf	MPU_ADC_CSA,A			;  and enable phase A I/O by setting its CS* LOW
#endif

	; Enable INT2 interrupt for next data set
	bcf	INTCON3,INT2IF,A		; Clear INT2 interrupt flag
	bsf	INTCON3,INT2IE,A		; Enable INT2 interrupt

;
; Phase correction for phase A
;
	movf	PhA_V_D1_7_0,W,A		; Subtract most recent voltage from previous voltage
	subwf	PhA_V_7_0,W,A
	movwf	PhA_V_P_7_0,A
	movf	PhA_V_D1_15_8,W,A
	subwfb	PhA_V_15_8,W,A
	movwf	LPI_temp1,A

	movf	PhA_DelayX2,W,A			; Get phase correction amplitude
	mulwf	PhA_V_P_7_0,A			; Arg1L * Arg2L -> PRODH -> PhA_V_P_7_0
	movff	PRODH,PhA_V_P_7_0		;  (don't need PRODL and done with old PhA_V_P_7_0)
	mulwf	LPI_temp1,A			; Multiply for cross product (Arg1L * Arg1H) ->
	movf	PRODL,W,A			; Add result
	addwf	PhA_V_P_7_0,F,A
	movff	PRODH,PhA_V_P_15_8
	btfsc	STATUS,C,A
	incf	PhA_V_P_15_8,F,A
	btfss	LPI_temp1,7,A			; Difference negative?
	bra	LPI_PhA_Diff_Done		; No, done
	movf	PhA_DelayX2,A
	subwf	PhA_V_P_15_8,F,A
LPI_PhA_Diff_Done

	movf	PhA_V_D1_7_0,W,A		; Add portion of difference to previous voltage
	addwf	PhA_V_P_7_0,F,A
	movf	PhA_V_D1_15_8,W,A
	addwfc	PhA_V_P_15_8,F,A

	btfsc	Flags1,PhA_Delay_SignBit,A	; Sign of phase correction determines current value to use
	bra	LPI_PhA_PC_Neg
	movff	PhA_I_D1_7_0,PhA_I_P_7_0	; If positive, use delayed value
	movff	PhA_I_D1_15_8,PhA_I_P_15_8
	bra	LPI_PhA_PC_Done
LPI_PhA_PC_Neg
	movff	PhA_I_7_0,PhA_I_P_7_0		; If negative, use most recent value
	movff	PhA_I_15_8,PhA_I_P_15_8
LPI_PhA_PC_Done

;
; Phase A power = V*I and accumulate
;
	movf	PhA_V_P_7_0,W,A			; Arg1L * Arg2L -> PRODH:PRODL -> LPI_Res1:LPI_Res0
	mulwf	PhA_I_P_7_0,A
	movff	PRODH,LPI_Res1
	movff	PRODL,LPI_Res0
	movf	PhA_V_P_15_8,W,A		; Arg1H * Arg2H -> PRODH:PRODL -> LPI_Res3:LPI_Res2
	mulwf	PhA_I_P_15_8,A
	movff	PRODH,LPI_Res3
	movff	PRODL,LPI_Res2
	movf	PhA_V_P_7_0,W,A			; Cross products: Arg1L * Arg2H -> PRODH:PRODL ->
	mulwf	PhA_I_P_15_8,A			;  add to LPI_Res3:LPI_Res1
	movf	PRODL,W,A
	addwf	LPI_Res1,F,A
	movf	PRODH,W,A
	addwfc	LPI_Res2,F,A
	clrf	WREG,A
	addwfc	LPI_Res3,F,A
	movf	PhA_V_P_15_8,W,A		; Cross products: Arg1H * Arg2L -> PRODH:PRODL ->
	mulwf	PhA_I_P_7_0,A			;  add to LPI_Res3:LPI_Res1
	movf	PRODL,W,A
	addwf	LPI_Res1,F,A
	movf	PRODH,W,A
	addwfc	LPI_Res2,F,A
	clrf	WREG,A
	addwfc	LPI_Res3,F,A
	btfss	PhA_I_P_15_8,7,A		; Current negative?
	bra	LPI_PhA_P_ChkNegV		; No, check voltage
	movf	PhA_V_P_7_0,W,A
	subwf	LPI_Res2,F,A
	movf	PhA_V_P_15_8,W,A
	subwfb	LPI_Res3,F,A
LPI_PhA_P_ChkNegV
	btfss	PhA_V_P_15_8,7,A		; Voltage negative?
	bra	LPI_PhA_P_SqrDone		; No, done
	movf	PhA_I_P_7_0,W,A
	subwf	LPI_Res2,F,A
	movf	PhA_I_P_15_8,W,A
	subwfb	LPI_Res3,F,A
LPI_PhA_P_SqrDone

	movf	LPI_Res0,W,A			; Accumulate phase A power
	addwf	PhA_W_WAcc_7_0,F,A
	movf	LPI_Res1,W,A
	addwfc	PhA_W_WAcc_15_8,F,A
	movf	LPI_Res2,W,A
	addwfc	PhA_W_WAcc_23_16,F,A
	movf	LPI_Res3,W,A
	addwfc	PhA_W_WAcc_31_24,F,A
	clrf	WREG,A				; Add carry & sign extend
	btfsc	LPI_Res3,7,A			;  if needed
	comf	WREG,F,A
	addwfc	PhA_W_WAcc_39_32,F,A

;
; Square and accumulate phase A current
;
	btfss	PhA_I_D1_15_8,7,A		; Check for negative number
	bra	LPI_PhA_I_Pos			; Is positive, skip two's complement
	comf	PhA_I_D1_15_8,F,A		; Is negative, two's complement the 16-bit value
	negf	PhA_I_D1_7_0,A
	btfsc	STATUS,C,A
	incf	PhA_I_D1_15_8,F,A
LPI_PhA_I_Pos
	movf	PhA_I_D1_7_0,W,A		; Arg1L * Arg1L -> PRODH:PRODL -> add to bits 15:0 of accum
	mulwf	PhA_I_D1_7_0,A
	movf	PRODL,W,A
	addwf	PhA_I_WAcc_7_0,F,A
	movf	PRODH,W,A
	addwfc	PhA_I_WAcc_15_8,F,A
	clrf	WREG,A
	addwfc	PhA_I_WAcc_23_16,F,A
	addwfc	PhA_I_WAcc_31_24,F,A
	addwfc	PhA_I_WAcc_39_32,F,A
	movf	PhA_I_D1_15_8,W,A		; Arg1H * Arg1H -> PRODH:PRODL -> add to bits 31:16 of accum
	mulwf	PhA_I_D1_15_8,A
	movf	PRODL,W,A
	addwf	PhA_I_WAcc_23_16,F,A
	movf	PRODH,W,A
	addwfc	PhA_I_WAcc_31_24,F,A
	clrf	WREG,A
	addwfc	PhA_I_WAcc_39_32,F,A
	rlncf	PhA_I_D1_15_8,W,A		; Cross products: Arg1L * (2*Arg1H) -> PRODH:PRODL ->
	mulwf	PhA_I_D1_7_0,A			;  add to bits 39:8 of accum
	movf	PRODL,W,A			; (Note: the rotate to produce 2*Arg1H works because
	addwf	PhA_I_WAcc_15_8,F,A		;  the initial value is between 0x00 and 0x7F, multiplying
	movf	PRODH,W,A			;  by two means the cross product only has to be added
	addwfc	PhA_I_WAcc_23_16,F,A		;  once rather than twice.)
	clrf	WREG,A
	addwfc	PhA_I_WAcc_31_24,F,A
	addwfc	PhA_I_WAcc_39_32,F,A

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -