📄 bl_esc_100a_307b.asm
字号:
mov R2, a
mov a, R1
rrc a
mov R1, a
END_T_ADJ: ret
;--
T_ADV_ADJ_END:
STORE_ADV_T_L: mov a, TMR2L
clr c
subb a, R1 ; Advanced time "L" is in R1
mov R1, a ; R1 is temp
STORE_ADV_T_H: mov a, TMR2H
subb a, R2
; jc NO_ADVANCE_TIME_SET
mov R2, a ; Advanced time "H" is in R2
;---------
STICK_POWER_ADDING:
mov a, ON_DUTY
jz ZERO_ON_DUTY ; no adding power. keep 50% duty
mov b, ZC_STEPS ; zero cross power up STEPS
mul ab
mov TMR2L, a ; TMR2L is temporary data storage for T2 Time set as stick control "L"
mov TMR2H, b ; TMR2H is temporary data storage for T2 Time set as stick control "H"
;-----------
COMP_FULL_ON_LIMIT_CHK: mov a, R1 ; Advanced timing "L"
clr c
subb a, TMR2L ;
mov ZC_OFF_DUTY_L, a ; set ZC power off duty control time
COMP_FULL_ON_H: mov a, R2 ; Advanced timing "H"
subb a, TMR2H
mov ZC_OFF_DUTY_H, a ; set ZC power off duty control time
jc FULL_POWER_TIME_SET ; Over 100% setting?
ZC_ADD_POWER: mov R1, TMR2L
mov R2, TMR2H
jmp ZC_T2_SET
FULL_POWER_TIME_SET: mov ZC_OFF_DUTY_H, #0 ; full on power setting
mov R2, #0
mov ZC_OFF_DUTY_L, #1 ; ZC_OFF_DUTY_L must be never zero
mov R1, #1
ZC_T2_SET: mov a, R1 ; get low byte of T2 zero cross timing data (Also Advanced timing "L", if time set over)
cpl a ; T2 is the count-up timer
mov TMR2L, a ; low byte re-load data
mov a, R2 ; get high byte of T2 zero cross timing data(Also Advanced timing "H", if time set over)
cpl a
mov TMR2H, a ; high byte re-load data
clr TF2H
setb TR2
ret
;------------------
ZERO_ON_DUTY: mov ZC_OFF_DUTY_L, R1 ; keep 50% power duty
mov ZC_OFF_DUTY_H, R2
jmp ZC_T2_SET
;*****************
ZERO_CROSS_OFF_DUTY: call CURRENT_LIMITER
;call LESS_THAN_5V_CHECK
ZC_OFF_TIME_SET: ;;;;*****************
;call SPIN_FREE
call SPIN_FREE8
mov a, DRIVE_STATE
clr c
subb a, #6 ; State 6 driving?
jnz ZC_OFF_TIME_SET1
;call CHECK_TOP_CELL_VOLTAGE ; voltage down and over current check routine
;;;;;********
ZC_OFF_TIME_SET1: call WDT_OFF
clr TR2
mov TMR2L, ZC_OFF_DUTY_L
mov TMR2H, ZC_OFF_DUTY_H
mov a, TMR2L ; get low byte of T2 zero cross timing data
cpl a ; T2 is the count-up timer
mov TMR2L, a ; low byte re-load data
mov a, TMR2H ; get high byte of T2 zero cross timing data
cpl a
mov TMR2H, a ; high byte re-load data
clr TF2H
setb TR2
ZC_POWER_OFF_TIME: jnb TF2H, ZC_POWER_OFF_TIME
ret
MOTOR_UNUSUAL_STOP: call SPIN_FREE
JMP GET_BEMF1 ; Keep run
;--------------
INDUCKTIVE_KICK_DET_HL: call START_T2
call WAIT_1uS ; Avoid inductive kick front edge
IND_KICK_POS_LEVEL_CHK:
mov a, CPT0CN ; Get Comparator result
anl a, #01000000b ; Get CP0OUT bit
jnz IND_KICK_NEG_EDGE_CHK ; The inductive kick is already done in off duty timing.
clr TR2
mov TMR2M_H, TMR2H
mov TMR2M_L, TMR2L
setb TR2
ret
IND_KICK_NEG_EDGE_CHK: clr c
mov a, TMR2H
subb a, #IND_KICK_TIME_CHECK ; Sync out value in T2. Over 350uS to get zero coross point as over load.
jnc SMALL_ZC_MARGIN_NEG
ZC_NEG_CHK: call WAIT_1uS ; Comparator responce
mov a, CPT0CN ; Get Comparator result
anl a, #01000000b ; Get CP0OUT bit
jnz IND_KICK_NEG_EDGE_CHK ; checking the negative edge of inductive kick.
clr TR2
mov TMR2M_H, TMR2H
mov TMR2M_L, TMR2L
setb TR2
ret
SMALL_ZC_MARGIN_NEG: call SPIN_FREE
mov a, ON_DUTY ; May be accelating. Power down to avoid un-sync.
clr c
subb a, #1
jc ZERO_ON_DUTY_NEG
mov ON_DUTY, a
ZERO_ON_DUTY_NEG: jmp ZC_NEG_CHK
;---------------------
ZERO_CROSS_CHK_UP: call WAIT_10uS ; Avoid chatter
clr EA
ZERO_CROSS_CHK_U: mov a, TMR2H
clr c
subb a, #REAR_EDGE_TO_ZC_POINT ; Sync out value in T2. Over 250uS to get zero coross point as over load.
jnc COULD_NOT_CATCH_CROSS_POINT
mov CPT0CN, #10000000b
call WAIT_1uS ; comparator responce.
mov a, CPT0CN ; Get Comparator result
anl a, #01000000b ; Get CP0OUT bit
jz ZERO_CROSS_CHK_U ; checking the UP SLOPE until over zero cross point
setb EA
STOP_T2_2: clr TR2 ; stop the T2 count-up
CALC_TIMING_ADVANCE: jmp OVER_ZERO_CHECK
;------------
COULD_NOT_CATCH_CROSS_POINT: call SPIN_FREE
jmp MOTOR_UNUSUAL_STOP
;------------
CHECK_T2_END:
;call WAIT_20uS
T2_END_CHECK: jnb TF2H, T2_END_CHECK ; wait untill T2 high byte over flow flag for T2 time over.
clr TF2H
ret
;------------
;as well as Auto timing adjust routine
OVER_SHOOT_CHK: call WAIT_1uS ; avoid comparator responce delay
OVER_SHOOT_CHK_: jnb TF2H, OVER_SHOOT_CHK_
ret
OVER_SHOOT_CHK_UD: mov a, CPT0CN ; Get Comparator result
anl a, #01000000b ; Get CP0OUT bit. Checking the SLOPE until over GND or VCC.
jnz KEEP_RUN ; No. No Problem.
;call SPIN_FREE ; TEST ONLY
ret ; SLOPE over GND or VCC.
KEEP_RUN: jnb TF2H, OVER_SHOOT_CHK_UD ; Checking T2 high byte over flow flag for T2 time over.
;call SPIN_FREE ; TEST ONLY
ret ; Yes, T2 time over.
;------------------------------------------
TIMER_20uS: call WAIT_20uS
ret
;------------------------------------------
;-------------------
SAME_RPM: jmp SET_ON_DUTY_TIMER
;-------------------
;------------------------------------------
GET_COMP_DATA:
; mov a, ON_DUTY
; clr c
; subb a, #SLOW_START-1 ; <<<<<<<< Spin enough as BEMF enough?
; jc SPIN_SPEED_NOT_ENOUGH
; call COMP_MEASURE ; to get high responce
; ret
SPIN_SPEED_NOT_ENOUGH:
mov COMP_REMEASURE_COUNTER, #50
call COMP_MEASURE
;call WDT_OFF ; Motor off and No burning if re-measure loop time is so long.
GET_FIRST_BEMF_DATA:
mov PREV_COMP_D, COMP_D
RE_MEASURE: dec COMP_REMEASURE_COUNTER ; BEMF Re-measure loop timing limitter
call COMP_MEASURE ; Re-check
mov a, COMP_D ;
cjne a, PREV_COMP_D, NOISE_DATA ; Same comp. result?
GOT_BEMF_DATA:
ret ; Yes
NOISE_DATA: mov a, COMP_REMEASURE_COUNTER ; Try 50 times to get stable result.
jz NOISE
mov PREV_COMP_D, COMP_D ; No
jmp RE_MEASURE
NOISE: ;mov a, COMP_D ; system failer
jmp NOISE
jmp GOT_BEMF_DATA
;-----------------------------------------------------------------------------
; Interrupt routine to get Rx input pulse
;-----------------------------------------------------------------------------
PCA0_PLS: clr CCF0 ; clear PCA0 module0 interrupt flag
push PSW ; Program Status Word, preserve registers
mov STORAGE_B, b
push acc
Capture_Edge_check:
mov a, PCA0CPM0
anl a, #00100000b ;Caputure rise edge select data on PCA0, is bit 5
jz fall_edge
;
rise_edge: mov PCA0_CAP_L, PCA0CPL0 ; Save 16 bit counter low byte value at positive front edge time
mov PCA0_CAP_H, PCA0CPH0 ; Save 16 bit counter high byte value at positive front edge time
mov PCA0CPM0, #00010001b ; PCA0 is captured by negative edge on P0.7 first and generates the interrupt.
pop acc
mov b, STORAGE_B
pop PSW
reti
;
fall_edge: mov PCA0CPM0, #00100001b ; PCA0 is captured by positive edge on P0.7 first and generates the interrupt.
mov a, PCA0CPL0
clr c
subb a, PCA0_CAP_L
mov PULSE_WIDTH_L, a
mov a, PCA0CPH0
subb a, PCA0_CAP_H
mov PULSE_WIDTH_H, a
clr c
mov a, PULSE_WIDTH_L
subb a, #LOW(CTRL_MIN) ; offset control minimum pulse width(about 1mS)
mov PULSE_WIDTH_L, a
mov a, PULSE_WIDTH_H
subb a, #HIGH(CTRL_MIN) ; offset control minimum pulse width
jc ALMOST_ZERO ; Minus after offset adj.
mov PULSE_WIDTH_H, a
CNTRL_PULSE_CHK:
mov a, PULSE_WIDTH_H ; 00 - 09 range for normal input.
jz MIN_WIDTH_NEGO
jmp MAX_WIDTH_CHK
MIN_WIDTH_NEGO:
mov a, PULSE_WIDTH_L
clr c
subb a, #080h ; no need low nibble. Less than "8" is Zero
jc ALMOST_ZERO
MAX_WIDTH_CHK:
mov a, PULSE_WIDTH_H ; 00 - 09 range for normal input.
clr c
subb a, #10
jnc BAD_PULSE ; range over pulse(over 10 or less than 0)
mov a, PULSE_WIDTH_L
mov CONTROL_DATA_L, a
mov a, PULSE_WIDTH_H
mov CONTROL_DATA_H, a
;--------
DUTY_CALC: mov a, CONTROL_DATA_L ; The pulse width count resolution is 0000 - 0900
anl a, #11110000b
rr a ; no need low nibble
rr a
rr a
rr a
mov b, a
mov a, CONTROL_DATA_H
anl a, #00001111b
clr c
subb a, #9 ; over 8 as 9?
jz max_08h_hi
jmp cut_hi_nibble_0
max_08h_hi: mov a, CONTROL_DATA_H
dec a
jmp cut_hi_nibble
cut_hi_nibble_0:
mov a, CONTROL_DATA_H
cut_hi_nibble:
rl a ; not use in upper nibble
rl a
rl a
rl a
add a,b
mov CONTROL_DATA, a
clr c ;
subb a, CONTROL_DATA_MAX ; When over heat or Li-Po voltage down, Then MAX duty decreaced.
jnc MAX_DOWN
jmp RETURN_I
MAX_DOWN:
mov CONTROL_DATA, CONTROL_DATA_MAX ; Power limit at emergency condition ;
RETURN_I: mov a, CONTROL_DATA ; input pulse noise filter
clr c
subb a, TEMP4 ; Is it same as previous Rx in pulse width?
jz RET_I ; Yes.
mov TEMP4, CONTROL_DATA ; No.
RET_I: mov INPUT_COUNTER_L, #0 ; clear input signal lose check counter
mov INPUT_COUNTER_H, #0 ; This counter is cleared in State2 on
pop acc
mov b, STORAGE_B
pop PSW
reti
ALMOST_ZERO: mov CONTROL_DATA, #1 ; Debug on Mar. 8th '05
jmp RETURN_I
BAD_PULSE: jmp RETURN_I
;------------------------------------
; Timer0 16bit counter with pre-scaled clock is 24.5MHz/12=490nS.
START_T0: mov TL0, #0 ;
mov TH0, #0 ;
clr TF0
setb TR0
ret
; Timer1 16bit counter with pre-scaled clock is 24.5MHz/12=490nS.
START_T1: clr TR1
mov TL1, #0 ;
mov TH1, #0 ;
clr TF1
setb TR1
ret
;
; Timer2 16bit counter with auto re-load, pre-scaled clock is 1/12=490nS.
T2_SET: anl CKCON, #11001111b ; T2 clock source select internal OSC
orl TMR2CN, #00000100b ; Enable Timer2
;;;;**********
anl CKCON, #11001111b ; Timer2 with 1/12 sys. clock.
jmp START_T2
H_T2_SET: mov CKCON, #0 ; T2 clock source select internal OSC
orl CKCON, #00110000b ; Timer2 with sys. clock.
orl TMR2CN, #00000100b ; Enable Timer2
;;;;**********
START_T2: clr TR2
mov TMR2RLL, #0h ; low byte re-load data
mov TMR2RLH, #0h ; High byte re-load data
mov TMR2L, #0h ;
mov TMR2H, #0h ;
clr TF2H
clr TF2L
setb TR2
ret
;
START_T3: anl TMR3CN, #00111011b ; clr TF3H, clr TF3L and clr TR3 "<<<<<<<<
mov TMR3RLL, #0h ; low byte re-load data;
mov TMR3RLH, #0h ; High byte re-load data
mov TMR3L, #0h ;
mov TMR3H, #0h ;
orl TMR3CN, #00000100b ; setb TR3
ret
;------------
; BEMF run power duty control timer routine
ON_TIMER:
;setb P1.7
anl TMR3CN, #11111011b ; clr TR3 to get BEMF off-duty time
mov BEMF_OFF_DUTY_TIME_L, TMR3L ; get off duty time
mov BEMF_OFF_DUTY_TIME_H, TMR3H
call START_T3 ; start to measure the on-duty time by T3
L1: mov a, ON_DUTY ; on-duty timer
add a, ON_DUTY ; x2
;add a, ON_DUTY ; x3
mov DUTY, a
L2: call WAIT_500nS
djnz DUTY, L2 ; High speed sampling
;clr P1.7
OFF_DUTY: anl TMR3CN, #11111011b ; stop timer3 to get BEMF on-duty time
call SPIN_FREE ; set off-duty
mov R1, TMR3L ; get on-duty time
mov R2, TMR3H
;
mov a, BEMF_OFF_DUTY_TIME_L
clr c
add a, R1
mov BEMF_DUTY_TIME_L, a
mov a, BEMF_OFF_DUTY_TIME_H
addc a, R2
mov BEMF_DUTY_TIME_H, a ; Storage sampling time using for returning from ZC mode
;
call TIMING_ADVAN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -