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

📄 bl_esc_100a_307b.asm

📁 本设计是关于无刷电机的设计源程序 只可惜是会变的 不过是很好的资料哦
💻 ASM
📖 第 1 页 / 共 5 页
字号:

		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 + -