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

📄 bldc fan sensorless control.asm

📁 this is a sensorless fan motor control code .(it use the angle-ahead commutate tech.)
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	btfss status,c	     		;如果status的c=1进位, 则向前跳一步。
	goto Ve1_end

;	incf Ton2,1					;溢出
	goto main


Ve1_end	 
	incf k,1					;换相,设置k=0,代表T1T2=10,下一周期该T1导通
	clrf	INTCON				;起动定时器中断
	return
;***********************************反电势变化情况分析2********************************************



;*****************完成Ton个PWM周期,其中导通时间为Tu,PWM周期为Tall*******************************
PWM_Ton
	clrf N0	
	clrf N1
;	clrf N2

Next_PWM
	;***********判断Ton与N的大小**********************
	movf Ton0,0
	subwf N0,0
	btfss status,z					;z=1,Ton0-N0=0则前跳一步,比较Ton1与N1
	goto PWM_Continue				;z=0,Ton0-N0不为0则继续输出PWM

	movf Ton1,0
	subwf N1,0
	btfss status,z					;z=1,Ton1-N1=0则前跳一步,结束PWM
	goto PWM_Continue				;z=0,Ton1-N1不为0则继续输出PWM

;	movf Ton2,0
;	subwf N2,0
;	btfss status,z					;z=1,Ton1-N1=0则前跳一步,结束PWM
;	goto PWM_Continue				;z=0,Ton1-N1不为0则继续输出PWM

	goto PWM_Ton_end 
	;***********判断Ton与N的大小**********************

PWM_Continue
	;**************产生一个PWM脉冲********************

	;**********根据k设置T1T2输出电平******
	movf k,1
	btfss status,z					;z=1,k=0时前跳一步
	goto k_is_1
k_is_0
	bsf DrivePort,T1
	nop
	bcf DrivePort,T2				;T1T2=10
	goto k_end
k_is_1
	bcf DrivePort,T1
	nop
	bsf DrivePort,T2				;T1T2=10
k_end
	;**********根据k设置T1T2输出电平*******


	movf Tu,0
	movwf Soft_T
	call Delay

	movf Tu,0
	subwf Tall,0
	btfsc status,z					;if z=0,then Tall>Tu, Jump
	goto OnePWMpulse_end				;Z=1,W=Tall-Tu=0结束
	
	movwf Soft_T
	clrf DrivePort
	call Delay
	;**************产生一个PWM脉冲********************

OnePWMpulse_end	

	incf N0,1	
	btfss status,z					;若c=1,N0=N0+1溢出,则前跳一步
	goto Next_PWM					;若c=0,N0=N0+1没溢出,则继续输出PWM

	incf N1,1	
	btfss status,z					;若c=1,N0=N0+1溢出,则前跳一步
	goto Next_PWM					;若c=0,N0=N0+1没溢出,则继续输出PWM
					
;	incf N2,1						;只考虑N0、N1的情况,如加入N2则要修改

;	goto Next_PWM

PWM_Ton_end
	clrf DrivePort
	return
;*****************完成Ton个PWM周期,其中导通时间为Tu,PWM周期为Tall*******************************



;*****************完成Ton个PWM周期,其中导通时间为Tu,PWM周期为Tall*******************************
PAM_Ton
	clrf N0	
	clrf N1
;	clrf N2

Next_PAM
	;***********判断Ton与N的大小**********************
	movf Ton0,0
	subwf N0,0
	btfss status,z					;z=1,Ton0-N0=0则前跳一步,比较Ton1与N1
	goto PAM_Continue				;z=0,Ton0-N0不为0则继续输出PWM

	movf Ton1,0
	subwf N1,0
	btfss status,z					;z=1,Ton1-N1=0则前跳一步,结束PWM
	goto PAM_Continue				;z=0,Ton1-N1不为0则继续输出PWM

;	movf Ton2,0
;	subwf N2,0
;	btfss status,z					;z=1,Ton1-N1=0则前跳一步,结束PWM
;	goto PAM_Continue				;z=0,Ton1-N1不为0则继续输出PWM

	goto PAM_Ton_end 
	;***********判断Ton与N的大小**********************

PAM_Continue
	;**************产生一个PWM脉冲********************

	;**********根据k设置T1T2输出电平******
	movf k,1
	btfss status,z					;z=1,k=0时前跳一步
	goto Ak_is_1
Ak_is_0
	bsf DrivePort,T1
	;bcf DrivePort,T2				;T1T2=10
	goto Ak_end
Ak_is_1
	;bcf DrivePort,T1
	bsf DrivePort,T2				;T1T2=01
