📄 bl-4428.asm
字号:
nFET_off: sbr flags0, (1<<I_OFF_CYCLE) ; PWM state = off cycle
; switch appropriate nFET off
sbrs flags0, C_FET
rjmp test_AnFET
; C_FET is active
sbrs flags1, FULL_POWER
CnFET_off ; Cn off
rjmp reload_t0_off_cycle
test_AnFET: sbrs flags0, A_FET
rjmp switch_BnFET
; A_FET is active
switch_AnFET: sbrs flags1, FULL_POWER
AnFET_off ; An off
rjmp reload_t0_off_cycle
; B_FET is active
switch_BnFET: sbrs flags1, FULL_POWER
BnFET_off ; Bn off
; reload timer0 with the appropriate value
reload_t0_off_cycle:
mov i_temp1, tcnt0_power_on
subi i_temp1, -POWER_RANGE ; adi i_temp1, POWER_RANGE
com i_temp1 ; timer0 increments
out TCNT0, i_temp1
rjmp t0_int_exit
; reload timer90 + switch appropriate nFET on
t0_on_cycle: mov i_temp1, tcnt0_power_on
out TCNT0, i_temp1 ; reload t0
cbr flags0, (1<<I_OFF_CYCLE) ; PWM state = on cycle (no off cycle)
; switch appropriate nFET on
nFET_on: sbrs flags0, C_FET ; is Cn choppered ?
rjmp test_AnFET_on ; .. no - test An
sbrs flags1, POWER_OFF
CnFET_on ; Cn on
rjmp eval_power_state
test_AnFET_on: sbrs flags0, A_FET ; is An choppered ?
rjmp sw_BnFET_on ; .. no - Bn has to be choppered
sbrs flags1, POWER_OFF
AnFET_on ; An on
rjmp eval_power_state
sw_BnFET_on: sbrs flags1, POWER_OFF
BnFET_on ; Bn on
; evaluate power state
eval_power_state:
cpi i_temp1, MAX_POWER+1
brsh not_full_power
; FULL POWER
sbr flags1, (1<<FULL_POWER) ; tcnt0_power_on = MAX_POWER means FULL_POWER
cbr flags1, (1<<POWER_OFF)
rjmp t0_int_exit
not_full_power: cpi i_temp1, NO_POWER
brlo neither_full_nor_off
; POWER OFF
cbr flags1, (1<<FULL_POWER) ; tcnt0_power_on = NO_POWER means power off
sbr flags1, (1<<POWER_OFF)
rjmp t0_int_exit
neither_full_nor_off:
cbr flags1, (1<<FULL_POWER) ; tcnt0_power_on = MAX_POWER means FULL_POWER
cbr flags1, (1<<POWER_OFF)
t0_int_exit: sbrc flags2, POFF_CYCLE
sbr flags1, (1<<POWER_OFF)
out SREG, i_sreg
reti
;-----bko-----------------------------------------------------------------
urxc: in i_sreg, SREG
in i_temp1, UDR
dec motor_total ; #HH#
cpi i_temp1, 0xf5
breq x3d_sync
brcc unknown_cmd
sbrc flags2, NO_SYNC
rjmp urxc_exit ; trough away
dec motor_count
brne urxc_exit
; 10kHz do nothing range is 0-200
; mov ZH, i_temp1
; 16kHz range is 0-125 - divide by 2 and add a quarter
lsr i_temp1 ; 0-200 ==> 0-100
mov i_temp2, i_temp1
lsr i_temp2
lsr i_temp2
add i_temp1, i_temp2
mov ZH, i_temp1
; 20kHz range is 0-100 - divide by 2
; lsr i_temp1 ; 0-200 ==> 0-100
; mov ZH, i_temp1
ldi i_temp2, MOTOR_NUMBER
mov motor_count, i_temp2
sbr flags2, (1<<NO_SYNC)
ldi i_temp1, CONTROL_TOT
mov control_timeout, i_temp1
rjmp urxc_exit
unknown_cmd: sts uart_command, i_temp1
rjmp urxc_exit
x3d_sync: cbr flags2, (1<<NO_SYNC)
mov i_temp1, motor_total
cpi i_temp1, 0x00
breq x3d_sync_ok
HHDEBUGLED_on
rjmp x3d_sync_finish
x3d_sync_ok: HHDEBUGLED_off
x3d_sync_finish:
ldi i_temp1, MOTOR_MAX
mov motor_total, i_temp1
urxc_exit: out SREG, i_sreg
reti
utxc: in i_sreg, SREG
ld i_temp1,X+
out UDR, i_temp1
dec uart_cnt
brne utxc_90
cbi UCSRB, TXCIE ; disable irq
utxc_90: out SREG, i_sreg
reti
;-----bko-----------------------------------------------------------------
; beeper: timer0 is set to 1祍/count
beep_f1: ldi temp4, 200
ldi temp2, 80
rjmp beep
beep_f2: ldi temp4, 180
ldi temp2, 100
rjmp beep
beep_f3: ldi temp4, 160
ldi temp2, 120
rjmp beep
beep_f4: ldi temp4, 100
ldi temp2, 200
rjmp beep
beep: clr temp1
out TCNT0, temp1
BpFET_on ; BpFET on
AnFET_on ; CnFET on
beep_BpCn10: in temp1, TCNT0
cpi temp1, 64 ; 32祍 on
brne beep_BpCn10
BpFET_off ; BpFET off
AnFET_off ; CnFET off
ldi temp3, 16 ; 2040祍 off
beep_BpCn12: clr temp1
out TCNT0, temp1
beep_BpCn13: in temp1, TCNT0
cp temp1, temp4
brne beep_BpCn13
dec temp3
brne beep_BpCn12
dec temp2
brne beep
ret
wait30ms: ldi temp2, 30
beep_BpCn20: ldi temp3, 16
beep_BpCn21: clr temp1
out TCNT0, temp1
beep_BpCn22: in temp1, TCNT0
cpi temp1, 255
brne beep_BpCn22
dec temp3
brne beep_BpCn21
dec temp2
brne beep_BpCn20
ret
; 256 periods = 261ms silence
wait260ms: ldi temp2, 0 ; = 256
beep2_BpCn20: ldi temp3, 16
beep2_BpCn21: clr temp1
out TCNT0, temp1
beep2_BpCn22: in temp1, TCNT0
cpi temp1, 255
brne beep2_BpCn22
dec temp3
brne beep2_BpCn21
dec temp2
brne beep2_BpCn20
ret
;-----bko-----------------------------------------------------------------
tcnt1_to_temp: ldi temp4, T1STOP ; stop timer1
out TCCR1B, temp4
ldi temp4, T1CK8 ; preload temp with restart timer1
in temp1, TCNT1L ; - the preload cycle is needed to complete stop operation
in temp2, TCNT1H
out TCCR1B, temp4
ret ; !!! ext0int stays disabled - must be enabled again by caller
; there seems to be only one TEMP register in the AVR
; if the ext0int interrupt falls between readad LOW value while HIGH value is captured in TEMP and
; read HIGH value, TEMP register is changed in ext0int routine
;-----bko-----------------------------------------------------------------
evaluate_sys_state:
cbr flags1, (1<<EVAL_SYS_STATE)
sbrs flags0, T1OVFL_FLAG
rjmp eval_sys_s99
; do it not more often as every 32祍
cbr flags0, (1<<T1OVFL_FLAG)
rjmp eval_sys_s99 ; disabled ;-)
; control current
eval_sys_i: rjmp eval_sys_i_ok
mov temp1, current_err
cpi temp1, CURRENT_ERR_MAX
brcc panic_exit
inc current_err
rjmp eval_sys_ub
eval_sys_i_ok: tst current_err
breq eval_sys_ub
dec current_err
; control voltage
eval_sys_ub: rjmp eval_sys_ub_ok
mov temp1, sys_control
cpi temp1, POWER_RANGE
brcc eval_sys_s99
inc sys_control
rjmp eval_sys_s99
eval_sys_ub_ok: tst sys_control
breq eval_sys_s99
dec sys_control
eval_sys_s99: ret
panic_exit: ; !!!!!! OVERCURRENT !!!!!!!!
cli
rjmp reset
;-----bko-----------------------------------------------------------------
set_new_duty: mov temp1, ZH
sub temp1, sys_control
brcc set_new_duty10
ldi temp1, MIN_DUTY-1
; evaluate RPM range
set_new_duty10: lds temp2, timing_x
tst temp2
brne set_new_duty12
lds temp2, timing_h ; get actual RPM reference high
cpi temp2, PWR_RANGE1 ; lower range1 ?
brcs set_new_duty20 ; on carry - test next range
; lower as range1
set_new_duty12: sbr flags2, (1<<RPM_RANGE1)
sbr flags2, (1<<RPM_RANGE2)
ldi temp2, PWR_MAX_RPM1 ; higher than range1 power max ?
cp temp1, temp2
brcs set_new_duty40 ; on carry - not higher, no restriction
mov temp1, temp2 ; low (range1) RPM - set PWR_MAX_RPM1
rjmp set_new_duty40
; higher as range1
set_new_duty20: cpi temp2, PWR_RANGE2 ; lower range2 ?
brcs set_new_duty30 ; on carry - not lower, no restriction
set_new_duty22: cbr flags2, (1<<RPM_RANGE1)
sbr flags2, (1<<RPM_RANGE2)
ldi temp2, PWR_MAX_RPM2 ; higher than range2 power max ?
cp temp1, temp2
brcs set_new_duty40 ; on carry - not higher, no restriction
mov temp1, temp2 ; low (range2) RPM - set PWR_MAX_RPM2
rjmp set_new_duty40
; higher as range2
set_new_duty30: cbr flags2, (1<<RPM_RANGE1)+(1<<RPM_RANGE2)
; range limits are evaluated - look for STARTUP conditions
set_new_duty40: sbrs flags2, STARTUP
rjmp set_new_duty50
ldi temp3, PWR_STARTUP ; at least PWR_STARTUP ?
cp temp1, temp3
brcc set_new_duty42 ; on no carry - higher than PWR_STARTUP, test PWR_MAX_STARTUP
ldi temp1, PWR_STARTUP ; lower - set to PWR_STARTUP
rjmp set_new_duty50
set_new_duty42: ldi temp3, PWR_MAX_STARTUP ; limit power in startup phase
cp temp1, temp3
brcs set_new_duty50 ; on carry - not higher, test range 2
mov temp1, temp3 ; set PWR_MAX_STARTUP limit
set_new_duty50: com temp1 ; down-count to up-count (T0)
mov tcnt0_pwron_next, temp1 ; save in next
; tcnt0_power_on is updated to tcnt0_pwron_next in acceptable steps
ret
;-----bko-----------------------------------------------------------------
evaluate_rpm: cbr flags1, (1<<EVAL_RPM)
lds temp3, rpm_x
lds temp2, rpm_h
lds temp1, rpm_l ; subtract 1/256
sub temp1, temp2
sts rpm_l, temp1
lds temp1, rpm_h
sbc temp1, temp3
sts rpm_h, temp1
lds temp1, rpm_x
sbci temp1, 0
sts rpm_x, temp1
lds temp3, timing_acc_x
lds temp2, timing_acc_h
lds temp1, timing_acc_l
lsr temp3 ; make one complete commutation cycle
ror temp2
ror temp1
lsr temp3
ror temp2
ror temp1
; temp3 is zero now - for sure !!
sts timing_acc_x, temp3
sts timing_acc_h, temp3
sts timing_acc_l, temp3
; and add the result as 1/256
lds temp3, rpm_l
add temp3, temp1
sts rpm_l, temp3
lds temp3, rpm_h
adc temp3, temp2
sts rpm_h, temp3
ldi temp1, 0
lds temp3, rpm_x
adc temp3, temp1
sts rpm_x, temp3
ret
;-----bko-----------------------------------------------------------------
set_all_timings:
ldi YL, low (timeoutSTART)
ldi YH, high (timeoutSTART)
sts wt_OCT1_tot_l, YL
sts wt_OCT1_tot_h, YH
ldi temp3, 0xff
ldi temp4, 0x1f
sts wt_comp_scan_l, temp3
sts wt_comp_scan_h, temp4
sts com_timing_l, temp3
sts com_timing_h, temp4
set_timing_v: ldi ZL, 0x03
sts timing_x, ZL
ldi temp4, 0xff
sts timing_h, temp4
ldi temp3, 0xff
sts timing_l, temp3
ret
;-----bko-----------------------------------------------------------------
update_timing: rcall tcnt1_to_temp
sts tcnt1_sav_l, temp1
sts tcnt1_sav_h, temp2
add temp1, YL
adc temp2, YH
ldi temp4, (1<<TOIE1)+(1<<TOIE0)
out TIMSK, temp4
out OCR1AH, temp2
out OCR1AL, temp1
sbr flags0, (1<<OCT1_PENDING)
ldi temp4, (1<<TOIE1)+(1<<OCIE1A)+(1<<TOIE0) ; enable interrupt again
out TIMSK, temp4
; calculate next waiting times - timing(-l-h-x) holds the time of 4 commutations
lds temp1, timing_l
lds temp2, timing_h
lds ZL, timing_x
sts zero_wt_l, temp1 ; save for zero crossing timeout
sts zero_wt_h, temp2
tst ZL
breq update_t00
ldi temp4, 0xff
sts zero_wt_l, temp4 ; save for zero crossing timeout
sts zero_wt_h, temp4
update_t00:
lsr ZL ; build a quarter
ror temp2
ror temp1
lsr ZL
ror temp2
ror temp1
lds temp3, timing_l ; .. and subtract from timing
lds temp4, timing_h
lds ZL, timing_x
sub temp3, temp1
sbc temp4, temp2
sbci ZL, 0
lds temp1, tcnt1_sav_l ; calculate this commutation time
lds temp2, tcnt1_sav_h
lds YL, last_tcnt1_l
lds YH, last_tcnt1_h
sts last_tcnt1_l, temp1
sts last_tcnt1_h, temp2
sub temp1, YL
sbc temp2, YH
sts last_com_l, temp1
sts last_com_h, temp2
add temp3, temp1 ; .. and add to timing
adc temp4, temp2
ldi temp2, 0
adc ZL, temp2
; limit RPM to 120.000
tst ZL
brne update_t90
tst temp4
breq update_t10
cpi temp4, 0x02
brne update_t90
cpi temp3, 0x98 ; 0x298 = 120.000 RPM
brcc update_t90
; set RPM to 120.000
update_t10: ldi temp4, 0x02
ldi temp3, 0x98
tst run_control
brne update_t90 ; just active
ldi temp1, 0xff ; not active - reactivate
mov run_control, temp1
update_t90: sts timing_l, temp3
sts timing_h, temp4
sts timing_x, ZL
cpi ZL, 4 ; limit range to 0x3ffff
brcs update_t99
rcall set_timing_v
update_t99: lds temp1, timing_acc_l
add temp1, temp3
sts timing_acc_l, temp1
lds temp1, timing_acc_h
adc temp1, temp4
sts timing_acc_h, temp1
lds temp1, timing_acc_x
adc temp1, ZL
sts timing_acc_x, temp1
lsr ZL ; a 16th is the next wait before scan
ror temp4
ror temp3
lsr ZL
ror temp4
ror temp3
lsr ZL
ror temp4
ror temp3
lsr ZL
ror temp4
ror temp3
sts wt_comp_scan_l, temp3
sts wt_comp_scan_h, temp4
; use the same value for commutation timing (15
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -