📄 bldc fan sensorless control.asm
字号:
list p=12F675 ; list directive to define processor
#include <p12F675.inc> ; processor specific variable definitions
errorlevel -302 ; suppress message 302 from list file
__CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
;**********************************************************************
;* Define variable storage 变量定义
CBLOCK 0x20
temp
k
PWM_temp
Talfa ;PWM的高电平时间
Tcycle ;PWM的周期时间
Soft_T ;延时子程序变量
Tu
Tall
steady
N2
N1
N0
Ton2 ;保存导通时间Ton
Ton1
Ton0
OvCu
ENDC
CBLOCK 0x30
Decrease_big
Decrease_small
Delay_Deadtime
Ton_Increase
Ncount
t_I_ZCP
kst
start_flag
i_flag
start_i
LowVoltage
ADH
ADL
ADH1
ADL1
k_dog
current_B
status_temp
w_temp
ENDC
;**********************************************************************
;* Define I/O,(3*Delay_400us+3)Tcyc
;***********************************************************************************************
;******延时为(3*X+3)Tcyc******
#define Delay_Time0 D'100' ;软件延时,用于产生电流检测间隔时间
#define Delay_WT D'10' ;***7.27*** 这个发现没啥用
#define Delay_200 D'50'
#define Decrease_Large D'45'
#define Decrease D'1'
#define Increase D'2'
#define DrivePort GPIO
#define DrivePortTris TRISIO
;*************采用电流、反电势过零点信息全部外部送入的方式工作
;T1:GP5
;T2:GP4
#define first_IO b'00010000'
#define T1 D'5'
#define T2 D'4'
#define T3 D'2'
#define Neg b'00110000'
#define i D'3' ; 电流过零点信号由GP1送入
#define e D'6' ;反电势过零点信号由GP3送入
;*******************************************中断*************************************************
;VECTOR ADDRESS 中断向量定义
RESET_VECTOR ;Reset中断向量入口
ORG 0x000 ; startup vector
nop ; required for ICD operation
goto main ;进入主程序程序
;****************************************中断*****************************************************
;*******************************************中断*************************************************
INIT_VECTOR
ORG 0x004 ; interrupt vector location
ISR
movwf w_temp ; save off current W register contents
swapf STATUS,W ; move status register into W register
movf status,0
movwf status_temp ; save off contents of STATUS register
bcf INTCON,T0IF
decf k_dog,1
movf k_dog,0
btfsc status,z
goto main
go_on
bcf status,RP0
clrf TMR0
swapf status_temp,W ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,W ; restore pre-isr W register contents
retfie
;*******************************************中断*************************************************
;***************************************主函数****************************************************
ORG 0x050 ;0x010
main
Call System_initial ;系统初始化。
clrf start_i ;start_i=0, not detect current
clrf start_flag
incf start_flag,1
movlw d'14' ;喂狗
movwf k_dog
;*************************************初速度判断********************************************************************
;********************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
Kst_again
bcf INTCON,T0IF ;TMR0中断标志位清零
movlw d'13'
movwf k_dog
Next_kst
decfsz k_dog,1
; movf k_dog,1
; btfss status,z
goto Timer_OK
goto KstEnd
Timer_OK
incf k_dog,1
btfsc CMCON,e ;Ve=0,前跳一步
goto Kst_again ;Ve=1,继续查询,等其变0,喂狗
goto Next_kst
KstEnd
clrf INTCON ;关闭定时器中断
;*************************************初速度判断********************************************************************
call rotor_initial
clrf i_flag
clrf k ;k=0,代表T1T2=10,T1导通
;*******T1触发导通在PWM模式下工作时间:Ton(=Ton0+Ton1*255+Ton2*255*255)个PWM周期******
movlw h'bf' ;Ton0=h'30', Ton1=h'1b'时,PWM共占时间约980ms,约1s
movwf Ton0
movlw h'00'
movwf Ton1
movlw Decrease
movwf Decrease_small
movlw Increase
movwf Ton_Increase
movlw h'de'
movwf t_I_ZCP ;电流过零点等待延时参数,有三个地方对她進行暸设置
movlw D'30'
movwf Decrease_big ;Ton减小时的减幅设置
clrf start_flag
call First_Half_I_Cycle
call Second_Half_I_Cycle
movf Decrease_big,0 ;大幅度的减小Ton
subwf Ton0,1 ;减法很怪的,c=0表示发生借位
btfsc status,c ;c=0发生借位则前跳一步
goto Pulse5 ;c=1减法不发生借位,即Ton1>=Decrease_big
movlw d'1'
subwf Ton1,1
Pulse5
call First_Half_I_Cycle
call Second_Half_I_Cycle
movf Decrease_big,0 ;大幅度的减小Ton
subwf Ton0,1 ;减法很怪的,c=0表示发生借位
btfsc status,c ;c=0发生借位则前跳一步
goto Pulse8 ;c=1减法不发生借位,即Ton1>=Decrease_big
movlw d'1'
subwf Ton1,1
Pulse8
;***************PWM: enlarge Tu till Tu=Tall-1********************
loop_start
movlw d'5'
movwf kst
start_loop1
call First_Half_I_Cycle
call Second_Half_I_Cycle
decfsz kst,1 ;若kst=0,则前跳一步
goto start_loop1
incf Tu,1
decf Decrease_big,1
movf Tu,0
subwf Tall,0
btfss status,z
goto loop_start
decf Tu,1 ;if Tall-Tu=0,then Tu=Tu-1
;***************PWM: enlarge Tu till Tu=Tall-1********************
; incf start_i,1 ;start_i=1, begin detect current
incf start_flag,1
;********* decrease Decrease_big till Decrease_big=3 **************
loop_start_dec
movlw d'5'
movwf kst
start_loop_dec
call First_Half_I_Cycle
call Second_Half_I_Cycle
decfsz kst,1 ;若kst=0,则前跳一步
goto start_loop_dec
decf Decrease_big,1
movlw d'3'
subwf Decrease_big,0
btfsc status,c
goto loop_start_dec
;********* decrease Decrease_big till Decrease_big=3 **************
;****在PWM占空比刚变为1时电流急剧增大,那时需要较大的t_I_ZCP以保证****
;*******电流能真正在延时程序中过零。这里将t_I_ZCP增大********
movlw h'fe'
movwf t_I_ZCP ;电流过零点等待延时参数
;******将t_I_ZCP增大********
;*****減小 Tu=Tall 之后電流的突變帶來的毛刺,措施分阶段減小 Ton******
movlw d'25'
subwf Ton0,0 ;w=f-w=Ton0-w
btfsc status,c ;c=0,发生借位,不能减,跳过
movwf Ton0
;********減小 Tu=Tall 之后電流的突變帶來的毛刺,措施減小 Ton*********
;incf start_i,1 ;start_i=1, begin detect current
;********************令Decrease_big=1********************************
movlw d'13'
movwf kst
start_loop_Ton3
call PAM_Ton ;T1导通Ton个PWM
call Vi_control ;电流过零信号分析
call Ve_control ;反电势变化情况分析
call PAM_Ton ;T1导通Ton个PWM
call Vi_control_2 ;电流过零信号分析
call Ve_control_2 ;反电势变化情况分析
decfsz kst,1 ;若kst=0,则前跳一步
goto start_loop_Ton3
movlw d'10'
subwf Ton0,0 ;w=f-w=Ton0-w
btfsc status,c ;c=0,发生借位,不能减,跳过
movwf Ton0
movlw D'1'
movwf Decrease_big
;********************令Decrease_big=1********************************
;*******在PWM占空比刚变为1时电流急剧增大,那时需要较大的t_I_ZCP以保证
;*******电流能真正在延时程序中过零。一段时间后可将t_I_ZCP减小********
movlw d'23'
movwf kst
start_loop_Ton4
call PAM_Ton ;T1导通Ton个PWM
call Vi_control ;电流过零信号分析
call Ve_control ;反电势变化情况分析
call PAM_Ton ;T1导通Ton个PWM
call Vi_control_2 ;电流过零信号分析
call Ve_control_2 ;反电势变化情况分析
decfsz kst,1 ;若kst=0,则前跳一步
goto start_loop_Ton4
movlw h'50' ;a0
movwf t_I_ZCP ;电流过零点等待延时参数
;*******将t_I_ZCP减小********
;*************************正常运行,主循环****************************
run_loop
call PAM_Ton ;T1导通Ton个PWM
call Vi_control ;电流过零信号分析
call Ve_control ;反电势变化情况分析
call PAM_Ton ;T1导通Ton个PWM
call Vi_control_2 ;电流过零信号分析
call Ve_control_2 ;反电势变化情况分析
decfsz Decrease_big,1 ;若 Decrease_big=0,则前跳一步
goto run_loop
incf Decrease_big,1
goto run_loop
;*************************正常运行,主循环****************************
;****************************************主函数*********************************************
;*************************************************************************
rotor_initial
movlw d'180'
movwf OvCu
movlw h'07'
movwf Tu
movlw h'10' ;Tall=h'20'时,PWM频率约为7.14kHz
movwf Tall ;设置PWM占空比=Tu/Tall
bsf ADCON0,1
nop
wait_AD1
btfsc ADCON0,1
goto wait_AD1
movf ADRESH,0
movwf ADH
bsf status,RP0
movf ADRESL,0
movwf ADL
bcf status,RP0
;**************************************** Vcc AD Convertion **************************
movlw h'00'
movwf Ton1
movlw h'0a3' ;a0--11v a3--11.2v a5---11.4v aa--11.7v
movwf Ton0
;比较高位
movf Ton1,0 ;大幅度的减小Ton
subwf ADH,0 ;(ADH-Ton1)减法很怪的,c=0表示发生借位
btfss status,c ;c=1减法不发生借位,即ADH>=Ton1,则前跳一步
goto Ton_AD ;c=0发生借位,溢出,ADH<Ton1
btfss status,z ;z=1,即ADH=Ton1,则前跳一步,比较低位
goto AD_Ton ;z=0,即ADH>Ton1
;比较低位4
movf Ton0,0 ;大幅度的减小Ton
subwf ADL,0 ;(ADL-Ton0)减法很怪的,c=0表示发生借位
btfss status,c ;c=1减法不发生借位,即ADL>=Ton0,则前跳一步
goto Ton_AD ;c=0发生借位,溢出,ADL<Ton0
btfss status,z ;z=1,即ADL=Ton0,则前跳一步,认为Ton>AD
goto AD_Ton ;z=0,即ADL>Ton0
Ton_AD ;AD<a3h=11.2v
movlw d'180'
movwf OvCu
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -