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

📄 clsd_bldchalhal.asm

📁 This program controls a BLDC motor in closed loop using PIC18Fxx31 devices. Hardware used is PICDE
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	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 + -