开源BLHELI-S 代码详细解读(四)

这里涉及到一些定时器,PCA,说明一下它们的使用:

; 主时钟是内部24MHz振荡器(或48MHz,以下时间减半)
; 虽然代码中使用了 24/48,但确切的时钟频率是 24.5MHz 或 49.0 MHz
; 定时器 0(41.67ns 计数)始终向上计数并用于
; - RC输入信号脉冲测量

; 定时器 1(41.67ns 计数)始终向上计数并用于
; - DShot 帧同步检测

; 定时器 2(计数 500ns)始终向上计数,用于
; - RC输入信号脉冲超时计数和换相时间

; 定时器 3(计数 500ns)始终向上计数,用于
; - 换相超时

; PCA0(41.67ns 计数)始终向上计数并用于
; - 硬件 PWM 生成

; - 使用了两个道通CEX0和CEX1, 两个pwm互补。

上一篇在检查comp_out超时的时候,会调用一下零位扫描的。这里继续一起读一下。

这个 wait_before_zc_scan,其实比较简单,就是从把timer3的超时设置为Comm_Period4x_L和Comm_Period4x_H, 只有在STARTUP_PHASE和 SHL INITIAL_RUN_PHASE阶段才会设置。

特别地,如果是STARTUP_PHASE,timer3的高位寄存器会加上 64(40h).



;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Wait before zero cross scan routine
;
; No assumptions
;
; Waits for the zero cross scan wait time to elapse
; Also sets up timer 3 for the zero cross scan timeout time
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
wait_before_zc_scan:	
	jnb	Flags0.T3_PENDING, ($+5)  ;jump if Flags0.T3_PENDING is zero
	ajmp	wait_before_zc_scan

	mov	Startup_Zc_Timeout_Cntd, #2
setup_zc_scan_timeout:
	setb	Flags0.T3_PENDING
	orl	EIE1, #80h			; Enable timer 3 interrupts
	mov	A, Flags1
	anl	A, #((1 SHL STARTUP_PHASE)+(1 SHL INITIAL_RUN_PHASE))
	jz	wait_before_zc_scan_exit		

	mov	Temp1, Comm_Period4x_L	; Set long timeout when starting
	mov	Temp2, Comm_Period4x_H
	clr	C
	mov	A, Temp2
	rrc	A
	mov	Temp2, A
	mov	A, Temp1
	rrc	A
	mov	Temp1, A
IF MCU_48MHZ == 0
	clr	C
	mov	A, Temp2
	rrc	A
	mov	Temp2, A
	mov	A, Temp1
	rrc	A
	mov	Temp1, A
ENDIF
	jnb	Flags1.STARTUP_PHASE, setup_zc_scan_timeout_startup_done

	mov	A, Temp2
	add	A, #40h				; Increase timeout somewhat to avoid false wind up
	mov	Temp2, A

setup_zc_scan_timeout_startup_done:
	clr	IE_EA
	anl	EIE1, #7Fh			; Disable timer 3 interrupts
	mov	TMR3CN0, #00h			; Timer 3 disabled and interrupt flag cleared
	clr	C
	clr	A
	subb	A, Temp1				; Set timeout
	mov	TMR3L, A
	clr	A
	subb	A, Temp2		
	mov	TMR3H, A
	mov	TMR3CN0, #04h			; Timer 3 enabled and interrupt flag cleared
	setb	Flags0.T3_PENDING
	orl	EIE1, #80h			; Enable timer 3 interrupts
	setb	IE_EA

wait_before_zc_scan_exit:          
	ret

换相之后有一个等待,就是等t3超时



;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Wait for commutation routine
;
; No assumptions
;
; Waits from zero cross to commutation 
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
wait_for_comm: 
	; Update demag metric
	mov	Temp1, #0
	jnb	Flags0.DEMAG_DETECTED, ($+5)

	mov	Temp1, #1

	mov	A, Demag_Detected_Metric	; Sliding average of 8, 256 when demag and 0 when not. Limited to minimum 120
	mov	B, #7
	mul	AB					; Multiply by 7
	mov	Temp2, A
	mov	A, B					; Add new value for current demag status
	add	A, 					
	mov	B, A
	mov	A, Temp2
	mov	C, B.0				; Divide by 8
	rrc	A					
	mov	C, B.1
	rrc	A
	mov	C, B.2
	rrc	A
	mov	Demag_Detected_Metric, A
	clr	C
	subb	A, #120				; Limit to minimum 120
	jnc	($+5)

	mov	Demag_Detected_Metric, #120

	clr	C
	mov	A, Demag_Detected_Metric	; Check demag metric
	subb	A, Demag_Pwr_Off_Thresh
	jc	wait_for_comm_wait		; Cut power if many consecutive demags. This will help retain sync during hard accelerations

	All_pwmFETs_off
	Set_Pwms_Off