Ak_end
	;**********根据k设置T1T2输出电平*******

	movf Tall,0
	movwf Soft_T
	call Delay

	;**************产生一个PWM脉冲********************

	incf N0,1	
	btfss status,z					;若c=1,N0=N0+1溢出,则前跳一步
	goto Next_PAM					;若c=0,N0=N0+1没溢出,则继续输出PWM

	incf N1,1	
	btfss status,z					;若c=1,N0=N0+1溢出,则前跳一步
	goto Next_PAM					;若c=0,N0=N0+1没溢出,则继续输出PWM
					
;	incf N2,1						;只考虑N0、N1的情况,如加入N2则要修改	
	goto Next_PAM

PAM_Ton_end

	bsf ADCON0,1
	nop		
wait_AD
	btfsc ADCON0,1
	goto wait_AD

	movf ADRESH,0
	movwf ADH1
	bsf status,RP0
	movf ADRESL,0
	movwf ADL1
	bcf status,RP0

	clrf DrivePort
	return
;*****************完成Ton个PWM周期,其中导通时间为Tu,PWM周期为Tall*******************************





;******************软件延时程序,用于产生PWM波*******************************
Delay					;延时为(3*Soft_T+3)Tcyc
	movf Soft_T,0
	movwf temp
D	decfsz temp,1
	goto D
	return
;******************软件延时程序,用于产生PWM波*******************************

;******************软件延时程序,用于产生电流检测间隔时间********************
Delay0					;延时为(3*Delay_Time0+3)Tcyc
	movlw Delay_Time0
	movwf temp
D0	decfsz temp,1
	goto D0
	return
;******************软件延时程序,用于产生电流检测间隔时间********************
DelayWT
	movlw Delay_WT
	movwf temp
D20011
	decfsz temp,1
	goto D20011
	return

;******************软件延时程序,用于产生区间AB*******************************
Delay200us					;延时为(3*Delay_200us+3)Tcyc
	movlw Delay_200
	movwf temp
D200
	decfsz temp,1
	goto D200
	return
;******************软件延时程序,用于产生区间AB*******************************

;******************软件延时程序,用于产生区间AB*******************************
Delayxus					;延时为(3*Delay_200us+3)Tcyc
	movlw d'2'
	movwf temp
D2001
	decfsz temp,1
	goto D2001
	return
;******************软件延时程序,用于产生区间AB*******************************


;******************软件延时程序,用于产生死区*******************************
Delay_1s					;延时为(3*Delay_Deadtime+3)Tcyc

	;********************timer*********************
	banksel	OPTION_REG
	movlw	b'01010111'			; Timer0: Fosc, 1:2 分频比设置,内部时钟源
	movwf	OPTION_REG

	banksel	INTCON	
	movlw	0x0a0
	movwf	INTCON				;INTCON=0000 0000 关闭所有中断响应,并关闭TMR0溢出后产生中断
								;bit7=0关闭所有中断请求,bit5=0关闭TMR0溢出中断请求。	 VCCCCCCCCCCCCCCCCCCCCCCC
	bcf		INTCON,T0IF			;TMR0中断标志位清零

	bcf status,RP0
	clrf 	TMR0


	bcf		INTCON,T0IF			;TMR0中断标志位清零
	movlw d'12'
	movwf kst

Next_kst1
	movf kst,1
	btfss status,z
	goto Next_kst1

	clrf INTCON

	return
;******************软件延时程序,用于产生死区*******************************

;******************************延时500us*****************************************
delay500us
	bsf status,RP0
	movlw	b'01010000'			; Timer0: Fosc, 1:2 分频比设置,内部时钟源
	movwf	OPTION_REG

	bcf status,RP0
	movlw	0x000
	movwf	INTCON				;INTCON=0000 0000 关闭所有中断响应,并关闭TMR0溢出后产生中断
								;bit7=0关闭所有中断请求,bit5=0关闭TMR0溢出中断请求。
	bcf		INTCON,T0IF			;TMR0中断标志位清零

	movlw d'00'
	movwf TMR0
Wait_over
	btfss INTCON,2
	goto Wait_over
	bcf		INTCON,T0IF			;TMR0中断标志位清零
	return
;******************************延时500us*****************************************




;**********************************系统初始化**********************************************
System_initial  	;系统初始化
;**************************** registers in bank0 initial ********************************************
	bcf     STATUS,RP0      	; set file register bank to 0
	clrf    PCLATH          	; ensure page bits are cleared  
	
	clrf	DrivePort			; all drivers off

	movlw b'00000010'
	movwf CMCON					;CMCON=b'00010001'则bit0,1为比较器输入,bit2为比较器输出
								;CMCON=b'00010010'则bit0,1为比较器输入,bit2为一般IO口
								;CMCON=b'00010111'则bit0,1为一般IO口

	clrf 	TMR0

	movlw b'10001001'			;b7=1,使用ADRESL及ADRESH的低2位
	movwf ADCON0				;b6=1,Vref=外加;  b6=0,Vref=VDD;
								;b3-2=00(GP0),01(GP1),10(GP2),11(GP4)输入AD信号。
								;b1=1 GO/DONE表示AD正在进行; b1=0表示AD结束或没进行。
								;b0=1 ADON正处于AD运行模式;b0=0 ADON正处于非AD运行模式;
