📄 threephaseengine12.asm
字号:
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 + -