wait_for_comm_wait:
	jnb Flags0.T3_PENDING, ($+5)			
	ajmp	wait_for_comm_wait

	; Setup next wait time
	mov	TMR3RLL, Wt_Zc_Scan_Start_L
	mov	TMR3RLH, Wt_Zc_Scan_Start_H
	setb	Flags0.T3_PENDING
	orl	EIE1, #80h			; Enable timer 3 interrupts
	ret

然后我们去看看换相操作函数, 基本上就是开关fet, 设置pwm ,然后设置com,然后要是反向的话,开关的相会有所不同。

     1. A/B/CcomFET_on/off的操作就是打开关闭端口,这个比较简单。

     2. Set_Comp_Phase_A/B/C, 这个是通过设置CMP0MX来切换哪两个端口给比较器使用,这个上一篇有详细说明了。这里就不重复了。

     3. Set_Pwm_A/B/C则是通过操作crossbar的SKIP寄存来控制pca的pwm在哪个端口输出。对P.INC的针脚布局,P0SKIP在一开始就给设置成0xFF了,就是说外设不会在P0的端口输出。 于是这里就只需要操作 P1SKIP就可以了。 如Set_Pwm_C,   P1SKIP =  37h(00110111b), 即P1.3 P1.6和 P1.7会给外设使用,  根据优先度,PCA0的CEX0会使用P1.3(CpwmFET)输出 CEX1 会在P1.6(CcomFET)输出。 其它类似。Set_Pwm_B是 5Bh  (01011011    BpwmFET p.2 , BcomFET P1.5 ),Set_Pwm_A 是6Dh    (0110 1101      ApwmFET p.1  AcomFET p1.4.


;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Commutation routines
;
; No assumptions
;
; Performs commutation switching 
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
; Comm phase 1 to comm phase 2
comm1comm2:	
	Set_RPM_Out
	jb	Flags3.PGM_DIR_REV, comm12_rev

	clr 	IE_EA				; Disable all interrupts
	BcomFET_off 				; Turn off comfet
	AcomFET_on				; Turn on comfet
	Set_Pwm_C					; To reapply power after a demag cut
	setb	IE_EA
	Set_Comp_Phase_B 			; Set comparator phase
	jmp	comm_exit

comm12_rev:	
	clr 	IE_EA				; Disable all interrupts
	BcomFET_off 				; Turn off comfet
	CcomFET_on				; Turn on comfet (reverse)
	Set_Pwm_A					; To reapply power after a demag cut
	setb	IE_EA
	Set_Comp_Phase_B 			; Set comparator phase
	jmp	comm_exit


; Comm phase 2 to comm phase 3
comm2comm3:	
	Clear_RPM_Out
	jb	Flags3.PGM_DIR_REV, comm23_rev

	clr 	IE_EA				; Disable all interrupts
	CpwmFET_off				; Turn off pwmfet
	Set_Pwm_B					; To reapply power after a demag cut
	AcomFET_on
	setb	IE_EA
	Set_Comp_Phase_C 			; Set comparator phase
	ajmp	comm_exit

comm23_rev:
	clr 	IE_EA				; Disable all interrupts
	ApwmFET_off				; Turn off pwmfet (reverse)
	Set_Pwm_B					; To reapply power after a demag cut
	CcomFET_on
	setb	IE_EA
	Set_Comp_Phase_A 			; Set comparator phase (reverse)
	ajmp	comm_exit


; Comm phase 3 to comm phase 4
comm3comm4:	
	Set_RPM_Out
	jb	Flags3.PGM_DIR_REV, comm34_rev

	clr 	IE_EA				; Disable all interrupts
	AcomFET_off 				; Turn off comfet
	CcomFET_on				; Turn on comfet
	Set_Pwm_B					; To reapply power after a demag cut
	setb	IE_EA
	Set_Comp_Phase_A 			; Set comparator phase
	jmp	comm_exit

comm34_rev:	
	clr 	IE_EA				; Disable all interrupts
	CcomFET_off 				; Turn off comfet (reverse)
	AcomFET_on				; Turn on comfet (reverse)
	Set_Pwm_B					; To reapply power after a demag cut
	setb	IE_EA
	Set_Comp_Phase_C 			; Set comparator phase (reverse)
	jmp	comm_exit


; Comm phase 4 to comm phase 5
comm4comm5:	
	Clear_RPM_Out
	jb	Flags3.PGM_DIR_REV, comm45_rev

	clr 	IE_EA				; Disable all interrupts
	BpwmFET_off				; Turn off pwmfet
	Set_Pwm_A					; To reapply power after a demag cut
	CcomFET_on
	setb	IE_EA
	Set_Comp_Phase_B 			; Set comparator phase
	jmp	comm_exit

comm45_rev:
	clr 	IE_EA				; Disable all interrupts
	BpwmFET_off				; Turn off pwmfet
	Set_Pwm_C
	AcomFET_on				; To reapply power after a demag cut
	setb	IE_EA
	Set_Comp_Phase_B 			; Set comparator phase
	jmp	comm_exit


; Comm phase 5 to comm phase 6
comm5comm6:	
	Set_RPM_Out
	jb	Flags3.PGM_DIR_REV, comm56_rev

	clr 	IE_EA				; Disable all interrupts
	CcomFET_off 				; Turn off comfet
	BcomFET_on				; Turn on comfet
	Set_Pwm_A					; To reapply power after a demag cut
	setb	IE_EA
	Set_Comp_Phase_C 			; Set comparator phase
	jmp	comm_exit

comm56_rev:
	clr 	IE_EA				; Disable all interrupts
	AcomFET_off 				; Turn off comfet (reverse)
	BcomFET_on				; Turn on comfet
	Set_Pwm_C					; To reapply power after a demag cut
	setb	IE_EA
	Set_Comp_Phase_A 			; Set comparator phase (reverse)
	jmp	comm_exit


; Comm phase 6 to comm phase 1
comm6comm1:	
	Clear_RPM_Out
	jb	Flags3.PGM_DIR_REV, comm61_rev

	clr 	IE_EA				; Disable all interrupts
	ApwmFET_off				; Turn off pwmfet
	Set_Pwm_C
	BcomFET_on				; To reapply power after a demag cut
	setb	IE_EA
	Set_Comp_Phase_A 			; Set comparator phase
	jmp	comm_exit

comm61_rev:
	clr 	IE_EA				; Disable all interrupts
	CpwmFET_off				; Turn off pwmfet (reverse)
	Set_Pwm_A
	BcomFET_on				; To reapply power after a demag cut
	setb	IE_EA
	Set_Comp_Phase_C 			; Set comparator phase (reverse)

comm_exit:
	ret

未完等续, 下一篇我们再看看如何计算下一次换相时间

相关推荐

  1. 开源BLHELI-S 代码详细解读(

    2024-02-20 16:10:02       22 阅读
  2. [Algorithm][双指针][复写零]详细解读 + 代码实现

    2024-02-20 16:10:02       12 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-20 16:10:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-20 16:10:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-20 16:10:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-20 16:10:02       18 阅读

热门阅读

  1. Vue3中watch与watchEffect的区别

    2024-02-20 16:10:02       23 阅读
  2. OSS业务存储适配器模式

    2024-02-20 16:10:02       21 阅读
  3. python数据分析numpy基础之var求数组方差

    2024-02-20 16:10:02       26 阅读
  4. 缓存使用常见思路及问题

    2024-02-20 16:10:02       18 阅读
  5. BUG:required a single bean, but 2 were found:

    2024-02-20 16:10:02       22 阅读
  6. Prompt Engineering 提示工程教程详情

    2024-02-20 16:10:02       29 阅读
  7. LeetCode_20_简单_有效的括号

    2024-02-20 16:10:02       31 阅读
  8. Github 2024-02-19 开源项目日报 Top10

    2024-02-20 16:10:02       31 阅读