📄 clsd_bldchalhal.asm
字号:
bsf PORTC,0 ;Turn ON LED4 to indicate Forward direction
bra PICK_FROM_TABLE
ITS_REVERSE
lfsr 0,POSITION_TABLE_REV ;Initialize FSR0 to the beginning of the Reverse Table
bcf PORTC,0 ;Turn OFF LED4 to indicate Forward direction
;--
PICK_FROM_TABLE
movf PORTA,W ;Read Hall input state
andlw 0x1C ;IC1/IC2/IC3
rrncf WREG,W
rrncf WREG,W ;Shift Hall states to LSBits
movf PLUSW0,W ;Read the value from table
movwf OVDCOND ;Load OVDCOND to allow rewuired PWMs and mask other PWMs
return
;******************************************************************
ISR_LOW
RETFIE FAST
;******************************************************************
;This routine checks for the Faults. Also sets the flag for parameter display
;Over current (Fault A),Over voltage(FaultB) is initialized in cycle-by-cycle mode.
;If these faults occur very frequently, the mode is changed to catestriphic mode and PWMs are shut down
;The occurence of these faults are checked every PWM interrupt with a limit and if it exeeds the limit
;in 256 PWM cycles, the mode is changed to catestrophic.
;Heatsink temperature is compared with a pre defined limit and PWMs shut down, if the temp crosses the limit.
;LED1 is blinked at fixed rate, if the Overcurrent fault is detected in catestrophic mode
;LED2 is blinked at fixed rate, if the Overvoltage fault is detected in catestrophic mode
;LED3 is blinked at fixed rate, if the Overtemparature is detected
PWM_INTERRUPT
bsf FLAGS,CALC_PWM
incfsz PWM_CYCLE_COUNT,F
bra CHECK_FOR_FAULTS
clrf FAULTA_COUNT
clrf FAULTB_COUNT
bra CHECK_PARAMETER_DISPLAY
CHECK_FOR_FAULTS
btfss FLTCONFIG,FLTAS
bra CHECK_FLTB
incf FAULTA_COUNT,F
movlw MAX_FLTA_COUNT
cpfsgt FAULTA_COUNT
bra CHECK_FLTB
bcf FLTCONFIG,FLTAMOD
bsf FLT_FLAGS,OCUR
bsf FLT_FLAGS,FLT
CHECK_FLTB
btfss FLTCONFIG,FLTBS
bra CHECK_HEATSINK_TEMP
incf FAULTB_COUNT,F
movlw MAX_FLTB_COUNT
cpfsgt FAULTB_COUNT
bra CHECK_HEATSINK_TEMP
bcf FLTCONFIG,FLTBMOD
bsf FLT_FLAGS,OVOLT
bsf FLT_FLAGS,FLT
CHECK_HEATSINK_TEMP
movlw MAX_HEATSINKTEMP
cpfsgt HEATSINK_TEMPH
bra CHECK_PARAMETER_DISPLAY
call STOP_MOTOR
bsf FLT_FLAGS,OTEMP
bsf FLT_FLAGS,FLT
;----------------------------------
CHECK_PARAMETER_DISPLAY
call CHECK_PWM_TICK
bcf PIR3,PTIF
retfie FAST
;----------------------------------
CHECK_PWM_TICK
movlw CYCLE_COUNT_MAXH
cpfseq CYCLE_COUNTH
bra NOT_YET_THERE
movlw CYCLE_COUNT_MAXL
cpfsgt CYCLE_COUNTL
bra NOT_YET_THERE
bsf FLAGS,PARAM_DISPLAY
clrf CYCLE_COUNTH
clrf CYCLE_COUNTL
btfsc FLT_FLAGS,OCUR
btg LED1
btfsc FLT_FLAGS,OVOLT
btg LED2
btfsc FLT_FLAGS,OTEMP
btg LED3
return
NOT_YET_THERE
incfsz CYCLE_COUNTL,F
return
incf CYCLE_COUNTH,F
return
;******************************************************************
;This routine calcuclates the PWM duty cycle based on the speed referance input from potentiometer
;Compile time constant gives a ratio of the DC bus voltage input and motor rated voltage wrt to the speed referance
;The error is amplified and added to the PWM calcuclted based on the original value
UPDATE_PWM
movlw 0x30 ;Setting a minimum speed ref of 0x30
cpfsgt SPEED_REFH
bra RESET_DUTY_CYCLE ;If the Speed ref<0x30, reset the PWM duty cycle
; movlw 0xF8
; cpfslt SPEED_REFH
; movwf SPEED_REFH
;PWM = [(MotorVoltage/DCbus voltage)*(PTPER*4)]*[SpeedRef/255] *16
;16 is the multiplication factor
movf SPEED_REFH,W
mullw (MAIN_PWM_CONSTANT)
swapf PRODL,W
andlw 0x0F
movwf PDC_TEMPL
swapf PRODH,W
andlw 0xF0
iorwf PDC_TEMPL,F
swapf PRODH,W
andlw 0x0F
movwf PDC_TEMPH
movff pid_out0,DISPLAY_EOH ;Diplay error on hyper terminal
movff pid_out1,DISPLAY_EOL
movff pid_out2,DISPLAY_EOLL
call ADJUST_PID_OUT ;The amplified error is adjusted to 16 MS bits
btfsc pid_stat1,pid_sign,1 ;PID result sign flag, Pos = set/ Neg = clear
bra ADD_ERROR
; movf pid_out1,W,1 ;pid_out1; ERROR_PWML
movf ERROR_PWML,W ;If the error is negative, it is subtracted from the original value
subwf PDC_TEMPL,F
; movf pid_out0,W,1 ;ERROR_PWMH
movf ERROR_PWMH,W ;
subwfb PDC_TEMPH,F
btfsc STATUS,C
bra LOAD_PWM
clrf PDC_TEMPL
clrf PDC_TEMPH
bra LOAD_PWM
ADD_ERROR
; movf pid_out1,W,1 ;pid_out1; ERROR_PWML
movf ERROR_PWML,W ;ERROR_PWML
addwf PDC_TEMPL,F ;If the error is positive, it is added to the original value
; movf pid_out0,W,1 ;ERROR_PWMH
movf ERROR_PWMH,W ;ERROR_PWMH
addwfc PDC_TEMPH,F
btfsc STATUS,C ;Set limit to the PWM
bra SEAL_PWM_LIMIT
movlw HIGH(MAX_PWM_VALUE)
subwf PDC_TEMPH,W
btfss STATUS,C ;Is PWM vlaue>=Max_value
bra LOAD_PWM ;No,less
btfss STATUS,Z ;Is PWM = Max_value?
bra SEAL_PWM_LIMIT ;No greater
movlw LOW(MAX_PWM_VALUE)
subwf PDC_TEMPL,W
btfss STATUS,C ;Is PWM vlaueL>=Max_valueL
bra LOAD_PWM ;No,less
SEAL_PWM_LIMIT
movlw HIGH(MAX_PWM_VALUE) ;If PWM DS crosses the max limit, load the max value
movwf PDC_TEMPH
movlw LOW(MAX_PWM_VALUE)
movwf PDC_TEMPL
bra LOAD_PWM
LOAD_PWM
bsf PWMCON1,UDIS ;Disable the PWM buffer update
movf PDC_TEMPH,W ;Load the duty cycles to all PWM duty cycle registers
movwf PDC0H
movwf PDC1H
movwf PDC2H
movwf PDC3H
movf PDC_TEMPL,W
movwf PDC0L
movwf PDC1L
movwf PDC2L
movwf PDC3L
bcf PWMCON1,UDIS ;Enable the PWM buffer update
RETURN
;---------------------------------------------
RESET_DUTY_CYCLE
clrf PDC0H ;All duty cycles reset to zero
clrf PDC1H
clrf PDC2H
clrf PDC3H
clrf PDC0L
clrf PDC1L
clrf PDC2L
clrf PDC3L
call UPDATE_SEQUENCE
RETURN
;******************************************************************
CALCULATE_SPEED_ERROR
;Ref speed = (Rated speed * speed ref/0xFF)
;Speed f/b = (Velocity value * 60/8)
;60 is to convert into RPM. 8 is the multiplication factor for the velocity value
movlw LOW(MOTOR_RATED_SPEED)
mulwf SPEED_REFH ;Speed ref converted to RPM
movff PRODH,TEMP
movlw HIGH(MOTOR_RATED_SPEED)
mulwf SPEED_REFH
movf PRODL,W
addwf TEMP,F
clrf WREG
addwfc PRODH,W
movwf SPEED_REF_RPMH ;Speed ref in RPMH/L
movff TEMP,SPEED_REF_RPML
movff SPEED_REF_RPMH,DISPLAY_SRH ;For display on Hyper terminal
movff SPEED_REF_RPML,DISPLAY_SRL
;calculate speed feedback
movf SPEED_FEEDBACKL,W
mullw 0x8
movff PRODH,TEMP
movff PRODL,SPEED_FEEDBACKL
movf SPEED_FEEDBACKH,W
mullw 0x8
movf PRODL,W
addwf TEMP,W
movwf SPEED_FEEDBACKH ;Speed feedback in H/L registers
movff SPEED_FEEDBACKH,DISPLAY_SFH ;For display on Hyper terminal
movff SPEED_FEEDBACKL,DISPLAY_SFL
; Speed Error = SPEED_REF_RPM - SPEED_FEEDBACK
bsf STATUS,C
movf SPEED_REF_RPML,W
subfwb SPEED_FEEDBACKL,W
movwf SPEED_ERRORL
movf SPEED_REF_RPMH,W
subfwb SPEED_FEEDBACKH,W
movwf SPEED_ERRORH
bcf FLAGS,NEGATIVE_ERROR
bsf pid_stat1,err_sign,1 ;Error sign is positive for PID controller
btfss SPEED_ERRORH,7 ;If error is negative, complement the error
bra POSITIVE_ERROR
comf SPEED_ERRORH,F
comf SPEED_ERRORL,F
bsf FLAGS,NEGATIVE_ERROR
bcf pid_stat1,err_sign,1 ;Error sign is negtive for PID controller
POSITIVE_ERROR
;Calculate error PWM based on the speed error
;Error PWM = Error_PWM_constant(8bit) * Error(16bit)
movlw (ERROR_PWM_CONSTANT)
mulwf SPEED_ERRORL
movff PRODH,TEMP
movff PRODL,ERROR_PWML
movlw (ERROR_PWM_CONSTANT)
mulwf SPEED_ERRORH
movf PRODL,W
addwf TEMP,W
movwf ERROR_PWMH
;Error PWM has a multiplication factor 16
swapf ERROR_PWML,W
andlw 0x0F
movwf ERROR_PWML
swapf ERROR_PWMH,W
andlw 0xF0
iorwf ERROR_PWML,F
swapf ERROR_PWMH,W
andlw 0x0F
movwf ERROR_PWMH
call CHECK_ERROR_CAP ;Check cap to 4000d
movff ERROR_PWMH,error0 ;Load ERROR_PWM to the error registers used by PID algo
movff ERROR_PWML,error1
movff ERROR_PWMH,DISPLAY_EIH ;For display on Hyper terminal
movff ERROR_PWML,DISPLAY_EIL
return
;******************************************************************
CALCULATE_SPEED
; Velocity is calculated from the VEL registers
; Actual speed = RPM_CONSTANT_HALL/Velocity register
; Velocity is devided by 8 again to get a total 64 prescale
bcf STATUS,C
rrcf VELOCITY_READH,F
rrcf VELOCITY_READL,F
bcf STATUS,C
rrcf VELOCITY_READH,F
rrcf VELOCITY_READL,F
bcf STATUS,C
rrcf VELOCITY_READH,F
rrcf VELOCITY_READL,F
bnc CALC_ACT_RPM
incf VELOCITY_READL,F
bnc CALC_ACT_RPM
incf VELOCITY_READH,F
CALC_ACT_RPM
movff VELOCITY_READH,ARG2H
movff VELOCITY_READL,ARG2L
movlw HIGH(RPM_CONSTANT_HALL)
movwf ARG1H
movlw LOW(RPM_CONSTANT_HALL)
movwf ARG1L
call DIVISION_16BY16
movff RESL,DISPLAY_SPEED_ACTL
movff RESH,DISPLAY_SPEED_ACTH
movff RESL,SPEED_FEEDBACKL
movff RESH,SPEED_FEEDBACKH
return
;******************************************************************
INIT_PERPHERALS
;ADC initialization
;ADC is initialized to read
;The Potentiometer connected to AN1
;Motor current Phase R or DC bus current connected to AN0
;Motor current Phase Y connected to AN6
;Motor current Phase B or Heatsink hermisotr connected to AN7
movlw 0x07
movwf TRISE ;RE0/1/2 are inputs
movlw b'00010101' ;ADC set in multiple channel sequential mode2(SEQM2)
movwf ADCON0
movlw b'00010000' ;FIFO buffer enabled
movwf ADCON1
movlw b'00110010' ;Left justified result,12 TAD acquisition time, ADC clock = FOsc/32
movwf ADCON2
movlw b'10000000' ;Interrupt generated when 4th word is written to bufeer
movwf ADCON3
movlw b'01000100' ;AN0,AN1,AN6,AN7 are selected for conversion
movwf ADCHS
movlw b'11000011' ;AN0,AN1,AN6,AN7 are selected as analog inputs
movwf ANSEL0
movlw b'00000000' ;All other inputs set to digital
movwf ANSEL1
;-----------------------------------------------------------------
;PCPWM initalization
;PCPWM outputs initialized in independent mode. PWM<0:5> are enabled
movlw b'00000000' ;PWM timer is in free running mode(Edge aligned) with Fosc/4 input clock
movwf PTCON0
movlw LOW(PTPER_VALUE) ; 20KHz = 0xFA ;20KHz of PWM frequency
movwf PTPERL ;16KHz = 0x137
;12KHz = 0x1A0
movlw HIGH(PTPER_VALUE)
movwf PTPERH
movlw b'01001111' ;PWM0-5 enabled in independent mode
movwf PWMCON0
movlw b'00000001' ;Output overides synched wrt PWM timebase
movwf PWMCON1
movlw b'00000000' ;No dead time inserted
movwf DTCON
movlw b'00000000' ;PWM<0:5> PWM Duty cycle on overide
movwf OVDCOND
movlw b'00000000' ; All PWMs = 0 on init
movwf OVDCONS
movlw b'10110011' ;FaultA = Over current,cycle by cycle mode
movwf FLTCONFIG ;FaultbB = Over voltage,cycle by cycle mode
movlw 0x00 ;Special event not used
movwf SEVTCMPL
movlw 0x00
movwf SEVTCMPH
clrf PDC0L ;Clear all PWM duty cycle registers
clrf PDC1L
clrf PDC2L
clrf PDC3L
clrf PDC0H
clrf PDC1H
clrf PDC2H
clrf PDC3H
movlw b'10000000' ;PWM timer ON
movwf PTCON1
;-----------------------------------------------------------------
;Initializing the motion feedback module to read Hall sensors using InputCapture
;HallA/B/C @ IC1/IC2/IC3
bsf TRISA,2 ;IC1/2/3 inputs
bsf TRISA,3
bsf TRISA,4
movlw b'00011001' ;Timer5 ON with prescale 1:8
movwf T5CON
movlw b'01001000' ;Cap1/2/3-capture every input state change
movwf CAP1CON
movlw b'01001000' ;Cap1/2/3-capture every input state change
movwf CAP2CON
movlw b'01001000' ;Cap1/2/3-capture every input state change
movwf CAP3CON
movlw b'00000000' ;Digital filters disabled
movwf DFLTCON
movlw b'00000000' ;Disable QEI
movwf QEICON
;-----------------------------------------------------------------
;init PORTC
;PortC<0> LED4 : Output
;PortC<1> FaultA(Overcurrent): Input
;PortC<2> FaultB(Overcurrent): Input
;PortC<6> TX: Output
;PortC<7> RX: Input
movlw b'10111110' ;PortC<0> LED4 used for LEDs,FaultA and FaultB
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -