📄 bldc fan sensorless control.asm
字号:
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 + -