;**************************** end ofregisters in bank0 initial ****************************************



;**************************** registers in bank1 initial **********************************************
	bsf     STATUS,RP0      	; set file register bank to 1 

	movlw	B'00001111'  		; GP output:2(T3),4(T2),5(T1); input:0(C+)、1(C-)、3(Izero)
	movwf	DrivePortTris 		; set motor drivers as outputs  1-->IN; 0-->OUT

	movlw	b'01010000'			; Timer0: Fosc, 1:2 分频比设置,内部时钟源
	movwf	OPTION_REG

	movlw	b'00110111'
	movwf	WPU					; Enable the weak pull-up of PORTA

	movlw	0x000
	movwf	INTCON				;INTCON=0000 0000 关闭所有中断响应,并关闭TMR0溢出后产生中断
								;bit7=0关闭所有中断请求,bit5=0关闭TMR0溢出中断请求。
	bcf		INTCON,T0IF			;TMR0中断标志位清零

	movlw b'00000000'
	movwf VRCON					;使能CVref电路,CVref=(0/24)*Vdd=0

	movlw b'00010100'	;041h	;b6-4=001,8分频 ;b6-4=100,4分频 ;b6-4=101,16分频
	movwf ANSEL					;b2=1,ANS2(GP2)作为AD模拟信号输入通道

;**************************** end of registers in bank1 initial *********************************************


	bcf     STATUS,RP0      	; set file register bank to 0	
	return
;***************************************系统初始化******************************************



;***********************************过流检测*********************************************
I_over	
	;return

	;**** Detect the voltage at the line capacitance ***************
	bsf ADCON0,1
	nop		
wait_AD2
	btfsc ADCON0,1
	goto wait_AD2

	movf ADRESH,0
	movwf ADH
	bsf status,RP0
	movf ADRESL,0
	movwf ADL
	bcf status,RP0
	;**** End of AD the voltage at the line capacitance ***************

	movf start_flag,1			;
	btfsc status,z				;z=0,start_flag=1--->running
	goto Start_current			;z=1,start_flag=0--->starting



;****************** During running, over current protect *************************************


	goto end_I_over	
;****************** During running, over current protect *************************************





;****************** During starting, over current protect, used to detect lock *********************
Start_current
	;** ADH, ADL   ---> AD  --------> Ton之后(即开关关闭之后)的母线电容电压,续流充电后电压
	;** ADH1, ADL1 ---> AD1 --------> Ton期间(即开关开通期间)的母线电容电压,等于电源电压


	;movlw d'130'		;可增大Ton
	;addwf ADL1,1
	;btfss status,c	    ;如果status的c=1进位, 则向前跳一步。
	;goto ADB_end		;如果status的c=0没进位。
	;incf ADH1,1

	;movlw d'180'	;**13V**180**OK
	movf OvCu,0
	movwf ADL1
	movlw d'1'		;可增大Ton
	movwf ADH1


ADB_end			; AD为测出来的母线电容在续流期间的电压值。
				; AD1为给定电压值或电源电压值。

	;比较高位
	movf ADH1,0			;大幅度的减小Ton--AD1
	subwf ADH,0			; w=f-w -->(ADH-ADH1)减法很怪的,c=0表示发生借位
	btfss status,c		;c=1减法不发生借位,即ADH>=ADH1,则前跳一步
	goto AD1_AD			;c=0发生借位,溢出,AD<AD1

	btfss status,z		;z=1,即ADH=ADH1,则前跳一步,比较低位
	goto AD_AD1			;z=0,即AD>AD1

	;比较低位
	movf ADL1,0			;大幅度的减小Ton
	subwf ADL,0			;(ADL-ADL1)减法很怪的,c=0表示发生借位
	btfss status,c		;c=1减法不发生借位,即ADL>=ADL1,则前跳一步
	goto AD1_AD			;c=0发生借位,溢出,ADL<ADL1

	btfss status,z		;z=1,即ADL=ADL1,则前跳一步,认为AD1>AD
	goto AD_AD1			;z=0,即ADL>ADL1

AD_AD1	;过流
	goto main	;**起动过流被认为是堵转***************	

AD1_AD	;没过流
;****************** During starting, over current protect, used to detect lock *********************



end_I_over
	return
;***********************************过流检测*********************************************




;***************************************变量初始化*****************************************
Var_initial						; 变量初始化
	clrf kst
	clrf k
	return
;***************************************变量初始化*****************************************
	end

⌨️ 快捷键说明

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