You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

6848 lines
209 KiB

$NOMOD51
;**** **** **** **** ****
;
; BLHeli program for controlling brushless motors in helicopters
;
; Copyright 2011, 2012 Steffen Skaug
; This program is distributed under the terms of the GNU General Public License
;
; This file is part of BLHeli.
;
; BLHeli is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; BLHeli is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with BLHeli. If not, see <http://www.gnu.org/licenses/>.
;
;**** **** **** **** ****
;
; The software was initially designed for use with Eflite mCP X, but is now adapted to a copters/planes in general
;
; The software was inspired by and started from from Bernard Konze's BLMC: http://home.versanet.de/~bkonze/blc_6a/blc_6a.htm
; And also Simon Kirby's TGY: https://github.com/sim-/tgy
;
; This file is best viewed with tab width set to 5
;
; The input signal can be positive 1kHz, 2kHz, 4kHz or 8kHz PWM (taken from the "resistor tap" on mCPx)
; And the input signal can be PPM (1-2ms) at rates up to several hundred Hz.
; The code adapts itself to the various input modes/frequencies
; The code ESC can also be programmed to accept inverted input signal.
;
; The first lines of the software must be modified according to the chosen environment:
; Uncomment the selected ESC and main/tail/multi mode
; BESC EQU "ESC"_"mode"
;
;**** **** **** **** ****
; Revision history:
; - Rev1.0: Initial revision based upon BLHeli for AVR controllers
; - Rev2.0: Changed "Eeprom" initialization, layout and defaults
; Various changes and improvements to comparator reading. Now using timer1 for time from pwm on/off
; Beeps are made louder
; Added programmable low voltage limit
; Added programmable damped tail mode (only for 1S ESCs)
; Added programmable motor rotation direction
; - Rev2.1: (minor changes by 4712)
; Added Disable TX Programming by PC Setup Application
; therfore changed EEPROM_LAYOUT_REVISION = 8
; Added Vdd Monitor as reset source when writing to "EEProm"
; Changed for use of batch file to assemble, link and make hex files
; - Rev2.2: (minor changes by 4712)
; Added Disable Throttle Re-Arming every motor start by PC Setup Application
; - Rev2.3: (minor changes by 4712)
; Added bugfixed (2x CLR C before j(n)c operations)thx Steffen!
; - Rev2.4: Revisions 2.1 to 2.3 integrated
; - Rev3.0: Added PPM (1050us-1866us) as accepted input signal
; Added startup rpm as a programming parameter
; Added startup acceleration as a programming parameter
; Added option for using voltage measurements to compensate motor power
; Added governor target by setup as a governor mode option
; Governor is kept active regardless of rpm
; Smooth governor spoolup/down in arm and setup modes
; Increased governor P and I gain programming ranges
; Increased and changed low voltage limit programming range
; Disabled tx programming entry for all but the first arming sequence after power on
; Made it possible to skip parameters in tx programming by setting throttle midstick
; Made it default not to rearm for every restart
; - Rev3.1: Fixed bug that prevented chosen parameter to be set in tx programming
; - Rev3.2: ...also updated the EEPROM revision parameter
; - Rev3.3: Fixed negative number bug in voltage compensation
; Fixed bug in startup power calculation for non-default power
; Prevented possibility for voltage compensation fighting low voltage limiting
; Applied overall spoolup control to ensure soft spoolup in any mode
; Added a delay of 3 seconds from initiation of main motor stop until new startup is allowed
; Reduced beep power to reduce power consumption for very strong motors/ESCs
; - Rev3.4: Fixed bug that prevented full power in governor arm and setup modes
; Increased NFETON_DELAY for XP_7A and XP_12A to allow for more powerful fets
; Increased initial spoolup power, and linked to startup power
; - Rev4.0: Fixed bug that made tail tx program beeps very weak
; Added thermal protection feature
; Governor P and I gain ranges are extended up to 8.0x gain
; Startup sequence is aborted upon zero throttle
; Avoided voltage compensation function induced latency for tail when voltage compensation is not enabled
; Improved input signal frequency detection robustness
; - Rev4.1: Increased thermal protection temperature limits
; - Rev5.0: Added multi(copter) operating mode. TAIL define changed to MODE with three modes: MAIN, TAIL and MULTI
; Added programmable commutation timing
; Added a damped light mode that has less damping, but that can be used with all escs
; Added programmable damping force
; Added thermal protection for startup too
; Added wait beeps when waiting more than 30 sec for throttle above zero (after having been armed)
; Modified tail idling to provide option for very low speeds
; Changed PPM range to 1150-1830us
; Arming sequence is dropped for PPM input, unless it is governor arm mode
; Loss of input signal will immediately stop the motor for PPM input
; Bug corrected in Turnigy Plush 6A voltage measurement setup
; FET switching delays are set for original fets. Stronger/doubled/tripled etc fets may require faster pfet off switching
; Miscellaneous other changes
; - Rev6.0: Reverted comparator reading routine to rev5.0 equivalent, in order to avoid tail motor stops
; Added governor range programmability
; Implemented startup retry sequence with varying startup power for multi mode
; In damped light mode, damping is now applied to the active nfet phase for fully damped capable ESCs
; - Rev6.1: Added input signal qualification criteria for PPM, to avoid triggering on noise spikes (fix for plush hardware)
; Changed main and multi mode stop criteria. Will now be in run mode, even if RC pulse input is zero
; Fixed bug in commutation that caused rough running in damped light mode
; Miscellaneous other changes
; - Rev7.0 Added direct startup mode programmability
; Added throttle calibration. Min>=1000us and Max<=2000us. Difference must be >520us, otherwise max is shifted so that difference=520us
; Added programmable throttle change rate
; Added programmable beep strength, beacon strength and beacon delay
; Reduced power step to full power significantly
; Miscellaneous other changes
; - Rev8.0 Added a 2 second delay after power up, to wait for receiver initialization
; Added a programming option for disabling low voltage limit, and made it default for MULTI
; Added programable demag compensation, using the concept of SimonK
; Improved robustness against noisy input signal
; Refined direct startup
; Removed voltage compensation
; Miscellaneous other changes
; - Rev9.0 Increased programming range for startup power, and made it's default ESC dependent
; Made default startup method ESC dependent
; Even more smooth and gentle spoolup for MAIN, to suit larger helis
; Improved transition from stepped startup to run
; Refined direct startup
; - Rev9.1 Fixed bug that changed FW revision after throttle calibration or TX programming
; - Rev9.2 Altered timing of throttle calibration in order to work with MultiWii calibration firmware
; Reduced main spoolup time to around 5 seconds
; Changed default beacon delay to 3 minutes
; - Rev9.3 Fixed bug in Plush 60/80A temperature reading, that caused failure in operation above 4S
; Corrected temperature limit for HiModel cool 22/33/41A, RCTimer 6A, Skywalker 20/40A, Turnigy AE45A, Plush 40/60/80A. Limit was previously set too high
; - Rev9.4 Improved timing for increased maximum rpm limit
; - Rev10.0 Added closed loop mode for multi
; Added high/low BEC voltage option (for the ESCs where HW supports it)
; Added method of resetting all programmed parameter values to defaults by TX programming
; Added Turnigy K-force 40A and Turnigy K-force 120A HV ESCs
; Enabled fully damped mode for several ESCs
; Extended startup power range downwards to enable very smooth start for large heli main motors
; Extended damping force with a highest setting
; Corrected temperature limits for F310 chips (Plush 40A and AE 45A)
; Implemented temperature reading average in order to avoid problems with ADC noise on Skywalkers
; Increased switching delays for XP 7A fast, in order to avoid cross conduction of N and P fets
; Miscellaneous other changes
; - Rev10.1 Relaxed RC signal jitter requirement during frequency measurement
; Corrected bug that prevented using governor low
; Enabled vdd monitor always, in order to reduce likelihood of accidental overwriting of adjustments
; Fixed bug that caused stop for PPM input above 2048us, and moved upper accepted limit to 2160us
; - Rev10.2 Corrected temperature limit for AE20-30/XP7-25, where limit was too high
; Corrected temperature limit for 120HV, where limit was too low
; Fixed bug that caused AE20/25/30A not to run in reverse
;
;
;**** **** **** **** ****
; Up to 8K Bytes of In-System Self-Programmable Flash
; 768 Bytes Internal SRAM
;
;**** **** **** **** ****
; Master clock is internal 24MHz oscillator
; Timer 0 (167/500ns counts) always counts up and is used for
; - PWM generation
; Timer 1 (167/500ns counts) always counts up and is not used
; - Time from pwm on/off event
; Timer 2 (500ns counts) always counts up and is used for
; - RC pulse timeout/skip counts and commutation times
; Timer 3 (500ns counts) always counts up and is used for
; - Commutation timeouts
; PCA0 (500ns counts) always counts up and is used for
; - RC pulse measurement
;
;**** **** **** **** ****
; Interrupt handling
; The F330/2 does not disable interrupts when entering an interrupt routine.
; Also some interrupt flags need to be cleared by software
; The code disables interrupts in interrupt routines, in order to avoid nested interrupts
; - Interrupts are disabled during beeps, to avoid audible interference from interrupts
; - RC pulse interrupts are periodically disabled in order to reduce interference with pwm interrupts.
;
;**** **** **** **** ****
; Motor control:
; - Brushless motor control with 6 states for each electrical 360 degrees
; - An advance timing of 0deg has zero cross 30deg after one commutation and 30deg before the next
; - Timing advance in this implementation is set to 15deg nominally
; - "Damped" commutation schemes are available, where more than one pfet is on when pwm is off. This will absorb energy from bemf and make step settling more damped.
; Motor sequence starting from zero crossing:
; - Timer wait: Wt_Comm 15deg ; Time to wait from zero cross to actual commutation
; - Timer wait: Wt_Advance 15deg ; Time to wait for timing advance. Nominal commutation point is after this
; - Timer wait: Wt_Zc_Scan 7.5deg ; Time to wait before looking for zero cross
; - Scan for zero cross 22.5deg , Nominal, with some motor variations
;
; Motor startup in stepper mode:
; Initial motor rotations are done with the motor controlled as a stepper motor.
; In this stepper motor mode comparator information is not used.
; Settle phase is the first, where there are a few commutations with increasing step length, in order to settle the motor in a predefined position.
; Stepper phase comes next, where there is a step length decrease sequence.
; Direct startup is the last phase, for synchronization before normal bemf commutation run begins.
; Motor startup in direct mode:
; Direct startup is the only phase, before normal bemf commutation run begins.
;
;**** **** **** **** ****
; List of enumerated supported ESCs and modes (main, tail or multi)
XP_3A_Main EQU 1
XP_3A_Tail EQU 2
XP_3A_Multi EQU 3
XP_7A_Main EQU 4
XP_7A_Tail EQU 5
XP_7A_Multi EQU 6
XP_7A_Fast_Main EQU 7
XP_7A_Fast_Tail EQU 8
XP_7A_Fast_Multi EQU 9
XP_12A_Main EQU 10
XP_12A_Tail EQU 11
XP_12A_Multi EQU 12
XP_18A_Main EQU 13
XP_18A_Tail EQU 14
XP_18A_Multi EQU 15
XP_25A_Main EQU 16
XP_25A_Tail EQU 17
XP_25A_Multi EQU 18
DP_3A_Main EQU 19
DP_3A_Tail EQU 20
DP_3A_Multi EQU 21
Supermicro_3p5A_Main EQU 22
Supermicro_3p5A_Tail EQU 23
Supermicro_3p5A_Multi EQU 24
Turnigy_Plush_6A_Main EQU 25
Turnigy_Plush_6A_Tail EQU 26
Turnigy_Plush_6A_Multi EQU 27
Turnigy_Plush_10A_Main EQU 28
Turnigy_Plush_10A_Tail EQU 29
Turnigy_Plush_10A_Multi EQU 30
Turnigy_Plush_12A_Main EQU 31
Turnigy_Plush_12A_Tail EQU 32
Turnigy_Plush_12A_Multi EQU 33
Turnigy_Plush_18A_Main EQU 34
Turnigy_Plush_18A_Tail EQU 35
Turnigy_Plush_18A_Multi EQU 36
Turnigy_Plush_25A_Main EQU 37
Turnigy_Plush_25A_Tail EQU 38
Turnigy_Plush_25A_Multi EQU 39
Turnigy_Plush_30A_Main EQU 40
Turnigy_Plush_30A_Tail EQU 41
Turnigy_Plush_30A_Multi EQU 42
Turnigy_Plush_40A_Main EQU 43
Turnigy_Plush_40A_Tail EQU 44
Turnigy_Plush_40A_Multi EQU 45
Turnigy_Plush_60A_Main EQU 46
Turnigy_Plush_60A_Tail EQU 47
Turnigy_Plush_60A_Multi EQU 48
Turnigy_Plush_80A_Main EQU 49
Turnigy_Plush_80A_Tail EQU 50
Turnigy_Plush_80A_Multi EQU 51
Turnigy_AE_20A_Main EQU 52
Turnigy_AE_20A_Tail EQU 53
Turnigy_AE_20A_Multi EQU 54
Turnigy_AE_25A_Main EQU 55
Turnigy_AE_25A_Tail EQU 56
Turnigy_AE_25A_Multi EQU 57
Turnigy_AE_30A_Main EQU 58
Turnigy_AE_30A_Tail EQU 59
Turnigy_AE_30A_Multi EQU 60
Turnigy_AE_45A_Main EQU 61
Turnigy_AE_45A_Tail EQU 62
Turnigy_AE_45A_Multi EQU 63
Turnigy_KForce_40A_Main EQU 64
Turnigy_KForce_40A_Tail EQU 65
Turnigy_KForce_40A_Multi EQU 66
Turnigy_KForce_120A_HV_Main EQU 67
Turnigy_KForce_120A_HV_Tail EQU 68
Turnigy_KForce_120A_HV_Multi EQU 69
Skywalker_20A_Main EQU 70
Skywalker_20A_Tail EQU 71
Skywalker_20A_Multi EQU 72
Skywalker_40A_Main EQU 73
Skywalker_40A_Tail EQU 74
Skywalker_40A_Multi EQU 75
HiModel_Cool_22A_Main EQU 76
HiModel_Cool_22A_Tail EQU 77
HiModel_Cool_22A_Multi EQU 78
HiModel_Cool_33A_Main EQU 79
HiModel_Cool_33A_Tail EQU 80
HiModel_Cool_33A_Multi EQU 81
HiModel_Cool_41A_Main EQU 82
HiModel_Cool_41A_Tail EQU 83
HiModel_Cool_41A_Multi EQU 84
RCTimer_6A_Main EQU 85
RCTimer_6A_Tail EQU 86
RCTimer_6A_Multi EQU 87
Align_RCE_BL15X_Main EQU 88
Align_RCE_BL15X_Tail EQU 89
Align_RCE_BL15X_Multi EQU 90
Align_RCE_BL35X_Main EQU 91
Align_RCE_BL35X_Tail EQU 92
Align_RCE_BL35X_Multi EQU 93
Align_RCE_BL35P_Main EQU 94
Align_RCE_BL35P_Tail EQU 95
Align_RCE_BL35P_Multi EQU 96
H_King_10A_Main EQU 97
H_King_10A_Tail EQU 98
H_King_10A_Multi EQU 99
;**** **** **** **** ****
; Select the ESC and mode to use (or unselect all for use with external batch compile file)
;BESC EQU XP_3A_Main
;BESC EQU XP_3A_Tail
;BESC EQU XP_3A_Multi
;BESC EQU XP_7A_Main
;BESC EQU XP_7A_Tail
;BESC EQU XP_7A_Multi
;BESC EQU XP_7A_Fast_Main
;BESC EQU XP_7A_Fast_Tail
;BESC EQU XP_7A_Fast_Multi
;BESC EQU XP_12A_Main
;BESC EQU XP_12A_Tail
;BESC EQU XP_12A_Multi
;BESC EQU XP_18A_Main
;BESC EQU XP_18A_Tail
BESC EQU XP_18A_Multi
;BESC EQU XP_25A_Main
;BESC EQU XP_25A_Tail
;BESC EQU XP_25A_Multi
;BESC EQU DP_3A_Main
;BESC EQU DP_3A_Tail
;BESC EQU DP_3A_Multi
;BESC EQU Supermicro_3p5A_Main
;BESC EQU Supermicro_3p5A_Tail
;BESC EQU Supermicro_3p5A_Multi
;BESC EQU Turnigy_Plush_6A_Main
;BESC EQU Turnigy_Plush_6A_Tail
;BESC EQU Turnigy_Plush_6A_Multi
;BESC EQU Turnigy_Plush_10A_Main
;BESC EQU Turnigy_Plush_10A_Tail
;BESC EQU Turnigy_Plush_10A_Multi
;BESC EQU Turnigy_Plush_12A_Main
;BESC EQU Turnigy_Plush_12A_Tail
;BESC EQU Turnigy_Plush_12A_Multi
;BESC EQU Turnigy_Plush_18A_Main
;BESC EQU Turnigy_Plush_18A_Tail
;BESC EQU Turnigy_Plush_18A_Multi
;BESC EQU Turnigy_Plush_25A_Main
;BESC EQU Turnigy_Plush_25A_Tail
;BESC EQU Turnigy_Plush_25A_Multi
;BESC EQU Turnigy_Plush_30A_Main
;BESC EQU Turnigy_Plush_30A_Tail
;BESC EQU Turnigy_Plush_30A_Multi
;BESC EQU Turnigy_Plush_40A_Main
;BESC EQU Turnigy_Plush_40A_Tail
;BESC EQU Turnigy_Plush_40A_Multi
;BESC EQU Turnigy_Plush_60A_Main
;BESC EQU Turnigy_Plush_60A_Tail
;BESC EQU Turnigy_Plush_60A_Multi
;BESC EQU Turnigy_Plush_80A_Main
;BESC EQU Turnigy_Plush_80A_Tail
;BESC EQU Turnigy_Plush_80A_Multi
;BESC EQU Turnigy_AE_20A_Main
;BESC EQU Turnigy_AE_20A_Tail
;BESC EQU Turnigy_AE_20A_Multi
;BESC EQU Turnigy_AE_25A_Main
;BESC EQU Turnigy_AE_25A_Tail
;BESC EQU Turnigy_AE_25A_Multi
;BESC EQU Turnigy_AE_30A_Main
;BESC EQU Turnigy_AE_30A_Tail
;BESC EQU Turnigy_AE_30A_Multi
;BESC EQU Turnigy_AE_45A_Main
;BESC EQU Turnigy_AE_45A_Tail
;BESC EQU Turnigy_AE_45A_Multi
;BESC EQU Turnigy_KForce_40A_Main
;BESC EQU Turnigy_KForce_40A_Tail
;BESC EQU Turnigy_KForce_40A_Multi
;BESC EQU Turnigy_KForce_120A_HV_Main
;BESC EQU Turnigy_KForce_120A_HV_Tail
;BESC EQU Turnigy_KForce_120A_HV_Multi
;BESC EQU Skywalker_20A_Main
;BESC EQU Skywalker_20A_Tail
;BESC EQU Skywalker_20A_Multi
;BESC EQU Skywalker_40A_Main
;BESC EQU Skywalker_40A_Tail
;BESC EQU Skywalker_40A_Multi
;BESC EQU HiModel_Cool_22A_Main
;BESC EQU HiModel_Cool_22A_Tail
;BESC EQU HiModel_Cool_22A_Multi
;BESC EQU HiModel_Cool_33A_Main
;BESC EQU HiModel_Cool_33A_Tail
;BESC EQU HiModel_Cool_33A_Multi
;BESC EQU HiModel_Cool_41A_Main
;BESC EQU HiModel_Cool_41A_Tail
;BESC EQU HiModel_Cool_41A_Multi
;BESC EQU RCTimer_6A_Main
;BESC EQU RCTimer_6A_Tail
;BESC EQU RCTimer_6A_Multi
;BESC EQU Align_RCE_BL15X_Main
;BESC EQU Align_RCE_BL15X_Tail
;BESC EQU Align_RCE_BL15X_Multi
;BESC EQU Align_RCE_BL35X_Main
;BESC EQU Align_RCE_BL35X_Tail
;BESC EQU Align_RCE_BL35X_Multi
;BESC EQU Align_RCE_BL35P_Main
;BESC EQU Align_RCE_BL35P_Tail
;BESC EQU Align_RCE_BL35P_Multi
;BESC EQU H_King_10A_Main
;BESC EQU H_King_10A_Tail
;BESC EQU H_King_10A_Multi
;**** **** **** **** ****
; ESC selection statements
IF BESC == XP_3A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (XP_3A.inc) ; Select XP 3A pinout
ENDIF
IF BESC == XP_3A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (XP_3A.inc) ; Select XP 3A pinout
ENDIF
IF BESC == XP_3A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (XP_3A.inc) ; Select XP 3A pinout
ENDIF
IF BESC == XP_7A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (XP_7A.inc) ; Select XP 7A pinout
ENDIF
IF BESC == XP_7A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (XP_7A.inc) ; Select XP 7A pinout
ENDIF
IF BESC == XP_7A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (XP_7A.inc) ; Select XP 7A pinout
ENDIF
IF BESC == XP_7A_Fast_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (XP_7A_Fast.inc) ; Select XP 7A Fast pinout
ENDIF
IF BESC == XP_7A_Fast_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (XP_7A_Fast.inc) ; Select XP 7A Fast pinout
ENDIF
IF BESC == XP_7A_Fast_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (XP_7A_Fast.inc) ; Select XP 7A Fast pinout
ENDIF
IF BESC == XP_12A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (XP_12A.inc) ; Select XP 12A pinout
ENDIF
IF BESC == XP_12A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (XP_12A.inc) ; Select XP 12A pinout
ENDIF
IF BESC == XP_12A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (XP_12A.inc) ; Select XP 12A pinout
ENDIF
IF BESC == XP_18A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (XP_18A.inc) ; Select XP 18A pinout
ENDIF
IF BESC == XP_18A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (XP_18A.inc) ; Select XP 18A pinout
ENDIF
IF BESC == XP_18A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (XP_18A.inc) ; Select XP 18A pinout
ENDIF
IF BESC == XP_25A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (XP_25A.inc) ; Select XP 25A pinout
ENDIF
IF BESC == XP_25A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (XP_25A.inc) ; Select XP 25A pinout
ENDIF
IF BESC == XP_25A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (XP_25A.inc) ; Select XP 25A pinout
ENDIF
IF BESC == DP_3A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (DP_3A.inc) ; Select DP 3A pinout
ENDIF
IF BESC == DP_3A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (DP_3A.inc) ; Select DP 3A pinout
ENDIF
IF BESC == DP_3A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (DP_3A.inc) ; Select DP 3A pinout
ENDIF
IF BESC == Supermicro_3p5A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Supermicro_3p5A.inc) ; Select Supermicro 3.5A pinout
ENDIF
IF BESC == Supermicro_3p5A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Supermicro_3p5A.inc) ; Select Supermicro 3.5A pinout
ENDIF
IF BESC == Supermicro_3p5A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Supermicro_3p5A.inc) ; Select Supermicro 3.5A pinout
ENDIF
IF BESC == Turnigy_Plush_6A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Turnigy_Plush_6A.inc) ; Select Turnigy Plush 6A pinout
ENDIF
IF BESC == Turnigy_Plush_6A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Turnigy_Plush_6A.inc) ; Select Turnigy Plush 6A pinout
ENDIF
IF BESC == Turnigy_Plush_6A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Turnigy_Plush_6A.inc) ; Select Turnigy Plush 6A pinout
ENDIF
IF BESC == Turnigy_Plush_10A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Turnigy_Plush_10A.inc) ; Select Turnigy Plush 10A pinout
ENDIF
IF BESC == Turnigy_Plush_10A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Turnigy_Plush_10A.inc) ; Select Turnigy Plush 10A pinout
ENDIF
IF BESC == Turnigy_Plush_10A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Turnigy_Plush_10A.inc) ; Select Turnigy Plush 10A pinout
ENDIF
IF BESC == Turnigy_Plush_12A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Turnigy_Plush_12A.inc) ; Select Turnigy Plush 12A pinout
ENDIF
IF BESC == Turnigy_Plush_12A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Turnigy_Plush_12A.inc) ; Select Turnigy Plush 12A pinout
ENDIF
IF BESC == Turnigy_Plush_12A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Turnigy_Plush_12A.inc) ; Select Turnigy Plush 12A pinout
ENDIF
IF BESC == Turnigy_Plush_18A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Turnigy_Plush_18A.inc) ; Select Turnigy Plush 18A pinout
ENDIF
IF BESC == Turnigy_Plush_18A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Turnigy_Plush_18A.inc) ; Select Turnigy Plush 18A pinout
ENDIF
IF BESC == Turnigy_Plush_18A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Turnigy_Plush_18A.inc) ; Select Turnigy Plush 18A pinout
ENDIF
IF BESC == Turnigy_Plush_25A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Turnigy_Plush_25A.inc) ; Select Turnigy Plush 25A pinout
ENDIF
IF BESC == Turnigy_Plush_25A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Turnigy_Plush_25A.inc) ; Select Turnigy Plush 25A pinout
ENDIF
IF BESC == Turnigy_Plush_25A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Turnigy_Plush_25A.inc) ; Select Turnigy Plush 25A pinout
ENDIF
IF BESC == Turnigy_Plush_30A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Turnigy_Plush_30A.inc) ; Select Turnigy Plush 30A pinout
ENDIF
IF BESC == Turnigy_Plush_30A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Turnigy_Plush_30A.inc) ; Select Turnigy Plush 30A pinout
ENDIF
IF BESC == Turnigy_Plush_30A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Turnigy_Plush_30A.inc) ; Select Turnigy Plush 30A pinout
ENDIF
IF BESC == Turnigy_Plush_40A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Turnigy_Plush_40A.inc) ; Select Turnigy Plush 40A pinout
ENDIF
IF BESC == Turnigy_Plush_40A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Turnigy_Plush_40A.inc) ; Select Turnigy Plush 40A pinout
ENDIF
IF BESC == Turnigy_Plush_40A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Turnigy_Plush_40A.inc) ; Select Turnigy Plush 40A pinout
ENDIF
IF BESC == Turnigy_Plush_60A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Turnigy_Plush_60A.inc) ; Select Turnigy Plush 60A pinout
ENDIF
IF BESC == Turnigy_Plush_60A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Turnigy_Plush_60A.inc) ; Select Turnigy Plush 60A pinout
ENDIF
IF BESC == Turnigy_Plush_60A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Turnigy_Plush_60A.inc) ; Select Turnigy Plush 60A pinout
ENDIF
IF BESC == Turnigy_Plush_80A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Turnigy_Plush_80A.inc) ; Select Turnigy Plush 80A pinout
ENDIF
IF BESC == Turnigy_Plush_80A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Turnigy_Plush_80A.inc) ; Select Turnigy Plush 80A pinout
ENDIF
IF BESC == Turnigy_Plush_80A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Turnigy_Plush_80A.inc) ; Select Turnigy Plush 80A pinout
ENDIF
IF BESC == Turnigy_AE_20A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Turnigy_AE_20A.inc) ; Select Turnigy AE-20A pinout
ENDIF
IF BESC == Turnigy_AE_20A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Turnigy_AE_20A.inc) ; Select Turnigy AE-20A pinout
ENDIF
IF BESC == Turnigy_AE_20A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Turnigy_AE_20A.inc) ; Select Turnigy AE-20A pinout
ENDIF
IF BESC == Turnigy_AE_25A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Turnigy_AE_25A.inc) ; Select Turnigy AE-25A pinout
ENDIF
IF BESC == Turnigy_AE_25A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Turnigy_AE_25A.inc) ; Select Turnigy AE-25A pinout
ENDIF
IF BESC == Turnigy_AE_25A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Turnigy_AE_25A.inc) ; Select Turnigy AE-25A pinout
ENDIF
IF BESC == Turnigy_AE_30A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Turnigy_AE_30A.inc) ; Select Turnigy AE-30A pinout
ENDIF
IF BESC == Turnigy_AE_30A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Turnigy_AE_30A.inc) ; Select Turnigy AE-30A pinout
ENDIF
IF BESC == Turnigy_AE_30A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Turnigy_AE_30A.inc) ; Select Turnigy AE-30A pinout
ENDIF
IF BESC == Turnigy_AE_45A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Turnigy_AE_45A.inc) ; Select Turnigy AE-45A pinout
ENDIF
IF BESC == Turnigy_AE_45A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Turnigy_AE_45A.inc) ; Select Turnigy AE-45A pinout
ENDIF
IF BESC == Turnigy_AE_45A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Turnigy_AE_45A.inc) ; Select Turnigy AE-45A pinout
ENDIF
IF BESC == Turnigy_KForce_40A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Turnigy_KForce_40A.inc) ; Select Turnigy KForce 40A pinout
ENDIF
IF BESC == Turnigy_KForce_40A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Turnigy_KForce_40A.inc) ; Select Turnigy KForce 40A pinout
ENDIF
IF BESC == Turnigy_KForce_40A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Turnigy_KForce_40A.inc) ; Select Turnigy KForce 40A pinout
ENDIF
IF BESC == Turnigy_KForce_120A_HV_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Turnigy_KForce_120A_HV.inc) ; Select Turnigy KForce 120A HV pinout
ENDIF
IF BESC == Turnigy_KForce_120A_HV_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Turnigy_KForce_120A_HV.inc) ; Select Turnigy KForce 120A HV pinout
ENDIF
IF BESC == Turnigy_KForce_120A_HV_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Turnigy_KForce_120A_HV.inc) ; Select Turnigy KForce 120A HV pinout
ENDIF
IF BESC == Skywalker_20A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Skywalker_20A.inc) ; Select Skywalker 20A pinout
ENDIF
IF BESC == Skywalker_20A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Skywalker_20A.inc) ; Select Skywalker 20A pinout
ENDIF
IF BESC == Skywalker_20A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Skywalker_20A.inc) ; Select Skywalker 20A pinout
ENDIF
IF BESC == Skywalker_40A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Skywalker_40A.inc) ; Select Skywalker 40A pinout
ENDIF
IF BESC == Skywalker_40A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Skywalker_40A.inc) ; Select Skywalker 40A pinout
ENDIF
IF BESC == Skywalker_40A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Skywalker_40A.inc) ; Select Skywalker 40A pinout
ENDIF
IF BESC == HiModel_Cool_22A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (HiModel_Cool_22A.inc) ; Select HiModel Cool 22A pinout
ENDIF
IF BESC == HiModel_Cool_22A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (HiModel_Cool_22A.inc) ; Select HiModel Cool 22A pinout
ENDIF
IF BESC == HiModel_Cool_22A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (HiModel_Cool_22A.inc) ; Select HiModel Cool 22A pinout
ENDIF
IF BESC == HiModel_Cool_33A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (HiModel_Cool_33A.inc) ; Select HiModel Cool 33A pinout
ENDIF
IF BESC == HiModel_Cool_33A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (HiModel_Cool_33A.inc) ; Select HiModel Cool 33A pinout
ENDIF
IF BESC == HiModel_Cool_33A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (HiModel_Cool_33A.inc) ; Select HiModel Cool 33A pinout
ENDIF
IF BESC == HiModel_Cool_41A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (HiModel_Cool_41A.inc) ; Select HiModel Cool 41A pinout
ENDIF
IF BESC == HiModel_Cool_41A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (HiModel_Cool_41A.inc) ; Select HiModel Cool 41A pinout
ENDIF
IF BESC == HiModel_Cool_41A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (HiModel_Cool_41A.inc) ; Select HiModel Cool 41A pinout
ENDIF
IF BESC == RCTimer_6A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (RCTimer_6A.inc) ; Select RC Timer 6A pinout
ENDIF
IF BESC == RCTimer_6A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (RCTimer_6A.inc) ; Select RC Timer 6A pinout
ENDIF
IF BESC == RCTimer_6A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (RCTimer_6A.inc) ; Select RC Timer 6A pinout
ENDIF
IF BESC == Align_RCE_BL15X_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Align_RCE_BL15X.inc) ; Select Align RCE-BL15X pinout
ENDIF
IF BESC == Align_RCE_BL15X_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Align_RCE_BL15X.inc) ; Select Align RCE-BL15X pinout
ENDIF
IF BESC == Align_RCE_BL15X_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Align_RCE_BL15X.inc) ; Select Align RCE-BL15X pinout
ENDIF
IF BESC == Align_RCE_BL35X_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Align_RCE_BL35X.inc) ; Select Align RCE-BL35X pinout
ENDIF
IF BESC == Align_RCE_BL35X_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Align_RCE_BL35X.inc) ; Select Align RCE-BL35X pinout
ENDIF
IF BESC == Align_RCE_BL35X_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Align_RCE_BL35X.inc) ; Select Align RCE-BL35X pinout
ENDIF
IF BESC == Align_RCE_BL35P_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (Align_RCE_BL35P.inc) ; Select Align RCE-BL35P pinout
ENDIF
IF BESC == Align_RCE_BL35P_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (Align_RCE_BL35P.inc) ; Select Align RCE-BL35P pinout
ENDIF
IF BESC == Align_RCE_BL35P_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (Align_RCE_BL35P.inc) ; Select Align RCE-BL35P pinout
ENDIF
IF BESC == H_King_10A_Main
MODE EQU 0 ; Choose mode. Set to 0 for main motor
$include (H_King_10A.inc) ; Select H-King 10A pinout
ENDIF
IF BESC == H_King_10A_Tail
MODE EQU 1 ; Choose mode. Set to 1 for tail motor
$include (H_King_10A.inc) ; Select H-King 10A pinout
ENDIF
IF BESC == H_King_10A_Multi
MODE EQU 2 ; Choose mode. Set to 2 for multirotor
$include (H_King_10A.inc) ; Select H-King 10A pinout
ENDIF
;**** **** **** **** ****
; TX programming defaults
;
; Parameter dependencies:
; - Governor P gain, I gain and Range is only used if one of the three governor modes is selected
; - Governor setup target is only used if Setup governor mode is selected (or closed loop mode is on for multi)
; - Startup rpm and startup accel is only used if stepped startup method is selected
; - Damping force is only used if DampedLight or Damped is selected
;
; Main
DEFAULT_PGM_MAIN_P_GAIN EQU 9 ; 1=0.13 2=0.17 3=0.25 4=0.38 5=0.50 6=0.75 7=1.00 8=1.5 9=2.0 10=3.0 11=4.0 12=6.0 13=8.0
DEFAULT_PGM_MAIN_I_GAIN EQU 9 ; 1=0.13 2=0.17 3=0.25 4=0.38 5=0.50 6=0.75 7=1.00 8=1.5 9=2.0 10=3.0 11=4.0 12=6.0 13=8.0
DEFAULT_PGM_MAIN_GOVERNOR_MODE EQU 1 ; 1=Tx 2=Arm 3=Setup 4=Off
DEFAULT_PGM_MAIN_GOVERNOR_RANGE EQU 1 ; 1=High 2=Low
DEFAULT_PGM_MAIN_LOW_VOLTAGE_LIM EQU 4 ; 1=Off 2=3.0V/c 3=3.1V/c 4=3.2V/c 5=3.3V/c 6=3.4V/c
DEFAULT_PGM_MAIN_STARTUP_RPM EQU 3 ; 1=0.67 2=0.8 3=1.00 4=1.25 5=1.5
DEFAULT_PGM_MAIN_STARTUP_ACCEL EQU 1 ; 1=0.4 2=0.7 3=1.0 4=1.5 5=2.3
DEFAULT_PGM_MAIN_COMM_TIMING EQU 3 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High
DEFAULT_PGM_MAIN_THROTTLE_RATE EQU 13 ; 1=2 2=3 3=4 4=6 5=8 6=12 7=16 8=24 9=32 10=48 11=64 12=128 13=255
DEFAULT_PGM_MAIN_DAMPING_FORCE EQU 1 ; 1=VeryLow 2=Low 3=MediumLow 4=MediumHigh 5=High 6=Highest
DEFAULT_PGM_MAIN_PWM_FREQ EQU 2 ; 1=High 2=Low 3=DampedLight
DEFAULT_PGM_MAIN_DEMAG_COMP EQU 1 ; 1=Disabled 2=15/0 3=15/7.5 4=7.5/7.5 5=7.5/15 (degrees blind advance / power off)
DEFAULT_PGM_MAIN_DIRECTION_REV EQU 1 ; 1=Normal 2=Reversed
DEFAULT_PGM_MAIN_RCP_PWM_POL EQU 1 ; 1=Positive 2=Negative
DEFAULT_PGM_MAIN_GOV_SETUP_TARGET EQU 180 ; Target for governor in setup mode. Corresponds to 70% throttle
DEFAULT_PGM_MAIN_REARM_START EQU 0 ; 1=Enabled 0=Disabled
DEFAULT_PGM_MAIN_BEEP_STRENGTH EQU 80 ; Beep strength
DEFAULT_PGM_MAIN_BEACON_STRENGTH EQU 100 ; Beacon strength
DEFAULT_PGM_MAIN_BEACON_DELAY EQU 2 ; 1=30s 2=1m 3=2m 4=3m 5=Infinite
; Tail
DEFAULT_PGM_TAIL_GAIN EQU 3 ; 1=0.75 2=0.88 3=1.00 4=1.12 5=1.25
DEFAULT_PGM_TAIL_IDLE_SPEED EQU 4 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High
DEFAULT_PGM_TAIL_STARTUP_RPM EQU 3 ; 1=0.67 2=0.8 3=1.00 4=1.25 5=1.5
DEFAULT_PGM_TAIL_STARTUP_ACCEL EQU 5 ; 1=0.4 2=0.7 3=1.0 4=1.5 5=2.3
DEFAULT_PGM_TAIL_COMM_TIMING EQU 3 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High
DEFAULT_PGM_TAIL_THROTTLE_RATE EQU 13 ; 1=2 2=3 3=4 4=6 5=8 6=12 7=16 8=24 9=32 10=48 11=64 12=128 13=255
DEFAULT_PGM_TAIL_DAMPING_FORCE EQU 5 ; 1=VeryLow 2=Low 3=MediumLow 4=MediumHigh 5=High 6=Highest
IF DAMPED_MODE_ENABLE == 1
DEFAULT_PGM_TAIL_PWM_FREQ EQU 1 ; 1=High 2=Low 3=DampedLight 4=Damped
ELSE
DEFAULT_PGM_TAIL_PWM_FREQ EQU 1 ; 1=High 2=Low 3=DampedLight
ENDIF
DEFAULT_PGM_TAIL_DEMAG_COMP EQU 1 ; 1=Disabled 2=15/0 3=15/7.5 4=7.5/7.5 5=7.5/15 (degrees blind advance / power off)
DEFAULT_PGM_TAIL_DIRECTION_REV EQU 1 ; 1=Normal 2=Reversed
DEFAULT_PGM_TAIL_RCP_PWM_POL EQU 1 ; 1=Positive 2=Negative
DEFAULT_PGM_TAIL_BEEP_STRENGTH EQU 250 ; Beep strength
DEFAULT_PGM_TAIL_BEACON_STRENGTH EQU 250 ; Beacon strength
DEFAULT_PGM_TAIL_BEACON_DELAY EQU 4 ; 1=30s 2=1m 3=2m 4=3m 5=Infinite
; Multi
DEFAULT_PGM_MULTI_FIRST_KEYWORD EQU 66h ;增加首个关键字 2013.8.27
DEFAULT_PGM_MULTI_P_GAIN EQU 9 ; 1=0.13 2=0.17 3=0.25 4=0.38 5=0.50 6=0.75 7=1.00 8=1.5 9=2.0 10=3.0 11=4.0 12=6.0 13=8.0
DEFAULT_PGM_MULTI_I_GAIN EQU 9 ; 1=0.13 2=0.17 3=0.25 4=0.38 5=0.50 6=0.75 7=1.00 8=1.5 9=2.0 10=3.0 11=4.0 12=6.0 13=8.0
DEFAULT_PGM_MULTI_GOVERNOR_MODE EQU 1 ; 1=Off 2=LoRange 3=MidRange 4=HiRange
DEFAULT_PGM_MULTI_GAIN EQU 3 ; 1=0.75 2=0.88 3=1.00 4=1.12 5=1.25
DEFAULT_PGM_MULTI_LOW_VOLTAGE_LIM EQU 2
;DEFAULT_PGM_MULTI_LOW_VOLTAGE_LIM EQU 1 ; 1=Off 2=3.0V/c 3=3.1V/c 4=3.2V/c 5=3.3V/c 6=3.4V/c
DEFAULT_PGM_MULTI_LOW_VOLTAGE_CTL EQU 1 ;增加低压保护控制方式默认值 1=功率逐渐降到31% 2=关闭输出
DEFAULT_PGM_MULTI_STARTUP_RPM EQU 1 ; 1=0.67 2=0.8 3=1.00 4=1.25 5=1.5
DEFAULT_PGM_MULTI_STARTUP_ACCEL EQU 5 ; 1=0.4 2=0.7 3=1.0 4=1.5 5=2.3
DEFAULT_PGM_MULTI_COMM_TIMING EQU 3 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High
DEFAULT_PGM_MULTI_THROTTLE_RATE EQU 13 ; 1=2 2=3 3=4 4=6 5=8 6=12 7=16 8=24 9=32 10=48 11=64 12=128 13=255
DEFAULT_PGM_MULTI_DAMPING_FORCE EQU 1 ; 1=VeryLow 2=Low 3=MediumLow 4=MediumHigh 5=High 6=Highest
IF DAMPED_MODE_ENABLE == 1
DEFAULT_PGM_MULTI_PWM_FREQ EQU 1 ; 1=Low 2=High
ELSE
DEFAULT_PGM_MULTI_PWM_FREQ EQU 1 ; 1=Low 2=High
ENDIF
DEFAULT_PGM_MULTI_DEMAG_COMP EQU 2 ; 1=Disabled 2=15/0 3=15/7.5 4=7.5/7.5 5=7.5/15 (degrees blind advance / power off)
DEFAULT_PGM_MULTI_DIRECTION_REV EQU 1 ; 1=Normal 2=Reversed
DEFAULT_PGM_MULTI_RCP_PWM_POL EQU 1 ; 1=Positive 2=Negative
;DEFAULT_PGM_MULTI_BEEP_STRENGTH EQU 40 ; Beep strength
;DEFAULT_PGM_MULTI_BEACON_STRENGTH EQU 80 ; Beacon strength 等待摇杆操作声强
;DEFAULT_PGM_MULTI_BEACON_DELAY EQU 4 ; 1=30s 2=1m 3=2m 4=3m 5=Infinite
DEFAULT_PGM_MULTI_BEEP_STRENGTH EQU 80 ; Beep strength 上电到一次信号拉到最低声强
DEFAULT_PGM_MULTI_BEACON_STRENGTH EQU 100 ; Beacon strength 等待摇杆操作声强
DEFAULT_PGM_MULTI_BEACON_DELAY EQU 2 ; 1=30s 2=1m 3=2m 4=3m 5=Infinite 等待摇杆操作时间
; Common
DEFAULT_PGM_ENABLE_TX_PROGRAM EQU 1 ; 1=Enabled 0=Disabled
DEFAULT_PGM_PPM_MIN_THROTTLE EQU 37 ; 4*37+1000=1148
DEFAULT_PGM_PPM_MAX_THROTTLE EQU 208 ; 4*208+1000=1832
DEFAULT_PGM_BEC_VOLTAGE_HIGH EQU 0 ; 0=Low 1= High
;**** **** **** **** ****
; Constant definitions for main
IF MODE == 0
GOV_SPOOLRATE EQU 1 ; Number of steps for governor requested pwm per 32ms
RCP_TIMEOUT_PPM EQU 10 ; Number of timer2H overflows (about 32ms) before considering rc pulse lost
RCP_TIMEOUT EQU 64 ; Number of timer2L overflows (about 128us) before considering rc pulse lost
RCP_SKIP_RATE EQU 32 ; Number of timer2L overflows (about 128us) before reenabling rc pulse detection
RCP_MIN EQU 0 ; This is minimum RC pulse length
RCP_MAX EQU 254 ; This is maximum RC pulse length
RCP_VALIDATE EQU 2 ; Require minimum this pulse length to validate RC pulse
RCP_STOP EQU 1 ; Stop motor at or below this pulse length
RCP_STOP_LIMIT EQU 3 ; Stop motor if this many timer2H overflows (~32ms) are below stop limit
PWM_SETTLE EQU 50 ; PWM used when in start settling phase (also max power during direct start)
PWM_STEPPER EQU 80 ; PWM used when in start stepper phase
COMM_TIME_RED EQU 8 ; Fixed reduction (in us) for commutation wait (to account for fixed delays)
COMM_TIME_MIN EQU 1 ; Minimum time (in us) for commutation wait
TEMP_CHECK_RATE EQU 8 ; Number of adc conversions for each check of temperature (the other conversions are used for voltage)
ENDIF
; Constant definitions for tail
IF MODE == 1
GOV_SPOOLRATE EQU 1 ; Number of steps for governor requested pwm per 32ms
RCP_TIMEOUT_PPM EQU 10 ; Number of timer2H overflows (about 32ms) before considering rc pulse lost
RCP_TIMEOUT EQU 24 ; Number of timer2L overflows (about 128us) before considering rc pulse lost
RCP_SKIP_RATE EQU 6 ; Number of timer2L overflows (about 128us) before reenabling rc pulse detection
RCP_MIN EQU 0 ; This is minimum RC pulse length
RCP_MAX EQU 255 ; This is maximum RC pulse length
RCP_VALIDATE EQU 2 ; Require minimum this pulse length to validate RC pulse
RCP_STOP EQU 1 ; Stop motor at or below this pulse length
RCP_STOP_LIMIT EQU 130 ; Stop motor if this many timer2H overflows (~32ms) are below stop limit
PWM_SETTLE EQU 50 ; PWM used when in start settling phase (also max power during direct start)
PWM_STEPPER EQU 120 ; PWM used when in start stepper phase
COMM_TIME_RED EQU 8 ; Fixed reduction (in us) for commutation wait (to account for fixed delays)
COMM_TIME_MIN EQU 1 ; Minimum time (in us) for commutation wait
TEMP_CHECK_RATE EQU 8 ; Number of adc conversions for each check of temperature (the other conversions are used for voltage)
ENDIF
; Constant definitions for multi
IF MODE == 2
GOV_SPOOLRATE EQU 1 ; Number of steps for governor requested pwm per 32ms
RCP_TIMEOUT_PPM EQU 64 ; Number of timer2H overflows (about 32ms) before considering rc pulse lost
RCP_TIMEOUT EQU 40 ; Number of timer2L overflows (about 128us) before considering rc pulse lost
RCP_SKIP_RATE EQU 6 ; Number of timer2L overflows (about 128us) before reenabling rc pulse detection
RCP_MIN EQU 0 ; This is minimum RC pulse length
RCP_MAX EQU 255 ; This is maximum RC pulse length
RCP_VALIDATE EQU 2 ; Require minimum this pulse length to validate RC pulse
RCP_STOP EQU 1 ; Stop motor at or below this pulse length
;//////RCP_STOP_LIMIT EQU 20 ; Stop motor if this many timer2H overflows (~32ms) are below stop limit
PWM_SETTLE EQU 50 ; PWM used when in start settling phase (also max power during direct start)
PWM_STEPPER EQU 120 ; PWM used when in start stepper phase
COMM_TIME_RED EQU 8 ; Fixed reduction (in us) for commutation wait (to account for fixed delays)
COMM_TIME_MIN EQU 1 ; Minimum time (in us) for commutation wait
TEMP_CHECK_RATE EQU 8 ; Number of adc conversions for each check of temperature (the other conversions are used for voltage)
ENDIF
;**** **** **** **** ****
; Temporary register definitions
Temp1 EQU R0
Temp2 EQU R1
Temp3 EQU R2
Temp4 EQU R3
Temp5 EQU R4
Temp6 EQU R5
Temp7 EQU R6
Temp8 EQU R7
;**** **** **** **** ****
; Register definitions
DSEG AT 20h ; Variables segment
Bit_Access: DS 1 ; Variable at bit accessible address (for non interrupt routines)
Bit_Access_Int: DS 1 ; Variable at bit accessible address (for interrupts)
Requested_Pwm: DS 1 ; Requested pwm (from RC pulse value)
Governor_Req_Pwm: DS 1 ; Governor requested pwm (sets governor target)
Current_Pwm: DS 1 ; Current pwm
Current_Pwm_Limited: DS 1 ; Current pwm that is limited (applied to the motor output)
Rcp_Prev_Edge_L: DS 1 ; RC pulse previous edge timer3 timestamp (lo byte)
Rcp_Prev_Edge_H: DS 1 ; RC pulse previous edge timer3 timestamp (hi byte)
Rcp_Timeout_Cnt: DS 1 ; RC pulse timeout counter (decrementing)
Rcp_Skip_Cnt: DS 1 ; RC pulse skip counter (decrementing)
Rcp_Edge_Cnt: DS 1 ; RC pulse edge counter
Rcp_Stop_Limit: DS 1 ;增加刹车速度
Flags0: DS 1 ; State flags. Reset upon init_start
T3_PENDING EQU 0 ; Timer3 pending flag
RCP_MEAS_PWM_FREQ EQU 1 ; Measure RC pulse pwm frequency
PWM_ON EQU 2 ; Set in on part of pwm cycle
DEMAG_DETECTED EQU 3 ; Set when excessive demag time is detected
DEMAG_CUT_POWER EQU 4 ; Set when demag compensation cuts power
; EQU 5
PROGRAM_FUNC_FLAG EQU 6
SUCCESS_BEEP_FLAG EQU 7
Flags1: DS 1 ; State flags. Reset upon init_start
MOTOR_SPINNING EQU 0 ; Set when in motor is spinning
SETTLE_PHASE EQU 1 ; Set when in motor start settling phase
STEPPER_PHASE EQU 2 ; Set when in motor start stepper motor phase
DIRECT_STARTUP_PHASE EQU 3 ; Set when in direct startup phase
INITIAL_RUN_PHASE EQU 4 ; Set when in initial run phase, before synchronized run is achieved
; EQU 5
; EQU 6
LOW_LIMIT_STOP EQU 7
Flags2: DS 1 ; State flags. NOT reset upon init_start
RCP_UPDATED EQU 0 ; New RC pulse length value available
RCP_EDGE_NO EQU 1 ; RC pulse edge no. 0=rising, 1=falling
PGM_PWMOFF_DAMPED EQU 2 ; Programmed pwm off damped mode. Set when fully damped or damped light mode is selected
PGM_PWMOFF_DAMPED_FULL EQU 3 ; Programmed pwm off fully damped mode. Set when all pfets shall be on in pwm_off period
PGM_PWMOFF_DAMPED_LIGHT EQU 4 ; Programmed pwm off damped light mode. Set when only 2 pfets shall be on in pwm_off period
PGM_PWM_HIGH_FREQ EQU 5 ; Progremmed pwm high frequency
CURR_PWMOFF_DAMPED EQU 6 ; Currently running pwm off cycle is damped
CURR_PWMOFF_COMP_ABLE EQU 7 ; Currently running pwm off cycle is usable for comparator
Flags3: DS 1 ; State flags. NOT reset upon init_start
RCP_PWM_FREQ_1KHZ EQU 0 ; RC pulse pwm frequency is 1kHz
RCP_PWM_FREQ_2KHZ EQU 1 ; RC pulse pwm frequency is 2kHz
RCP_PWM_FREQ_4KHZ EQU 2 ; RC pulse pwm frequency is 4kHz
RCP_PWM_FREQ_8KHZ EQU 3 ; RC pulse pwm frequency is 8kHz
PGM_DIR_REV EQU 4 ; Programmed direction. 0=normal, 1=reversed
PGM_RCP_PWM_POL EQU 5 ; Programmed RC pulse pwm polarity. 0=positive, 1=negative
FULL_THROTTLE_RANGE EQU 6 ; When set full throttle range is used (1000-2000us) and stored calibration values are ignored
ERRO_DATA EQU 7 ;增加编程卡数据错误标志 2013.8.27
;**** **** **** **** ****
; RAM definitions
DSEG AT 30h ; Ram data segment, direct addressing
Initial_Arm: DS 1 ; Variable that is set during the first arm sequence after power on
;Pca_First_Int: DS 1
Power_On_Wait_Cnt_L: DS 1 ; Power on wait counter (lo byte)
Power_On_Wait_Cnt_H: DS 1 ; Power on wait counter (hi byte)
Pgm_Pulse_Cnt: DS 1
;Stepper_Step_Beg_L: DS 1 ; Stepper phase step time at the beginning (lo byte)
;Stepper_Step_Beg_H: DS 1 ; Stepper phase step time at the beginning (hi byte)
;Stepper_Step_End_L: DS 1 ; Stepper phase step time at the end (lo byte)
;Stepper_Step_End_H: DS 1 ; Stepper phase step time at the end (hi byte)
Startup_Rot_Cnt: DS 1 ; Startup phase rotations counter
Direct_Startup_Ok_Cnt: DS 1 ; Direct startup phase ok comparator waits counter (incrementing)
Prev_Comm_L: DS 1 ; Previous commutation timer3 timestamp (lo byte)
Prev_Comm_H: DS 1 ; Previous commutation timer3 timestamp (hi byte)
Comm_Period4x_L: DS 1 ; Timer3 counts between the last 4 commutations (lo byte)
Comm_Period4x_H: DS 1 ; Timer3 counts between the last 4 commutations (hi byte)
Comm_Phase: DS 1 ; Current commutation phase
Comp_Wait_Reads: DS 1 ; Comparator wait comparator reads
Gov_Target_L: DS 1 ; Governor target (lo byte)
Gov_Target_H: DS 1 ; Governor target (hi byte)
Gov_Integral_L: DS 1 ; Governor integral error (lo byte)
Gov_Integral_H: DS 1 ; Governor integral error (hi byte)
Gov_Integral_X: DS 1 ; Governor integral error (ex byte)
Gov_Proportional_L: DS 1 ; Governor proportional error (lo byte)
Gov_Proportional_H: DS 1 ; Governor proportional error (hi byte)
Gov_Prop_Pwm: DS 1 ; Governor calculated new pwm based upon proportional error
Gov_Arm_Target: DS 1 ; Governor arm target value
Gov_Active: DS 1 ; Governor active (enabled when speed is above minimum)
Wt_Advance_L: DS 1 ; Timer3 counts for commutation advance timing (lo byte)
Wt_Advance_H: DS 1 ; Timer3 counts for commutation advance timing (hi byte)
Wt_Zc_Scan_L: DS 1 ; Timer3 counts from commutation to zero cross scan (lo byte)
Wt_Zc_Scan_H: DS 1 ; Timer3 counts from commutation to zero cross scan (hi byte)
Wt_Comm_L: DS 1 ; Timer3 counts from zero cross to commutation (lo byte)
Wt_Comm_H: DS 1 ; Timer3 counts from zero cross to commutation (hi byte)
;Wt_Stepper_Step_L: DS 1 ; Timer3 counts for stepper step (lo byte)
;Wt_Stepper_Step_H: DS 1 ; Timer3 counts for stepper step (hi byte)
Rcp_PrePrev_Edge_L: DS 1 ; RC pulse pre previous edge pca timestamp (lo byte)
Rcp_PrePrev_Edge_H: DS 1 ; RC pulse pre previous edge pca timestamp (hi byte)
Rcp_Edge_L: DS 1 ; RC pulse edge pca timestamp (lo byte)
Rcp_Edge_H: DS 1 ; RC pulse edge pca timestamp (hi byte)
Rcp_Prev_Period_L: DS 1 ; RC pulse previous period (lo byte)
Rcp_Prev_Period_H: DS 1 ; RC pulse previous period (hi byte)
Rcp_Period_Diff_Accepted: DS 1 ; RC pulse period difference acceptable
New_Rcp: DS 1 ; New RC pulse value in pca counts
Prev_Rcp_Pwm_Freq: DS 1 ; Previous RC pulse pwm frequency (used during pwm frequency measurement)
Curr_Rcp_Pwm_Freq: DS 1 ; Current RC pulse pwm frequency (used during pwm frequency measurement)
Rcp_Stop_Cnt: DS 1 ; Counter for RC pulses below stop value
Pwm_Limit: DS 1 ; Maximum allowed pwm
Pwm_Limit_Spoolup: DS 1 ; Maximum allowed pwm during spoolup of main
Pwm_Spoolup_Beg: DS 1 ; Pwm to begin main spoolup with
Pwm_Motor_Idle: DS 1 ; Motor idle speed pwm
Pwm_On_Cnt: DS 1 ; Pwm on event counter (used to increase pwm off time for low pwm)
Pwm_Off_Cnt: DS 1 ; Pwm off event counter (used to run some pwm cycles without damping)
Spoolup_Limit_Cnt: DS 1 ; Interrupt count for spoolup limit
Spoolup_Limit_Skip: DS 1 ; Interrupt skips for spoolup limit increment (0=no skips, 1=skip one etc)
Damping_Period: DS 1 ; Damping on/off period
Damping_On: DS 1 ; Damping on part of damping period
;Lipo_Adc_Reference_L: DS 1 ; Voltage reference adc value (lo byte)
;Lipo_Adc_Reference_H: DS 1 ; Voltage reference adc value (hi byte)
Lipo_Adc_Limit_L: DS 1 ; Low voltage limit adc value (lo byte)
Lipo_Adc_Limit_H: DS 1 ; Low voltage limit adc value (hi byte)
Adc_Conversion_Cnt: DS 1 ; Adc conversion counter
Lipo_Cell_Count: DS 1 ;增加电池节数累计变量 2013.5.29
Limit_Count: DS 1 ;增加逐渐递减计数变量 2013.7.5
Current_Average_Temp: DS 1 ; Current average temperature (lo byte ADC reading, assuming hi byte is 1)
Ppm_Throttle_Gain: DS 1 ; Gain to be applied to RCP value for PPM input
Beep_Strength: DS 1 ; Strength of beeps
Tx_Pgm_Func_No: DS 1 ; Function number when doing programming by tx
Tx_Pgm_Paraval_No: DS 1 ; Parameter value number when doing programming by tx
Tx_Pgm_Beep_No: DS 1 ; Beep number when doing programming by tx
Commu_Data_Buffer: DS 1 ;编程卡接收,发送数据暂存 2013.8.27
Commu_Sum: DS 1 ;增加编程卡校验和 2013.8.27
Min_Throttle: DS 1
; Indirect addressing data segment
ISEG AT 080h
Pgm_Fir_Key: DS 1 ;增加首个关键字 2013.8.27
Pgm_Gov_P_Gain: DS 1 ; Programmed governor P gain
Pgm_Gov_I_Gain: DS 1 ; Programmed governor I gain
Pgm_Gov_Mode: DS 1 ; Programmed governor mode
Pgm_Low_Voltage_Lim: DS 1 ; Programmed low voltage limit
Pgm_Low_Voltage_Ctl: DS 1 ;增加低压保护控制方式编程项 2013.7.5
Pgm_Motor_Gain: DS 1 ; Programmed motor gain
Pgm_Motor_Idle: DS 1 ; Programmed motor idle speed
Pgm_Startup_Pwr: DS 1 ; Programmed startup power
Pgm_Pwm_Freq: DS 1 ; Programmed pwm frequency
Pgm_Direction_Rev: DS 1 ; Programmed rotation direction
Pgm_Input_Pol: DS 1 ; Programmed input pwm polarity
Initialized_L_Dummy: DS 1 ; Place holder
Initialized_H_Dummy: DS 1 ; Place holder
Pgm_Enable_TX_Program: DS 1 ; Programmed enable/disable value for TX programming
Pgm_Main_Rearm_Start: DS 1 ; Programmed enable/disable re-arming main every start
Pgm_Gov_Setup_Target: DS 1 ; Programmed main governor setup target
Pgm_Startup_Rpm: DS 1 ; Programmed startup rpm
Pgm_Startup_Accel: DS 1 ; Programmed startup acceleration
Pgm_Volt_Comp_Dummy: DS 1 ; Place holder
Pgm_Comm_Timing: DS 1 ; Programmed commutation timing
Pgm_Damping_Force: DS 1 ; Programmed damping force
Pgm_Gov_Range: DS 1 ; Programmed governor range
;Pgm_Startup_Method: DS 1 ; Programmed startup method
Pgm_Ppm_Min_Throttle: DS 1 ; Programmed throttle minimum
Pgm_Ppm_Max_Throttle: DS 1 ; Programmed throttle maximum
Pgm_Beep_Strength: DS 1 ; Programmed beep strength
Pgm_Beacon_Strength: DS 1 ; Programmed beacon strength
Pgm_Beacon_Delay: DS 1 ; Programmed beacon delay
Pgm_Throttle_Rate: DS 1 ; Programmed throttle rate
Pgm_Demag_Comp: DS 1 ; Programmed demag compensation
Pgm_BEC_Voltage_High: DS 1 ; Programmed BEC voltage
Pgm_Gov_P_Gain_Decoded: DS 1 ; Programmed governor decoded P gain
Pgm_Gov_I_Gain_Decoded: DS 1 ; Programmed governor decoded I gain
Pgm_Throttle_Rate_Decoded: DS 1 ; Programmed throttle rate decoded
Pgm_Startup_Pwr_Decoded: DS 1 ; Programmed startup power decoded
Pgm_Demag_Comp_Wait_Decoded: DS 1 ; Programmed demag compensation wait decoded
Pgm_Demag_Comp_Power_Decoded: DS 1 ; Programmed demag compensation power cut decoded
; Indirect addressing data segment
ISEG AT 0D0h
Tag_Temporary_Storage: DS 48 ; Temporary storage for tags when updating "Eeprom"
;**** **** **** **** ****
CSEG AT 1A00h ; "Eeprom" segment
EEPROM_FW_MAIN_REVISION EQU 10 ; Main revision of the firmware
EEPROM_FW_SUB_REVISION EQU 2 ; Sub revision of the firmware
EEPROM_LAYOUT_REVISION EQU 16 ; Revision of the EEPROM layout
Eep_FW_Main_Revision: DB EEPROM_FW_MAIN_REVISION ; EEPROM firmware main revision number
Eep_FW_Sub_Revision: DB EEPROM_FW_SUB_REVISION ; EEPROM firmware sub revision number
Eep_Layout_Revision: DB EEPROM_LAYOUT_REVISION ; EEPROM layout revision number
IF MODE == 0
Eep_Pgm_Gov_P_Gain: DB DEFAULT_PGM_MAIN_P_GAIN ; EEPROM copy of programmed governor P gain
Eep_Pgm_Gov_I_Gain: DB DEFAULT_PGM_MAIN_I_GAIN ; EEPROM copy of programmed governor I gain
Eep_Pgm_Gov_Mode: DB DEFAULT_PGM_MAIN_GOVERNOR_MODE ; EEPROM copy of programmed governor mode
Eep_Pgm_Low_Voltage_Lim: DB DEFAULT_PGM_MAIN_LOW_VOLTAGE_LIM ; EEPROM copy of programmed low voltage limit
_Eep_Pgm_Motor_Gain: DB 0FFh
_Eep_Pgm_Motor_Idle: DB 0FFh
Eep_Pgm_Startup_Pwr: DB DEFAULT_PGM_MAIN_STARTUP_PWR ; EEPROM copy of programmed startup power
Eep_Pgm_Pwm_Freq: DB DEFAULT_PGM_MAIN_PWM_FREQ ; EEPROM copy of programmed pwm frequency
Eep_Pgm_Direction_Rev: DB DEFAULT_PGM_MAIN_DIRECTION_REV ; EEPROM copy of programmed rotation direction
Eep_Pgm_Input_Pol: DB DEFAULT_PGM_MAIN_RCP_PWM_POL ; EEPROM copy of programmed input polarity
Eep_Initialized_L: DB 0A5h ; EEPROM initialized signature low byte
Eep_Initialized_H: DB 05Ah ; EEPROM initialized signature high byte
Eep_Enable_TX_Program: DB DEFAULT_PGM_ENABLE_TX_PROGRAM ; EEPROM TX programming enable
Eep_Main_Rearm_Start: DB DEFAULT_PGM_MAIN_REARM_START ; EEPROM re-arming main enable
Eep_Pgm_Gov_Setup_Target: DB DEFAULT_PGM_MAIN_GOV_SETUP_TARGET ; EEPROM main governor setup target
Eep_Pgm_Startup_Rpm: DB DEFAULT_PGM_MAIN_STARTUP_RPM ; EEPROM copy of programmed startup rpm
Eep_Pgm_Startup_Accel: DB DEFAULT_PGM_MAIN_STARTUP_ACCEL ; EEPROM copy of programmed startup acceleration
_Eep_Pgm_Volt_Comp: DB 0FFh
Eep_Pgm_Comm_Timing: DB DEFAULT_PGM_MAIN_COMM_TIMING ; EEPROM copy of programmed commutation timing
Eep_Pgm_Damping_Force: DB DEFAULT_PGM_MAIN_DAMPING_FORCE ; EEPROM copy of programmed damping force
Eep_Pgm_Gov_Range: DB DEFAULT_PGM_MAIN_GOVERNOR_RANGE ; EEPROM copy of programmed governor range
Eep_Pgm_Startup_Method: DB DEFAULT_PGM_MAIN_STARTUP_METHOD ; EEPROM copy of programmed startup method
Eep_Pgm_Ppm_Min_Throttle: DB DEFAULT_PGM_PPM_MIN_THROTTLE ; EEPROM copy of programmed minimum throttle (final value is 4x+1000=1148)
Eep_Pgm_Ppm_Max_Throttle: DB DEFAULT_PGM_PPM_MAX_THROTTLE ; EEPROM copy of programmed minimum throttle (final value is 4x+1000=1832)
Eep_Pgm_Beep_Strength: DB DEFAULT_PGM_MAIN_BEEP_STRENGTH ; EEPROM copy of programmed beep strength
Eep_Pgm_Beacon_Strength: DB DEFAULT_PGM_MAIN_BEACON_STRENGTH ; EEPROM copy of programmed beacon strength
Eep_Pgm_Beacon_Delay: DB DEFAULT_PGM_MAIN_BEACON_DELAY ; EEPROM copy of programmed beacon delay
Eep_Pgm_Throttle_Rate: DB DEFAULT_PGM_MAIN_THROTTLE_RATE ; EEPROM copy of programmed throttle rate
Eep_Pgm_Demag_Comp: DB DEFAULT_PGM_MAIN_DEMAG_COMP ; EEPROM copy of programmed demag compensation
Eep_Pgm_BEC_Voltage_High: DB DEFAULT_PGM_BEC_VOLTAGE_HIGH ; EEPROM copy of programmed BEC voltage
ENDIF
IF MODE == 1
_Eep_Pgm_Gov_P_Gain: DB 0FFh
_Eep_Pgm_Gov_I_Gain: DB 0FFh
_Eep_Pgm_Gov_Mode: DB 0FFh
_Eep_Pgm_Low_Voltage_Lim: DB 0FFh
Eep_Pgm_Motor_Gain: DB DEFAULT_PGM_TAIL_GAIN ; EEPROM copy of programmed tail gain
Eep_Pgm_Motor_Idle: DB DEFAULT_PGM_TAIL_IDLE_SPEED ; EEPROM copy of programmed tail idle speed
Eep_Pgm_Startup_Pwr: DB DEFAULT_PGM_TAIL_STARTUP_PWR ; EEPROM copy of programmed startup power
Eep_Pgm_Pwm_Freq: DB DEFAULT_PGM_TAIL_PWM_FREQ ; EEPROM copy of programmed pwm frequency
Eep_Pgm_Direction_Rev: DB DEFAULT_PGM_TAIL_DIRECTION_REV ; EEPROM copy of programmed rotation direction
Eep_Pgm_Input_Pol: DB DEFAULT_PGM_TAIL_RCP_PWM_POL ; EEPROM copy of programmed input polarity
Eep_Initialized_L: DB 05Ah ; EEPROM initialized signature low byte
Eep_Initialized_H: DB 0A5h ; EEPROM initialized signature high byte
Eep_Enable_TX_Program: DB DEFAULT_PGM_ENABLE_TX_PROGRAM ; EEPROM TX programming enable
_Eep_Main_Rearm_Start: DB 0FFh
_Eep_Pgm_Gov_Setup_Target: DB 0FFh
Eep_Pgm_Startup_Rpm: DB DEFAULT_PGM_TAIL_STARTUP_RPM ; EEPROM copy of programmed startup rpm
Eep_Pgm_Startup_Accel: DB DEFAULT_PGM_TAIL_STARTUP_ACCEL ; EEPROM copy of programmed startup acceleration
_Eep_Pgm_Volt_Comp: DB 0FFh
Eep_Pgm_Comm_Timing: DB DEFAULT_PGM_TAIL_COMM_TIMING ; EEPROM copy of programmed commutation timing
Eep_Pgm_Damping_Force: DB DEFAULT_PGM_TAIL_DAMPING_FORCE ; EEPROM copy of programmed damping force
_Eep_Pgm_Gov_Range: DB 0FFh
Eep_Pgm_Startup_Method: DB DEFAULT_PGM_TAIL_STARTUP_METHOD ; EEPROM copy of programmed startup method
Eep_Pgm_Ppm_Min_Throttle: DB DEFAULT_PGM_PPM_MIN_THROTTLE ; EEPROM copy of programmed minimum throttle (final value is 4x+1000=1148)
Eep_Pgm_Ppm_Max_Throttle: DB DEFAULT_PGM_PPM_MAX_THROTTLE ; EEPROM copy of programmed minimum throttle (final value is 4x+1000=1832)
Eep_Pgm_Beep_Strength: DB DEFAULT_PGM_TAIL_BEEP_STRENGTH ; EEPROM copy of programmed beep strength
Eep_Pgm_Beacon_Strength: DB DEFAULT_PGM_TAIL_BEACON_STRENGTH ; EEPROM copy of programmed beacon strength
Eep_Pgm_Beacon_Delay: DB DEFAULT_PGM_TAIL_BEACON_DELAY ; EEPROM copy of programmed beacon delay
Eep_Pgm_Throttle_Rate: DB DEFAULT_PGM_TAIL_THROTTLE_RATE ; EEPROM copy of programmed throttle rate
Eep_Pgm_Demag_Comp: DB DEFAULT_PGM_TAIL_DEMAG_COMP ; EEPROM copy of programmed demag compensation
Eep_Pgm_BEC_Voltage_High: DB DEFAULT_PGM_BEC_VOLTAGE_HIGH ; EEPROM copy of programmed BEC voltage
ENDIF
IF MODE == 2
Eep_Pgm_Fir_Key: DB DEFAULT_PGM_MULTI_FIRST_KEYWORD ;增加首个关键字 2013.8.27
Eep_Pgm_Gov_P_Gain: DB DEFAULT_PGM_MULTI_P_GAIN ; EEPROM copy of programmed closed loop P gain
Eep_Pgm_Gov_I_Gain: DB DEFAULT_PGM_MULTI_I_GAIN ; EEPROM copy of programmed closed loop I gain
Eep_Pgm_Gov_Mode: DB DEFAULT_PGM_MULTI_GOVERNOR_MODE ; EEPROM copy of programmed closed loop mode
Eep_Pgm_Low_Voltage_Lim: DB DEFAULT_PGM_MULTI_LOW_VOLTAGE_LIM ; EEPROM copy of programmed low voltage limit
Eep_Pgm_Low_Voltage_Ctl: DB DEFAULT_PGM_MULTI_LOW_VOLTAGE_CTL ; 增加低压保护控制编程
Eep_Pgm_Motor_Gain: DB DEFAULT_PGM_MULTI_GAIN ; EEPROM copy of programmed tail gain
_Eep_Pgm_Motor_Idle: DB 0FFh ; EEPROM copy of programmed tail idle speed
Eep_Pgm_Startup_Pwr: DB DEFAULT_PGM_MULTI_STARTUP_PWR ; EEPROM copy of programmed startup power
Eep_Pgm_Pwm_Freq: DB DEFAULT_PGM_MULTI_PWM_FREQ ; EEPROM copy of programmed pwm frequency
Eep_Pgm_Direction_Rev: DB DEFAULT_PGM_MULTI_DIRECTION_REV ; EEPROM copy of programmed rotation direction
Eep_Pgm_Input_Pol: DB DEFAULT_PGM_MULTI_RCP_PWM_POL ; EEPROM copy of programmed input polarity
Eep_Initialized_L: DB 055h ; EEPROM initialized signature low byte
Eep_Initialized_H: DB 0AAh ; EEPROM initialized signature high byte
Eep_Enable_TX_Program: DB DEFAULT_PGM_ENABLE_TX_PROGRAM ; EEPROM TX programming enable
_Eep_Main_Rearm_Start: DB 0FFh
_Eep_Pgm_Gov_Setup_Target: DB 0FFh
Eep_Pgm_Startup_Rpm: DB DEFAULT_PGM_MULTI_STARTUP_RPM ; EEPROM copy of programmed startup rpm
Eep_Pgm_Startup_Accel: DB DEFAULT_PGM_MULTI_STARTUP_ACCEL ; EEPROM copy of programmed startup acceleration
_Eep_Pgm_Volt_Comp: DB 0FFh
Eep_Pgm_Comm_Timing: DB DEFAULT_PGM_MULTI_COMM_TIMING ; EEPROM copy of programmed commutation timing
Eep_Pgm_Damping_Force: DB DEFAULT_PGM_MULTI_DAMPING_FORCE ; EEPROM copy of programmed damping force
_Eep_Pgm_Gov_Range: DB 0FFh
;Eep_Pgm_Startup_Method: DB DEFAULT_PGM_MULTI_STARTUP_METHOD ; EEPROM copy of programmed startup method
Eep_Pgm_Ppm_Min_Throttle: DB DEFAULT_PGM_PPM_MIN_THROTTLE ; EEPROM copy of programmed minimum throttle (final value is 4x+1000=1148)
Eep_Pgm_Ppm_Max_Throttle: DB DEFAULT_PGM_PPM_MAX_THROTTLE ; EEPROM copy of programmed minimum throttle (final value is 4x+1000=1832)
Eep_Pgm_Beep_Strength: DB DEFAULT_PGM_MULTI_BEEP_STRENGTH ; EEPROM copy of programmed beep strength
Eep_Pgm_Beacon_Strength: DB DEFAULT_PGM_MULTI_BEACON_STRENGTH ; EEPROM copy of programmed beacon strength
Eep_Pgm_Beacon_Delay: DB DEFAULT_PGM_MULTI_BEACON_DELAY ; EEPROM copy of programmed beacon delay
Eep_Pgm_Throttle_Rate: DB DEFAULT_PGM_MULTI_THROTTLE_RATE ; EEPROM copy of programmed throttle rate
Eep_Pgm_Demag_Comp: DB DEFAULT_PGM_MULTI_DEMAG_COMP ; EEPROM copy of programmed demag compensation
Eep_Pgm_BEC_Voltage_High: DB DEFAULT_PGM_BEC_VOLTAGE_HIGH ; EEPROM copy of programmed BEC voltage
ENDIF
Eep_Dummy: DB 0FFh ; EEPROM address for safety reason
CSEG AT 1A60h
Eep_Name: DB " " ; Name tag (16 Bytes)
;**** **** **** **** ****
Interrupt_Table_Definition ; SiLabs interrupts
CSEG AT 80h ; Code segment after interrupt vectors
;**** **** **** **** ****
; Table definitions
GOV_GAIN_TABLE: DB 02h, 03h, 04h, 06h, 08h, 0Ch, 10h, 18h, 20h, 30h, 40h, 60h, 80h
THROTTLE_RATE_TABLE: DB 02h, 03h, 04h, 06h, 08h, 0Ch, 10h, 18h, 20h, 30h, 40h, 80h, 0FFh
STARTUP_POWER_TABLE: DB 04h, 06h, 08h, 0Ch, 10h, 18h, 20h, 30h, 40h, 60h, 80h, 0A0h, 0C0h
DEMAG_WAIT_TABLE: DB 0, 0, 0, 1, 1
DEMAG_POWER_TABLE: DB 0, 3, 2, 2, 1
;FINISH_KEYWORD_TABLE: DB 066h, 08h, 08h, 03h, 01h, 00h, 02h, 00h
; DB 09h, 01h, 00h, 00h, 00h, 00h, 00h, 00h
; DB 0B4h, 00h, 04h, 00h, 02h, 00h, 00h, 025h
; DB 0D0h, 050h, 064h, 01h, 0Dh, 01h, 00h, 00h ;增加编程默认值表 2013.7.30 ;//////////////////////////////////////////
; DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
; DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
IF MODE == 0
TX_PGM_PARAMS_MAIN: DB 13, 13, 4, 2, 6, 2, 13, 5, 5, 5, 13, 6, 3, 5, 2, 2
ENDIF
IF MODE == 1
IF DAMPED_MODE_ENABLE == 1
TX_PGM_PARAMS_TAIL: DB 5, 5, 2, 13, 5, 5, 5, 13, 6, 4, 5, 2, 2
ENDIF
IF DAMPED_MODE_ENABLE == 0
TX_PGM_PARAMS_TAIL: DB 5, 5, 2, 13, 5, 5, 5, 13, 6, 3, 5, 2, 2
ENDIF
ENDIF
IF MODE == 2
IF DAMPED_MODE_ENABLE == 1
;///////TX_PGM_PARAMS_MULTI: DB 13, 13, 4, 5, 6, 2, 13, 5, 5, 5, 13, 6, 4, 5, 2, 2
TX_PGM_PARAMS_MULTI: DB 6, 5, 13, 4, 2, 4, 2
ENDIF
IF DAMPED_MODE_ENABLE == 0
;///////TX_PGM_PARAMS_MULTI: DB 13, 13, 4, 5, 6, 2, 13, 5, 5, 5, 13, 6, 3, 5, 2, 2
TX_PGM_PARAMS_MULTI: DB 6, 5, 13, 4, 2, 4, 2
ENDIF
ENDIF
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Timer0 interrupt routine
;
; Assumptions: DPTR register must be set to desired pwm_nfet_on label
; Requirements: Temp variables can NOT be used since PWSW.3 is not set
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
t0_int: ; Used for pwm control
clr EA ; Disable all interrupts
push PSW ; Preserve registers through interrupt
push ACC
; Check if pwm is on
jb Flags0.PWM_ON, t0_int_pwm_off ; Is pwm on?
; Pwm on cycle.
jnb Current_Pwm_Limited.7, t0_int_pwm_on_low_pwm ; Jump for low pwm (<50%)
t0_int_pwm_on_execute:
clr A
jmp @A+DPTR ; No - jump to pwm on routines. DPTR should be set to one of the pwm_nfet_on labels
t0_int_pwm_on_low_pwm:
; Do not execute pwm when stopped
jnb Flags1.MOTOR_SPINNING, t0_int_pwm_on_stopped
IF MODE == 0 OR MODE == 2 ; Main or multi
jmp t0_int_pwm_on_execute
ENDIF
IF MODE == 1 ; Tail
; Skip pwm on cycles for very low pwm
inc Pwm_On_Cnt ; Increment event counter
clr C
mov A, #5 ; Only skip for very low pwm
subb A, Current_Pwm_Limited ; Check skipping shall be done (for low pwm only)
jc t0_int_pwm_on_execute
subb A, Pwm_On_Cnt ; Check if on cycle is to be skipped
jc t0_int_pwm_on_execute
mov TL0, #120 ; Write start point for timer
mov A, Current_Pwm_Limited
jnz ($+5)
mov TL0, #0 ; Write start point for timer (long time for zero pwm)
jmp t0_int_pwm_on_exit_no_timer_update
ENDIF
t0_int_pwm_on_stopped:
jmp t0_int_pwm_on_exit
t0_int_pwm_off:
jnb Flags1.DIRECT_STARTUP_PHASE, t0_int_pwm_off_start_checked
All_nFETs_Off ; Switch off all nfets early during direct start, for a smooth start
t0_int_pwm_off_start_checked:
; Pwm off cycle
mov TL0, Current_Pwm_Limited ; Load new timer setting
; Clear pwm on flag
clr Flags0.PWM_ON
; Set full PWM (on all the time) if current PWM near max. This will give full power, but at the cost of a small "jump" in power
mov A, Current_Pwm_Limited ; Load current pwm
cpl A ; Full pwm?
jnz ($+4) ; No - branch
ajmp t0_int_pwm_off_fullpower_exit ; Yes - exit
inc Pwm_Off_Cnt ; Increment event counter
; Do not execute pwm when stopped
jnb Flags1.MOTOR_SPINNING, t0_int_pwm_off_stopped
; If damped operation, set pFETs on in pwm_off
jb Flags2.PGM_PWMOFF_DAMPED, t0_int_pwm_off_damped ; Damped operation?
; Separate exit commands here for minimum delay
mov TL1, #0 ; Reset timer1
pop ACC ; Restore preserved registers
pop PSW
All_nFETs_Off ; Switch off all nfets
setb EA ; Enable all interrupts
reti
t0_int_pwm_off_stopped:
All_nFETs_Off ; Switch off all nfets
jmp t0_int_pwm_off_exit
t0_int_pwm_off_damped:
setb Flags2.CURR_PWMOFF_DAMPED ; Set damped status
clr Flags2.CURR_PWMOFF_COMP_ABLE ; Set comparator unusable status
mov A, Damping_On
jz t0_int_pwm_off_do_damped ; Highest damping - apply damping always
clr C
mov A, Pwm_Off_Cnt ; Is damped on number reached?
dec A
subb A, Damping_On
jc t0_int_pwm_off_do_damped ; No - apply damping
clr Flags2.CURR_PWMOFF_DAMPED ; Set non damped status
setb Flags2.CURR_PWMOFF_COMP_ABLE ; Set comparator usable status
clr C
mov A, Pwm_Off_Cnt
subb A, Damping_Period ; Is damped period number reached?
jnc t0_int_pwm_off_clr_cnt ; Yes - Proceed
jmp t0_int_pwm_off_exit ; No - Branch
t0_int_pwm_off_clr_cnt:
mov Pwm_Off_Cnt, #0 ; Yes - clear counter
jmp t0_int_pwm_off_exit ; Not damped cycle - exit
t0_int_pwm_off_do_damped:
; Delay to allow nFETs to go off before pFETs are turned on (only in full damped mode)
jb Flags2.PGM_PWMOFF_DAMPED_LIGHT, t0_int_pwm_off_damped_light ; If damped light operation - branch
; All_pFETs_Off ; Switch off all nfets
; mov A, #PFETON_DELAY
; djnz ACC, $
; All_nFETs_On ; Switch on all pfets
jmp t0_int_pwm_off_exit
t0_int_pwm_off_damped_light:
IF DAMPED_MODE_ENABLE == 1
setb Flags2.CURR_PWMOFF_COMP_ABLE ; Set comparator usable status always for damped light mode on fully damped capable escs
ENDIF
All_nFETs_Off ; Switch off all nfets
mov A, Comm_Phase ; Turn on pfets according to commutation phase
jb ACC.2, t0_int_pwm_off_comm_4_5_6
jb ACC.1, t0_int_pwm_off_comm_2_3
IF DAMPED_MODE_ENABLE == 0
AnFET_On ; Comm phase 1 - turn on A
ELSE
mov A, #PFETON_DELAY
djnz ACC, $
CnFET_On ; Comm phase 1 - turn on C
ENDIF
jmp t0_int_pwm_off_exit
t0_int_pwm_off_comm_2_3:
jb ACC.0, t0_int_pwm_off_comm_3
IF DAMPED_MODE_ENABLE == 0
BnFET_On ; Comm phase 2 - turn on B
ELSE
mov A, #PFETON_DELAY
djnz ACC, $
CnFET_On ; Comm phase 2 - turn on C
ENDIF
jmp t0_int_pwm_off_exit
t0_int_pwm_off_comm_3:
IF DAMPED_MODE_ENABLE == 0
CnFET_On ; Comm phase 3 - turn on C
ELSE
mov A, #PFETON_DELAY
djnz ACC, $
BnFET_On ; Comm phase 3 - turn on B
ENDIF
jmp t0_int_pwm_off_exit
t0_int_pwm_off_comm_4_5_6:
jb ACC.1, t0_int_pwm_off_comm_6
jb ACC.0, t0_int_pwm_off_comm_5
IF DAMPED_MODE_ENABLE == 0
AnFET_On ; Comm phase 4 - turn on A
ELSE
mov A, #PFETON_DELAY
djnz ACC, $
BnFET_On ; Comm phase 4 - turn on B
ENDIF
jmp t0_int_pwm_off_exit
t0_int_pwm_off_comm_5:
IF DAMPED_MODE_ENABLE == 0
BnFET_On ; Comm phase 5 - turn on B
ELSE
mov A, #PFETON_DELAY
djnz ACC, $
AnFET_On ; Comm phase 5 - turn on A
ENDIF
jmp t0_int_pwm_off_exit
t0_int_pwm_off_comm_6:
IF DAMPED_MODE_ENABLE == 0
CnFET_On ; Comm phase 6 - turn on C
ELSE
mov A, #PFETON_DELAY
djnz ACC, $
AnFET_On ; Comm phase 6 - turn on A
ENDIF
t0_int_pwm_off_exit: ; Exit from pwm off cycle
mov TL1, #0 ; Reset timer1
pop ACC ; Restore preserved registers
pop PSW
All_nFETs_Off ; Switch off all nfets
setb EA ; Enable all interrupts
reti
t0_int_pwm_off_fullpower_exit: ; Exit from pwm off cycle, leaving power on
pop ACC ; Restore preserved registers
pop PSW
setb EA ; Enable all interrupts
reti
pwm_nofet_on: ; Dummy pwm on cycle
ajmp t0_int_pwm_on_exit
pwm_afet_on: ; Pwm on cycle afet on (bfet off)
AnFET_on
BnFET_off
ajmp t0_int_pwm_on_exit
pwm_bfet_on: ; Pwm on cycle bfet on (cfet off)
BnFET_on
CnFET_off
ajmp t0_int_pwm_on_exit
pwm_cfet_on: ; Pwm on cycle cfet on (afet off)
CnFET_on
AnFET_off
ajmp t0_int_pwm_on_exit
pwm_anfet_bpfet_on_fast: ; Pwm on cycle anfet on (bnfet off) and bpfet on (used in damped state 6)
ApFET_off
AnFET_on ; Switch nFETs
CpFET_off
BnFET_off
ajmp t0_int_pwm_on_exit
pwm_anfet_bpfet_on_safe: ; Pwm on cycle anfet on (bnfet off) and bpfet on (used in damped state 6)
; Delay from pFETs are turned off (only in damped mode) until nFET is turned on (pFETs are slow)
ApFET_off
CpFET_off
mov A, #NFETON_DELAY ; Set full delay
djnz ACC, $
AnFET_on ; Switch nFETs
BnFET_off
ajmp t0_int_pwm_on_exit
pwm_anfet_cpfet_on_fast: ; Pwm on cycle anfet on (bnfet off) and cpfet on (used in damped state 5)
ApFET_off
AnFET_on ; Switch nFETs
BpFET_off
BnFET_off
ajmp t0_int_pwm_on_exit
pwm_anfet_cpfet_on_safe: ; Pwm on cycle anfet on (bnfet off) and cpfet on (used in damped state 5)
; Delay from pFETs are turned off (only in damped mode) until nFET is turned on (pFETs are slow)
ApFET_off
BpFET_off
mov A, #NFETON_DELAY ; Set full delay
djnz ACC, $
AnFET_on ; Switch nFETs
BnFET_off
ajmp t0_int_pwm_on_exit
pwm_bnfet_cpfet_on_fast: ; Pwm on cycle bnfet on (cnfet off) and cpfet on (used in damped state 4)
BpFET_off
BnFET_on ; Switch nFETs
ApFET_off
CnFET_off
ajmp t0_int_pwm_on_exit
pwm_bnfet_cpfet_on_safe: ; Pwm on cycle bnfet on (cnfet off) and cpfet on (used in damped state 4)
; Delay from pFETs are turned off (only in damped mode) until nFET is turned on (pFETs are slow)
BpFET_off
ApFET_off
mov A, #NFETON_DELAY ; Set full delay
djnz ACC, $
BnFET_on ; Switch nFETs
CnFET_off
ajmp t0_int_pwm_on_exit
pwm_bnfet_apfet_on_fast: ; Pwm on cycle bnfet on (cnfet off) and apfet on (used in damped state 3)
BpFET_off
BnFET_on ; Switch nFETs
CpFET_off
CnFET_off
ajmp t0_int_pwm_on_exit
pwm_bnfet_apfet_on_safe: ; Pwm on cycle bnfet on (cnfet off) and apfet on (used in damped state 3)
; Delay from pFETs are turned off (only in damped mode) until nFET is turned on (pFETs are slow)
BpFET_off
CpFET_off
mov A, #NFETON_DELAY ; Set full delay
djnz ACC, $
BnFET_on ; Switch nFETs
CnFET_off
ajmp t0_int_pwm_on_exit
pwm_cnfet_apfet_on_fast: ; Pwm on cycle cnfet on (anfet off) and apfet on (used in damped state 2)
CpFET_off
CnFET_on ; Switch nFETs
BpFET_off
AnFET_off
ajmp t0_int_pwm_on_exit
pwm_cnfet_apfet_on_safe: ; Pwm on cycle cnfet on (anfet off) and apfet on (used in damped state 2)
; Delay from pFETs are turned off (only in damped mode) until nFET is turned on (pFETs are slow)
CpFET_off
BpFET_off
mov A, #NFETON_DELAY ; Set full delay
djnz ACC, $
CnFET_on ; Switch nFETs
AnFET_off
ajmp t0_int_pwm_on_exit
pwm_cnfet_bpfet_on_fast: ; Pwm on cycle cnfet on (anfet off) and bpfet on (used in damped state 1)
CpFET_off
CnFET_on ; Switch nFETs
ApFET_off
AnFET_off
ajmp t0_int_pwm_on_exit
pwm_cnfet_bpfet_on_safe: ; Pwm on cycle cnfet on (anfet off) and bpfet on (used in damped state 1)
; Delay from pFETs are turned off (only in damped mode) until nFET is turned on (pFETs are slow)
CpFET_off
ApFET_off
mov A, #NFETON_DELAY ; Set full delay
djnz ACC, $
CnFET_on ; Switch nFETs
AnFET_off
ajmp t0_int_pwm_on_exit
t0_int_pwm_on_exit:
; Set timer for coming on cycle length
mov A, Current_Pwm_Limited ; Load current pwm
cpl A ; cpl is 255-x
mov TL0, A ; Write start point for timer
; Set other variables
mov TL1, #0 ; Reset timer1
mov Pwm_On_Cnt, #0 ; Reset pwm on event counter
setb Flags0.PWM_ON ; Set pwm on flag
t0_int_pwm_on_exit_no_timer_update:
; Exit interrupt
pop ACC ; Restore preserved registers
pop PSW
setb EA ; Enable all interrupts
reti
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Timer2 interrupt routine
;
; No assumptions
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
t2_int: ; Happens every 128us for low byte and every 32ms for high byte
clr EA ; Disable all interrupts
push PSW ; Preserve registers through interrupt
push ACC
setb PSW.3 ; Select register bank 1 for interrupt routines
; Clear low byte interrupt flag
clr TF2L ; Clear interrupt flag
; Check RC pulse timeout counter
mov A, Rcp_Timeout_Cnt ; RC pulse timeout count zero?
jz t2_int_pulses_absent ; Yes - pulses are absent
; Decrement timeout counter (if PWM)
; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
; anl A, Flags3 ; Check pwm frequency flags
; jz t2_int_skip_start ; If no flag is set (PPM) - branch
; dec Rcp_Timeout_Cnt ; No - decrement
ajmp t2_int_skip_start
t2_int_pulses_absent:
; Timeout counter has reached zero, pulses are absent
mov Temp1, #RCP_MIN ; RCP_MIN as default
mov Temp2, #RCP_MIN
Read_Rcp_Int ; Look at value of Rcp_In
jnb ACC.Rcp_In, ($+5) ; Is it high?
mov Temp1, #RCP_MAX ; Yes - set RCP_MAX
Rcp_Int_First ; Set interrupt trig to first again
Rcp_Clear_Int_Flag ; Clear interrupt flag
clr Flags2.RCP_EDGE_NO ; Set first edge flag
Read_Rcp_Int ; Look once more at value of Rcp_In
jnb ACC.Rcp_In, ($+5) ; Is it high?
mov Temp2, #RCP_MAX ; Yes - set RCP_MAX
clr C
mov A, Temp1
subb A, Temp2 ; Compare the two readings of Rcp_In
jnz t2_int_pulses_absent ; Go back if they are not equal
jnb Flags0.RCP_MEAS_PWM_FREQ, ($+6) ; Is measure RCP pwm frequency flag set?
mov Rcp_Timeout_Cnt, #RCP_TIMEOUT ; Yes - set timeout count to start value
; mov Pgm_Pulse_Cnt, #0 ;清除PCA中断计数
; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
; anl A, Flags3 ; Check pwm frequency flags
; jz t2_int_ppm_timeout_set ; If no flag is set (PPM) - branch
; mov Rcp_Timeout_Cnt, #RCP_TIMEOUT ; For PWM, set timeout count to start value
t2_int_ppm_timeout_set:
mov New_Rcp, Temp1 ; Store new pulse length
setb Flags2.RCP_UPDATED ; Set updated flag
t2_int_skip_start:
; Check RC pulse skip counter
mov A, Rcp_Skip_Cnt
jz t2_int_skip_end ; If RC pulse skip count is zero - end skipping RC pulse detection
; Decrement skip counter (only if edge counter is zero)
dec Rcp_Skip_Cnt ; Decrement
ajmp t2_int_rcp_update_start
t2_int_skip_end:
; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
; anl A, Flags3 ; Check pwm frequency flags
; jz t2_int_rcp_update_start ; If no flag is set (PPM) - branch
; Skip counter has reached zero, start looking for RC pulses again
; Rcp_Int_Enable ; Enable RC pulse interrupt
; Rcp_Clear_Int_Flag ; Clear interrupt flag
t2_int_rcp_update_start:
; Process updated RC pulse
jb Flags2.RCP_UPDATED, ($+5) ; Is there an updated RC pulse available?
ajmp t2_int_pwm_exit ; No - exit
mov A, New_Rcp ; Load new pulse value
mov Temp1, A
clr Flags2.RCP_UPDATED ; Flag that pulse has been evaluated
; Use a gain of 1.0625x for pwm input if not governor mode
; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
; anl A, Flags3 ; Check pwm frequency flags
; jz t2_int_pwm_min_run ; If no flag is set (PPM) - branch
;;*****************************************************
;; Closed loop mode 选择
;;*****************************************************
;IF MODE <= 1 ; Main or tail
; mov Temp2, #Pgm_Gov_Mode ; Governor mode?
; cjne @Temp2, #4, t2_int_pwm_min_run; Yes - branch
;ENDIF
;IF MODE == 2 ; Multi
;;读取Closed loop mode
; mov Temp2, #Pgm_Gov_Mode ; Closed loop mode?
; cjne @Temp2, #4, t2_int_pwm_min_run; Yes - branch
;ENDIF
; ; Limit the maximum value to avoid wrap when scaled to pwm range
;;Closed loop mode = 第1项 Off
; clr C
; mov A, Temp1
; subb A, #240 ; 240 = (255/1.0625) Needs to be updated according to multiplication factor below
; jc t2_int_rcp_update_mult
; mov A, #240 ; Set requested pwm to max
; mov Temp1, A
;t2_int_rcp_update_mult:
; ; Multiply by 1.0625 (optional adjustment gyro gain)
; mov A, Temp1
; swap A ; After this "0.0625"
; anl A, #0Fh
; add A, Temp1
; mov Temp1, A
; ; Adjust tail gain
;;读取 Multi gain
; mov Temp2, #Pgm_Motor_Gain
; cjne @Temp2, #3, ($+5) ; Is gain 1?
; ajmp t2_int_pwm_min_run ; Yes - skip adjustment
;;Multi gain = 第2选项
; clr C
; rrc A ; After this "0.5"
; clr C
; rrc A ; After this "0.25"
; mov Bit_Access_Int, @Temp2 ; (Temp2 has #Pgm_Motor_Gain)
; jb Bit_Access_Int.0, t2_int_rcp_gain_corr ; Branch if bit 0 in gain is set
;;Multi gain = 第4选项
; clr C
; rrc A ; After this "0.125"
;t2_int_rcp_gain_corr:
; jb Bit_Access_Int.2, t2_int_rcp_gain_pos ; Branch if bit 2 in gain is set
;;Multi gain = 第1选项
; clr C
; xch A, Temp1
; subb A, Temp1 ; Apply negative correction
; mov Temp1, A
; ajmp t2_int_pwm_min_run
;;Multi gain = 第5选项
;t2_int_rcp_gain_pos:
; add A, Temp1 ; Apply positive correction
; mov Temp1, A
; jnc t2_int_pwm_min_run ; Above max?
; mov A, #0FFh ; Yes - limit
; mov Temp1, A
;;Multi gain = 第3选项
t2_int_pwm_min_run:
; Limit minimum pwm
clr C
mov A, Temp1
subb A, Pwm_Motor_Idle ; Is requested pwm lower than minimum?
jnc t2_int_pwm_update ; No - branch
mov A, Pwm_Motor_Idle ; Yes - limit pwm to Pwm_Motor_Idle
mov Temp1, A
t2_int_pwm_update:
; Check if any startup phase flags are set
mov A, Flags1
anl A, #((1 SHL SETTLE_PHASE)+(1 SHL STEPPER_PHASE))
jnz t2_int_pwm_exit ; Exit if any startup phase set (pwm controlled by set_startup_pwm)
; Update requested_pwm
mov Requested_Pwm, Temp1 ; Set requested pwm
; Limit pwm during direct start
jnb Flags1.DIRECT_STARTUP_PHASE, t2_int_current_pwm_update
clr C
mov A, Requested_Pwm ; Limit pwm during direct start
subb A, Pwm_Limit
jc ($+7)
mov Requested_Pwm, Pwm_Limit
ajmp t2_int_current_pwm_update
mov A, Requested_Pwm
add A, #11
mov Requested_Pwm, A
t2_int_current_pwm_update:
IF MODE <= 1 ; Main or tail
mov Temp1, #Pgm_Gov_Mode ; Governor mode?
cjne @Temp1, #4, t2_int_pwm_exit ; Yes - branch
ENDIF
IF MODE == 2 ; Multi
;读取Closed loop mode
mov Temp1, #Pgm_Gov_Mode ; Closed loop mode?
cjne @Temp1, #1, t2_int_pwm_exit ; Yes - branch
ENDIF
; Update current pwm, with limited throttle change rate
;Closed loop mode = Off
clr C
mov A, Requested_Pwm
subb A, Current_Pwm ; Is requested pwm larger than current pwm?
jc t2_int_set_current_pwm ; No - proceed
mov Temp1, #Pgm_Throttle_Rate_Decoded
subb A, @Temp1 ; Is difference larger than throttle change rate?
jc t2_int_set_current_pwm ; No - proceed
mov A, Current_Pwm ; Increase current pwm by throttle change rate
add A, @Temp1
mov Current_Pwm, A
jnc t2_int_current_pwm_done ; Is result above max?
mov Current_Pwm, #0FFh ; Yes - limit
jmp t2_int_current_pwm_done
t2_int_set_current_pwm:
mov Current_Pwm, Requested_Pwm ; Set equal as default
t2_int_current_pwm_done:
IF MODE == 1 ; Tail
; If tail, then set current_pwm_limited
mov Current_Pwm_Limited, Current_Pwm ; Default not limited
clr C
mov A, Current_Pwm ; Check against limit
subb A, Pwm_Limit
jc ($+5) ; If current pwm below limit - branch
mov Current_Pwm_Limited, Pwm_Limit ; Limit pwm
ENDIF
IF MODE == 2 ; Multi
; If multi, then set current_pwm_limited
mov Current_Pwm_Limited, Current_Pwm ; Default not limited
clr C
mov A, Current_Pwm ; Check against limit
subb A, Pwm_Limit
jc ($+5) ; If current pwm below limit - branch
mov Current_Pwm_Limited, Pwm_Limit ; Limit pwm
ENDIF
t2_int_pwm_exit:
; Check if high byte flag is set
jb TF2H, t2h_int
pop ACC ; Restore preserved registers
pop PSW
clr PSW.3 ; Select register bank 0 for main program routines
setb EA ; Enable all interrupts
reti
t2h_int:
; High byte interrupt (happens every 32ms)
clr TF2H ; Clear interrupt flag
mov Temp1, #GOV_SPOOLRATE ; Load governor spool rate
; Check RC pulse timeout counter (used here for PPM only)
mov A, Rcp_Timeout_Cnt ; RC pulse timeout count zero?
jz t2h_int_rcp_stop_check ; Yes - do not decrement
; Decrement timeout counter (if PPM)
; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
; anl A, Flags3 ; Check pwm frequency flags
; jnz t2h_int_rcp_stop_check ; If a flag is set (PWM) - branch
dec Rcp_Timeout_Cnt ; No flag set (PPM) - decrement
t2h_int_rcp_stop_check:
; Check RC pulse against stop value
clr C
mov A, New_Rcp ; Load new pulse value
subb A, #RCP_STOP
; subb A, #(RCP_STOP+2) ; Check if pulse is below stop value
jc t2h_int_rcp_stop
; RC pulse higher than stop value, reset stop counter
mov Rcp_Stop_Cnt, #0 ; Reset rcp stop counter
ajmp t2h_int_rcp_gov_pwm
t2h_int_rcp_stop:
; RC pulse less than stop value, increment stop counter
mov A, Rcp_Stop_Cnt ; Load rcp stop counter
inc A ; Check if counter is max
jz t2h_int_rcp_gov_pwm ; Branch if counter is equal to max
inc Rcp_Stop_Cnt ; Increment stop counter
t2h_int_rcp_gov_pwm:
IF MODE == 0 ; Main
mov Temp2, #Pgm_Gov_Mode ; Governor target by arm mode?
cjne @Temp2, #2, t2h_int_rcp_gov_by_setup ; No - branch
mov A, Gov_Active ; Is governor active?
jz t2h_int_rcp_gov_by_tx ; No - branch (this ensures soft spoolup by tx)
clr C
mov A, Requested_Pwm
subb A, #50 ; Is requested pwm below 20%?
jc t2h_int_rcp_gov_by_tx ; Yes - branch (this enables a soft spooldown)
mov Requested_Pwm, Gov_Arm_Target ; Yes - load arm target
t2h_int_rcp_gov_by_setup:
mov Temp2, #Pgm_Gov_Mode ; Governor target by setup mode?
cjne @Temp2, #3, t2h_int_rcp_gov_by_tx ; No - branch
mov A, Gov_Active ; Is governor active?
jz t2h_int_rcp_gov_by_tx ; No - branch (this ensures soft spoolup by tx)
clr C
mov A, Requested_Pwm
subb A, #50 ; Is requested pwm below 20%?
jc t2h_int_rcp_gov_by_tx ; Yes - branch (this enables a soft spooldown)
;读取Pgm_Gov_Setup_Target
mov Temp2, #Pgm_Gov_Setup_Target ; Gov by setup - load setup target
mov Requested_Pwm, @Temp2
t2h_int_rcp_gov_by_tx:
clr C
mov A, Governor_Req_Pwm
subb A, Requested_Pwm ; Is governor requested pwm equal to requested pwm?
jz t2h_int_rcp_gov_pwm_done ; Yes - branch
jc t2h_int_rcp_gov_pwm_inc ; No - if lower, then increment
dec Governor_Req_Pwm ; No - if higher, then decrement
ajmp t2h_int_rcp_gov_pwm_done
t2h_int_rcp_gov_pwm_inc:
inc Governor_Req_Pwm ; Increment
t2h_int_rcp_gov_pwm_done:
djnz Temp1, t2h_int_rcp_gov_pwm ; If not number of steps processed - go back
inc Spoolup_Limit_Cnt ; Increment spoolup count
jnz ($+4) ; Wrapped?
dec Spoolup_Limit_Cnt ; Yes - decrement
djnz Spoolup_Limit_Skip, t2h_int_rcp_exit ; Jump if skip count is not reached
mov Spoolup_Limit_Skip, #1 ; Reset skip count. Default is fast spoolup
mov Temp1, #3 ; Default fast increase
clr C
mov A, Spoolup_Limit_Cnt
subb A, #(3*MAIN_SPOOLUP_TIME) ; No spoolup until "30"*32ms
jc t2h_int_rcp_exit
clr C
mov A, Spoolup_Limit_Cnt
subb A, #(10*MAIN_SPOOLUP_TIME) ; Slow spoolup until "100"*32ms
jnc t2h_int_rcp_limit_middle_ramp
mov Temp1, #1 ; Slow initial spoolup
mov Spoolup_Limit_Skip, #3
jmp t2h_int_rcp_set_limit
t2h_int_rcp_limit_middle_ramp:
clr C
mov A, Spoolup_Limit_Cnt
subb A, #(15*MAIN_SPOOLUP_TIME) ; Faster spoolup until "150"*32ms
jnc t2h_int_rcp_set_limit
mov Temp1, #1 ; Faster middle spoolup
mov Spoolup_Limit_Skip, #1
t2h_int_rcp_set_limit:
mov A, Pwm_Limit_Spoolup ; Increment spoolup pwm
clr C
add A, Temp1
jnc t2h_int_rcp_no_limit ; If below 255 - branch
mov Pwm_Limit_Spoolup, #0FFh
ajmp t2h_int_rcp_exit
t2h_int_rcp_no_limit:
mov Pwm_Limit_Spoolup, A
ENDIF
IF MODE == 2 ; Multi
mov A, Pwm_Limit_Spoolup ; Increment spoolup pwm, for a 0.8 seconds spoolup
clr C
add A, #10
jnc t2h_int_rcp_no_limit ; If below 255 - branch
mov Pwm_Limit_Spoolup, #0FFh
ajmp t2h_int_rcp_exit
t2h_int_rcp_no_limit:
mov Pwm_Limit_Spoolup, A
ENDIF
t2h_int_rcp_exit:
pop ACC ; Restore preserved registers
pop PSW
clr PSW.3 ; Select register bank 0 for main program routines
setb EA ; Enable all interrupts
reti
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Timer3 interrupt routine
;
; No assumptions
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
t3_int: ; Used for commutation timing
clr EA ; Disable all interrupts
anl TMR3CN, #07Fh ; Clear interrupt flag
clr Flags0.T3_PENDING ; Flag that timer has wrapped
setb EA ; Enable all interrupts
reti
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; PCA interrupt routine
;
; No assumptions
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
pca_int: ; Used for RC pulse timing
clr EA ; Disable all interrupts
push PSW ; Preserve registers through interrupt
push ACC
push B
setb PSW.3 ; Select register bank 1 for interrupt routines
; mov A, Pca_First_Int
; cjne A, #1, ($+5)
; inc Pgm_Pulse_Cnt
; Get PCA0 capture values
mov Temp1, PCA0CPL0
mov Temp2, PCA0CPH0
; Clear interrupt flag
Rcp_Clear_Int_Flag
; Check which edge it is
jnb Flags2.RCP_EDGE_NO, ($+5) ; Is it a first edge trig?
ajmp pca_int_second_meas_pwm_freq ; No - branch to second
Rcp_Int_Second ; Yes - set second edge trig
setb Flags2.RCP_EDGE_NO ; Set second edge flag
; Read RC signal level
Read_Rcp_Int
; Test RC signal level
jb ACC.Rcp_In, ($+5) ; Is it high?
ajmp pca_int_fail_minimum ; No - jump to fail minimum
; RC pulse was high, store RC pulse start timestamp
mov Rcp_Prev_Edge_L, Temp1
mov Rcp_Prev_Edge_H, Temp2
ajmp pca_int_exit ; Exit
pca_int_fail_minimum:
; Prepare for next interrupt
Rcp_Int_First ; Set interrupt trig to first again
Rcp_Clear_Int_Flag ; Clear interrupt flag
clr Flags2.RCP_EDGE_NO ; Set first edge flag
; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
mov A, #(1 SHL RCP_PWM_FREQ_1KHZ)
anl A, Flags3 ; Check pwm frequency flags
jnz ($+4) ; If a flag is set (PWM) - proceed
ajmp pca_int_set_timeout ; If PPM - ignore trig as noise
mov Temp1, #RCP_MIN ; Set RC pulse value to minimum
Read_Rcp_Int ; Test RC signal level again
jnb ACC.Rcp_In, ($+5) ; Is it high?
ajmp pca_int_set_timeout ; Yes - set new timeout and exit
mov New_Rcp, Temp1 ; Store new pulse length
ajmp pca_int_set_timeout ; Set new timeout and exit
pca_int_second_meas_pwm_freq:
; Prepare for next interrupt
Rcp_Int_First ; Set first edge trig
clr Flags2.RCP_EDGE_NO ; Set first edge flag
; Check if pwm frequency shall be measured
jb Flags0.RCP_MEAS_PWM_FREQ, ($+5) ; Is measure RCP pwm frequency flag set?
ajmp pca_int_fall ; No - skip measurements
; Set second edge trig only during pwm frequency measurement
Rcp_Int_Second ; Set second edge trig
Rcp_Clear_Int_Flag ; Clear interrupt flag
setb Flags2.RCP_EDGE_NO ; Set second edge flag
; Store edge data to RAM
mov Rcp_Edge_L, Temp1
mov Rcp_Edge_H, Temp2
; Calculate pwm frequency
clr C
mov A, Temp1
subb A, Rcp_PrePrev_Edge_L
mov Temp1, A ;存低字节差
mov A, Temp2
subb A, Rcp_PrePrev_Edge_H
mov Temp2, A ;存高字节差
; clr A
; mov Temp4, A
; Check if pwm frequency is 8kHz
mov Temp3, #250 ; Set default period tolerance requirement
; clr C
; mov A, Temp1
; subb A, #low(360) ; If below 180us, 8kHz pwm is assumed
; mov A, Temp2
; subb A, #high(360)
; jnc pca_int_check_4kHz
; clr A
; setb ACC.RCP_PWM_FREQ_8KHZ
; mov Temp4, A
; mov Temp3, #15 ; Set period tolerance requirement
; ajmp pca_int_restore_edge
;pca_int_check_4kHz:
; ; Check if pwm frequency is 4kHz
; clr C
; mov A, Temp1
; subb A, #low(720) ; If below 360us, 4kHz pwm is assumed
; mov A, Temp2
; subb A, #high(720)
; jnc pca_int_check_2kHz
; clr A
; setb ACC.RCP_PWM_FREQ_4KHZ
; mov Temp4, A
; mov Temp3, #30 ; Set period tolerance requirement
; ajmp pca_int_restore_edge
;pca_int_check_2kHz:
; ; Check if pwm frequency is 2kHz
; clr C
; mov A, Temp1
; subb A, #low(1440) ; If below 720us, 2kHz pwm is assumed
; mov A, Temp2
; subb A, #high(1440)
; jnc pca_int_check_1kHz
; clr A
; setb ACC.RCP_PWM_FREQ_2KHZ
; mov Temp4, A
; mov Temp3, #60 ; Set period tolerance requirement
; ajmp pca_int_restore_edge
;pca_int_check_1kHz:
; Check if pwm frequency is 1kHz
clr C
mov A, Temp1
subb A, #low(2200) ; If below 1100us, 1kHz pwm is assumed
mov A, Temp2
subb A, #high(2200)
jnc pca_int_restore_edge
ajmp pca_int_set_timeout
; clr A
; setb ACC.RCP_PWM_FREQ_1KHZ
; mov Temp4, A
; mov Temp3, #120 ; Set period tolerance requirement
pca_int_restore_edge:
; Calculate difference between this period and previous period
clr C
mov A, Temp1
subb A, Rcp_Prev_Period_L
mov Temp5, A
mov A, Temp2
subb A, Rcp_Prev_Period_H
mov Temp6, A
; Make positive
jnb ACC.7, pca_int_check_diff
mov A, Temp5
cpl A
add A, #1
mov Temp5, A
mov A, Temp6
cpl A
mov Temp6, A
pca_int_check_diff:
; Check difference
mov Rcp_Period_Diff_Accepted, #0 ; Set not accepted as default
jnz pca_int_store_data ; Check if high byte is zero
clr C
mov A, Temp5
subb A, Temp3 ; Check difference
jnc pca_int_store_data
mov Rcp_Period_Diff_Accepted, #1 ; Set accepted
pca_int_store_data:
; Store previous period
mov Rcp_Prev_Period_L, Temp1
mov Rcp_Prev_Period_H, Temp2
; Restore edge data from RAM
mov Temp1, Rcp_Edge_L
mov Temp2, Rcp_Edge_H
; Store pre previous edge
mov Rcp_PrePrev_Edge_L, Temp1
mov Rcp_PrePrev_Edge_H, Temp2
pca_int_fall:
clr A
mov Temp4, A
; RC pulse edge was second, calculate new pulse length
clr C
mov A, Temp1
subb A, Rcp_Prev_Edge_L
mov Temp1, A
mov A, Temp2
subb A, Rcp_Prev_Edge_H
mov Temp2, A
; jnb Flags3.RCP_PWM_FREQ_8KHZ, ($+5) ; Is RC input pwm frequency 8kHz?
; ajmp pca_int_pwm_divide_done ; Yes - branch forward
; jnb Flags3.RCP_PWM_FREQ_4KHZ, ($+5) ; Is RC input pwm frequency 4kHz?
; ajmp pca_int_pwm_divide ; Yes - branch forward
mov A, Temp2 ; No - 2kHz. Divide by 2 again
clr C
rrc A
mov Temp2, A
mov A, Temp1
rrc A
mov Temp1, A
; jnb Flags3.RCP_PWM_FREQ_2KHZ, ($+5) ; Is RC input pwm frequency 2kHz?
; ajmp pca_int_pwm_divide ; Yes - branch forward
mov A, Temp2 ; No - 1kHz. Divide by 2 again
clr C
rrc A
mov Temp2, A
mov A, Temp1
rrc A
mov Temp1, A
clr C
mov A, Temp1
subb A, #250 ; If below 500us,
mov A, Temp2
subb A, #0
jnc ($+9)
mov A, Initial_Arm
cjne A, #1, ($+5)
ajmp pca_int_pwm_divide
; jnb Flags3.RCP_PWM_FREQ_1KHZ, ($+5) ; Is RC input pwm frequency 1kHz?
; ajmp pca_int_pwm_divide ; Yes - branch forward
mov A, Temp2 ; No - PPM. Divide by 2 (to bring range to 256) and move to Temp5/6
clr C
rrc A
mov Temp6, A
mov A, Temp1
rrc A
mov Temp5, A
; Skip range limitation if pwm frequency measurement
jb Flags0.RCP_MEAS_PWM_FREQ, pca_int_ppm_check_full_range
; Check if 2160us or above (in order to ignore false pulses)
clr C
mov A, Temp5 ; Is pulse 2160us or higher?
subb A, #28
mov A, Temp6
subb A, #2
jc ($+5) ; No - proceed
ljmp pca_int_set_timeout ; Yes - ignore pulse
; Check if below 800us (in order to ignore false pulses)
mov A, Temp6
jnz pca_int_ppm_check_full_range
clr C
mov A, Temp5 ; Is pulse below 800us?
subb A, #200
jnc pca_int_ppm_check_full_range ; No - proceed
jmp pca_int_exit ; Yes - ignore pulse
pca_int_ppm_check_full_range:
; Calculate "1000us" plus throttle minimum
mov A, #0 ; Set 1000us as default minimum
jb Flags3.FULL_THROTTLE_RANGE, pca_int_ppm_calculate ; Check if full range is chosen
mov Temp1, #Pgm_Ppm_Min_Throttle ; Min throttle value is in 4us units
mov A, @Temp1
pca_int_ppm_calculate:
add A, #250
mov Temp7, A
clr A
addc A, #0
mov Temp8, A
clr C
mov A, Temp5 ; Subtract minimum
subb A, Temp7
mov Temp5, A
mov A, Temp6
subb A, Temp8
mov Temp6, A
jnc pca_int_ppm_neg_checked ; Is result negative?
mov Temp1, #RCP_MIN ; Yes - set to minimum
mov Temp2, #0
ajmp pca_int_pwm_divide_done
pca_int_ppm_neg_checked:
clr C ; Check that RC pulse is within legal range (1000+4*255=2020)
mov A, Temp5
subb A, #RCP_MAX
mov A, Temp6
subb A, #0
jc pca_int_ppm_max_checked
mov Temp1, #RCP_MAX
mov Temp2, #0
ajmp pca_int_pwm_divide_done
pca_int_ppm_max_checked:
mov A, Temp5 ; Multiply throttle value by gain
mov B, Ppm_Throttle_Gain
mul AB
xch A, B
mov C, B.7 ; Multiply result by 2 (unity gain is 128)
rlc A
mov Temp1, A ; Transfer to Temp1/2
mov Temp2, #0
jc pca_int_ppm_limit_after_mult
jmp pca_int_limited
pca_int_ppm_limit_after_mult:
mov Temp1, #RCP_MAX
mov Temp2, #0
jmp pca_int_limited
pca_int_pwm_divide:
;480us
clr C
mov A, Temp1
subb A, #240
mov A, Temp2
subb A, #0
jnc pca_int_set_timeout
;40us
clr C
mov A, Temp1
subb A, #20
mov A, Temp2
subb A, #0
jc pca_int_set_timeout
clr A
setb ACC.RCP_PWM_FREQ_1KHZ
mov Temp4, A
; mov Rcp_Period_Diff_Accepted, #1
ajmp pca_int_limited
pca_int_pwm_divide_done:
; Check that RC pulse is within legal range
clr C
mov A, Temp1
subb A, #RCP_MAX
mov A, Temp2
subb A, #0
jc pca_int_limited
mov Temp1, #RCP_MAX
pca_int_limited:
; RC pulse value accepted
mov New_Rcp, Temp1 ; Store new pulse length
setb Flags2.RCP_UPDATED ; Set updated flag
; jb Flags0.RCP_MEAS_PWM_FREQ, ($+5) ; Is measure RCP pwm frequency flag set?
; ajmp pca_int_set_timeout ; No - skip measurements
; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
mov A, #(1 SHL RCP_PWM_FREQ_1KHZ)
cpl A
anl A, Flags3 ; Clear all pwm frequency flags
orl A, Temp4 ; Store pwm frequency value in flags
mov Flags3, A
pca_int_set_timeout:
mov Rcp_Timeout_Cnt, #RCP_TIMEOUT ; Set timeout count to start value
; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
mov A, #(1 SHL RCP_PWM_FREQ_1KHZ)
anl A, Flags3 ; Check pwm frequency flags
jnz pca_int_ppm_timeout_set ; If a flag is set - branch
mov Rcp_Timeout_Cnt, #RCP_TIMEOUT_PPM ; No flag set means PPM. Set timeout count
pca_int_ppm_timeout_set:
; jnb Flags0.RCP_MEAS_PWM_FREQ, ($+5) ; Is measure RCP pwm frequency flag set?
; ajmp pca_int_exit ; Yes - exit
; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
; anl A, Flags3 ; Check pwm frequency flags
; jz pca_int_exit ; If no flag is set (PPM) - branch
; Rcp_Int_Disable ; Disable RC pulse interrupt
pca_int_exit: ; Exit interrupt routine
mov Rcp_Skip_Cnt, #RCP_SKIP_RATE ; Load number of skips
; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
mov A, #(1 SHL RCP_PWM_FREQ_1KHZ)
anl A, Flags3 ; Check pwm frequency flags
jnz ($+5) ; If a flag is set (PWM) - branch
mov Rcp_Skip_Cnt, #10 ; Load number of skips
pop B ; Restore preserved registers
pop ACC
pop PSW
clr PSW.3 ; Select register bank 0 for main program routines
setb EA ; Enable all interrupts
reti
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Wait xms ~(x*4*250) (Different entry points)
;
; No assumptions
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
wait1ms:
mov Temp2, #1
ajmp waitxms_o
wait3ms:
mov Temp2, #3
ajmp waitxms_o
wait10ms:
mov Temp2, #10
ajmp waitxms_o
wait30ms:
mov Temp2, #30
ajmp waitxms_o
wait100ms:
mov Temp2, #100
ajmp waitxms_o
wait200ms:
mov Temp2, #200
ajmp waitxms_o
waitxms_o: ; Outer loop
mov Temp1, #23
waitxms_m: ; Middle loop
clr A
djnz ACC, $ ; Inner loop (42.7us - 1024 cycles)
djnz Temp1, waitxms_m
djnz Temp2, waitxms_o
ret
;**;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Wait 1 second routine
;
; No assumptions
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
wait1s:
mov Temp5, #5
wait1s_loop:
call wait200ms
djnz Temp5, wait1s_loop
ret
;**;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Success beep routine
;
; No assumptions
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
success_beep:
clr EA ; Disable all interrupts
call beep_f1
call beep_f2
call beep_f3
; call beep_f4
call wait10ms
call beep_f1
call beep_f2
call beep_f3
; call beep_f4
; call wait10ms
; call beep_f1
; call beep_f2
; call beep_f3
; call beep_f4
setb EA ; Enable all interrupts
ret
;**;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Success beep inverted routine
;
; No assumptions
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
success_beep_inverted:
clr EA ; Disable all interrupts
; call beep_f4
call beep_f3
call beep_f2
call beep_f1
call wait10ms
; call beep_f4
call beep_f3
call beep_f2
call beep_f1
call wait10ms
; call beep_f4
; call beep_f3
; call beep_f2
; call beep_f1
setb EA ; Enable all interrupts
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Function and parameter value beep routine
;
; No assumptions
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
function_paraval_beep:
mov Temp7, Tx_Pgm_Func_No ; Function no
mov Temp8, Tx_Pgm_Paraval_No ; Parameter value no
clr EA ; Disable all interrupts
;//////function_beep:
;////// call beep_f1
;////// call beep_f1
;////// call beep_f1
;////// call wait10ms
;////// djnz Temp7, function_beep
;//////paraval_beep:
;////// call beep_f4
;////// call wait10ms
;////// djnz Temp8, paraval_beep
;function_beep:
jnb Flags0.PROGRAM_FUNC_FLAG,paraval_beep ;跳到参数选项叫
function_no_6:
clr C
mov A,Temp7
subb A,#5
jc function_below_beep
jz function_beep
mov Temp7, A
function_beep:
call beep_f3
call beep_f3
call beep_f3
call beep_f3
call beep_f3
call wait30ms
cjne Temp7,#5,($+5)
ajmp fun_par_end
function_below_beep:
call beep_f1
call beep_f1
call beep_f1
call wait100ms
djnz Temp7, function_below_beep
ajmp fun_par_end
paraval_beep:
clr A
mov Temp7,A
clr C
mov A,Temp8
subb A,#10 ;参数数 - 10
jc paraval_no_7 ;<10
inc Temp7 ;>=10
inc Temp7
jz paraval_below_beep
mov Temp8,A ;>=存差
ajmp paraval_below_beep
paraval_no_7:
clr C
mov A,Temp8
subb A,#5
jc paraval_no_below
inc Temp7
jz paraval_below_beep
mov Temp8,A ;>=存差
paraval_below_beep:
call beep_f2
call beep_f2
call beep_f2
call wait30ms
djnz Temp7,paraval_below_beep
cjne Temp8,#10,($+5)
ajmp fun_par_end
cjne Temp8,#5,($+5)
ajmp fun_par_end
paraval_no_below:
call wait100ms
call beep_f4
call wait100ms
djnz Temp8, paraval_no_below
fun_par_end:
setb EA ; Enable all interrupts
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; 接收一个数据(一个字节)
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
receive_a_byte:
mov Temp8,#0
mov Commu_Data_Buffer, #0
mov Temp4, #8
wait_high:
Read_Rcp_Int
; Test RC signal level
jb ACC.Rcp_In,start_t2
jnb TF1, wait_high
; setb Flags3.ERRO_DATA
; ajmp receive_exit
start_t2:
mov TL0, #00h
mov TH0, #00h
setb TR0 ;启动T0
wait_low:
Read_Rcp_Int
; Test RC signal level
jnb ACC.Rcp_In, measure_wide
jnb TF1, wait_low
; setb Flags3.ERRO_DATA
; ajmp receive_exit
measure_wide:
clr TR0 ;停止T0
; mov Temp1, TL0
; mov Temp2, TH0
; mov New_Rcp, Temp1
mov New_Rcp, TL0
clr C
mov A, New_Rcp
subb A, #20 ;40us
jc receive_a_erro_byte ;<80us 错误字节
clr C
mov A, New_Rcp
subb A, #78 ;156us
jnc receive_bit_one ;>160us 进行位1判断
mov A, Temp8 ;取0
rl A
mov Temp8, A
ajmp receive_a_byte_exit
receive_bit_one:
clr C
mov A, New_Rcp
subb A, #102 ;240us
jc receive_a_erro_byte ;160< New_Rcp <240us 错误字节
clr C
mov A, New_Rcp
subb A, #204 ;400us
jnc receive_a_erro_byte ;>400us 错误字节
mov A, Temp8 ;取1
rl A
inc A
mov Temp8, A
ajmp receive_a_byte_exit
receive_a_erro_byte:
setb Flags3.ERRO_DATA
receive_a_byte_exit:
jnb TF1, ($+7)
setb Flags3.ERRO_DATA
ajmp ($+6)
djnz Temp4, wait_high
mov Commu_Data_Buffer, Temp8
receive_exit:
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; 接收一组数据
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
receive_bytes:
mov Temp5, #48
mov Temp2, #Tag_Temporary_Storage ; Set RAM address
mov Commu_Data_Buffer, #0
wait_receive_bytes:
call receive_a_byte
mov @Temp2, Commu_Data_Buffer
inc Temp2
djnz Temp5, wait_receive_bytes
ret
store_tags:
; call store_tags
mov Temp2, #Tag_Temporary_Storage ; Set RAM address
mov Temp5, #48
store_tag:
cjne Temp5, #45, store_two
mov Temp1, #Pgm_Gov_Mode
jmp store_eep
store_two:
cjne Temp5, #44, store_three
mov Temp1, #Pgm_Low_Voltage_Lim
jmp store_eep
store_three:
cjne Temp5, #43, store_four
mov Temp1, #Pgm_Low_Voltage_Ctl
jmp store_eep
store_four:
cjne Temp5, #40, store_five
mov Temp1, #Pgm_Startup_Pwr
jmp store_eep
store_five:
cjne Temp5, #39, store_six
mov Temp1, #Pgm_Pwm_Freq
jmp store_eep
store_six:
cjne Temp5, #28, store_seven
mov Temp1, #Pgm_Comm_Timing
jmp store_eep
store_seven:
cjne Temp5, #27, store_next
mov Temp1, #Pgm_Damping_Force
store_eep:
mov Commu_Data_Buffer, @Temp2
;setb P1.7
mov @Temp1, Commu_Data_Buffer
call erase_and_store_all_in_eeprom
clr EA
store_next:
inc Temp2
djnz Temp5, store_tag
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; 发送一个数据(一个字节)
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
send_a_byte:
clr EA
setb TR0 ;启动T0
mov Temp4, #8
mov A, Commu_Data_Buffer ;读取要发送的数据
wait_send_a_byte:
setb P0.7 ;发送高电平
; mov A, Commu_Data_Buffer ;读取要发送的数据
jnb ACC.7, low_value ;($+8)
mov TL0, #067h ;发送1脉宽长
ajmp high_value ;($+5)
low_value:
mov TL0, #0CDh ;发送0脉宽长
high_value:
mov TH0, #0FFh
clr TF0 ;清T0溢出标志
jnb TF0, $ ;等待T0溢出 高电平发送完成
clr P0.7 ;发送低电平
mov TL0, #0CDh ;
mov TH0, #0FFh
clr TF0 ;清T0溢出标志
jnb TF0, $ ;等待T0溢出 低电平发送完成
rl A ;发送下一位
; mov Commu_Data_Buffer, A
djnz Temp4, wait_send_a_byte
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; 发送一组数据
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
send_bytes:
clr P0.7
; mov A, P0MDOUT
; orl A, #080h
mov P0MDOUT, #80h ;设置成推挽输出
mov Temp5, #48
; mov Temp2, #Tag_Temporary_Storage ; Set RAM address
mov Temp1, #Pgm_Fir_Key
wait_send_bytes:
mov Commu_Data_Buffer, @Temp1
inc Temp1
call send_a_byte ;逐个字节发送
djnz Temp5, wait_send_bytes
; mov A, P0MDOUT
; anl A, #07Fh
mov P0MDOUT, #7Fh ;设置成漏极输出
setb P0.7
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; 编程卡校验和
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
get_commu_buffers_sum:
mov Commu_Sum, #0
mov Temp5, #48
mov Temp2, #Tag_Temporary_Storage ; Set RAM address
wait_get_commu_buffers_sum:
mov A, @Temp2
clr C
addc A, Commu_Sum
mov Commu_Sum, A
inc Temp2
djnz Temp5, wait_get_commu_buffers_sum
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; 清零校验和
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
set_commu_sum_to_zero:
mov Temp8, #0
mov Temp5, #47
mov Temp2, #Tag_Temporary_Storage ; Set RAM address
wait_set_commu_sum_to_zero:
mov A, @Temp2
clr C
addc A, Temp8
mov Temp8, A
inc Temp2
djnz Temp5, wait_set_commu_sum_to_zero
cpl A
inc A
mov @Temp2, A ;写最后一个字节
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; 读取EEPROM参数
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;check_parameters:
; mov Temp5, #48 ; Number of tags
; mov Temp2, #Tag_Temporary_Storage ; Set RAM address
; mov Temp1, #Bit_Access
; mov DPTR, #Eep_ESC_Layout ; Set flash address
;read_eep:
; call read_eeprom_byte
; mov A, Bit_Access
; mov @Temp2, A ; Write to RAM
; inc Temp2
; inc DPTR
; djnz Temp5, read_eep
; call get_commu_buffers_sum
; mov A, Commu_Sum
; jnz set_parameters_default
;;读取首字节
; mov Temp2, #Tag_Temporary_Storage ; Set RAM address
; mov Temp1, #Bit_Access
; mov DPTR, #Eep_ESC_Layout ; Set flash address
; call read_eeprom_byte
; mov A, Bit_Access
; cjne A, #66h, set_parameters_default
;;设置默认参数
;set_parameters_default:
; mov Temp5, #48
; mov Temp2, #Tag_Temporary_Storage ; Set RAM address
; mov DPTR, #FINISH_KEYWORD_TABLE
;wait_set_parameters_default:
; clr A
; movc A, @A+DPTR
; mov @Temp2, A
; inc Temp2
; inc DPTR
; djnz Temp5, wait_set_parameters_default
; call set_commu_sum_to_zero
; ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; 编程卡编程函数
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
program_by_card:
; clr EA
mov Commu_Data_Buffer, #0
call wait10ms
clr Flags3.ERRO_DATA ;清错误字节标志
mov TL1, #00h
mov TH1, #00h
setb TR1 ; 启动T1
clr TF1 ;清T1溢出标志
call receive_a_byte ;读取一个字节(关键字)
jb Flags3.ERRO_DATA, program_by_card ;接收到错误字节,则重新接收
mov A, Commu_Data_Buffer ;读接收到的字节
cjne A, #05h, receive_next_keyword ;判断是否关键字 0x05
call wait3ms
call send_bytes
ljmp program_by_card
receive_next_keyword:
cjne A, #09h, program_by_card ;判断是否关键字 0x09
mov Commu_Data_Buffer, #0
mov TL1, #00h
mov TH1, #00h
setb TR1 ;启动T1
clr TF1 ;清T1溢出标志
call receive_bytes ;读取一组数据
call get_commu_buffers_sum
mov A, Commu_Sum ;读取校验和
jnz program_by_card ;判断校验和
mov Temp2, #Tag_Temporary_Storage ; Set RAM address
mov A, @Temp2 ;读取首字节
cjne A, #66h, program_by_card ;判断首字节
call wait1ms
clr P0.7
; mov A, P0MDOUT
; orl A, #080h ;设置成推挽输出
mov P0MDOUT, #080h
mov Commu_Data_Buffer, #088h
call send_a_byte ;逐个字节发送
; mov A, P0MDOUT
; anl A, #07Fh ;设置成漏极输出
mov P0MDOUT, #07Fh
setb P0.7
call store_tags ;存一组数据
; call erase_and_store_all_in_eeprom
; clr EA
;clr P1.7
ljmp program_by_card
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Beeper routines (4 different entry points)
;
; No assumptions
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
beep_f1: ; Entry point 1, load beeper frequency 1 settings
mov Temp3, #18 ; Off wait loop length
mov Temp4, #100 ; Number of beep pulses Mos开关次数
ajmp beep
beep_f2: ; Entry point 2, load beeper frequency 2 settings
mov Temp3, #14
mov Temp4, #120 ;Mos开关次数
ajmp beep
beep_f3: ; Entry point 3, load beeper frequency 3 settings
mov Temp3, #12
mov Temp4, #160 ;Mos开关次数
ajmp beep
beep_f4: ; Entry point 4, load beeper frequency 4 settings
mov Temp3, #9
mov Temp4, #180 ;Mos开关次数
ajmp beep
beep: ; Beep loop start
mov Temp5, Current_Pwm_Limited ; Store value
mov Current_Pwm_Limited, #1 ; Set to a nonzero value
mov Temp2, #2 ; Must be an even number (or direction will change)
beep_onoff:
cpl Flags3.PGM_DIR_REV ; Toggle between using A fet and C fet 切换A、C up导通
clr A
BpFET_off ; BpFET off
djnz ACC, $ ; Allow some time after pfet is turned off
BnFET_on ; BnFET on (in order to charge the driver of the BpFET)
djnz ACC, $ ; Let the nfet be turned on a while
BnFET_off ; BnFET off again
djnz ACC, $ ; Allow some time after nfet is turned off
BpFET_on ; BpFET on
djnz ACC, $ ; Allow some time after pfet is turned on
; Turn on nfet
AnFET_on ; AnFET on
mov A, Beep_Strength
djnz ACC, $
; Turn off nfet
AnFET_off ; AnFET off
mov A, #100 ; 25祍 off
djnz ACC, $
djnz Temp2, beep_onoff
; Copy variable
mov A, Temp3
mov Temp1, A
beep_off: ; Fets off loop
djnz ACC, $
djnz Temp1, beep_off
beep_recharge_done:
djnz Temp4, beep
BpFET_off ; BpFET off
mov Current_Pwm_Limited, Temp5 ; Restore value
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Division 16bit unsigned by 16bit unsigned
;
; Dividend shall be in Temp2/Temp1, divisor in Temp4/Temp3
; Result will be in Temp2/Temp1
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
div_u16_by_u16:
clr C
mov Temp5, #0
mov Temp6, #0
mov B, #0
div_u16_by_u16_div1:
inc B ; Increment counter for each left shift
mov A, Temp3 ; Shift left the divisor
rlc A
mov Temp3, A
mov A, Temp4
rlc A
mov Temp4, A
jnc div_u16_by_u16_div1 ; Repeat until carry flag is set from high-byte
div_u16_by_u16_div2:
mov A, Temp4 ; Shift right the divisor
rrc A
mov Temp4, A
mov A, Temp3
rrc A
mov Temp3, A
clr C
mov A, Temp2 ; Make a safe copy of the dividend
mov Temp8, A
mov A, Temp1
mov Temp7, A
mov A, Temp1 ; Move low-byte of dividend into accumulator
subb A, Temp3 ; Dividend - shifted divisor = result bit (no factor, only 0 or 1)
mov Temp1, A ; Save updated dividend
mov A, Temp2 ; Move high-byte of dividend into accumulator
subb A, Temp4 ; Subtract high-byte of divisor (all together 16-bit substraction)
mov Temp2, A ; Save updated high-byte back in high-byte of divisor
jnc div_u16_by_u16_div3 ; If carry flag is NOT set, result is 1
mov A, Temp8 ; Otherwise result is 0, save copy of divisor to undo subtraction
mov Temp2, A
mov A, Temp7
mov Temp1, A
div_u16_by_u16_div3:
cpl C ; Invert carry, so it can be directly copied into result
mov A, Temp5
rlc A ; Shift carry flag into temporary result
mov Temp5, A
mov A, Temp6
rlc A
mov Temp6,A
djnz B, div_u16_by_u16_div2 ;Now count backwards and repeat until "B" is zero
mov A, Temp6 ; Move result to Temp2/Temp1
mov Temp2, A
mov A, Temp5
mov Temp1, A
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Multiplication 16bit signed by 8bit unsigned
;
; Multiplicand shall be in Temp2/Temp1, multiplicator in Temp3
; Result will be in Temp2/Temp1. Result will divided by 16
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
mult_s16_by_u8_div_16:
mov A, Temp1 ; Read input to math registers
mov B, Temp2
mov Bit_Access, Temp3
setb PSW.4 ; Select register bank 2 for math routines
mov Temp1, A ; Store in math registers
mov Temp2, B
mov Temp4, #0 ; Set sign in Temp4 and test sign
jnb B.7, mult_s16_by_u8_positive
mov Temp4, #0FFh
cpl A
add A, #1
mov Temp1, A
mov A, Temp2
cpl A
addc A, #0
mov Temp2, A
mult_s16_by_u8_positive:
mov A, Temp1 ; Multiply LSB with multiplicator
mov B, Bit_Access
mul AB
mov Temp6, B ; Place MSB in Temp6
mov Temp1, A ; Place LSB in Temp1 (result)
mov A, Temp2 ; Multiply MSB with multiplicator
mov B, Bit_Access
mul AB
mov Temp8, B ; Place in Temp8/7
mov Temp7, A
mov A, Temp6 ; Add up
add A, Temp7
mov Temp2, A
mov A, #0
addc A, Temp8
mov Temp3, A
mov Temp5, #4 ; Set number of divisions
mult_s16_by_u8_div_loop:
clr C ; Rotate right
mov A, Temp3
rrc A
mov Temp3, A
mov A, Temp2
rrc A
mov Temp2, A
mov A, Temp1
rrc A
mov Temp1, A
djnz Temp5, mult_s16_by_u8_div_loop
mov B, Temp4 ; Test sign
jnb B.7, mult_s16_by_u8_exit
mov A, Temp1
cpl A
add A, #1
mov Temp1, A
mov A, Temp2
cpl A
addc A, #0
mov Temp2, A
mult_s16_by_u8_exit:
mov A, Temp1 ; Store output
mov B, Temp2
clr PSW.4 ; Select normal register bank
mov Temp1, A
mov Temp2, B
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Calculate governor routines
;
; No assumptions
;
; Governs headspeed based upon the Comm_Period4x variable and pwm
; The governor task is split into several routines in order to distribute processing time
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
; First governor routine - calculate governor target
IF MODE <= 1 ; Main or tail
calc_governor_target:
mov Temp1, #Pgm_Gov_Mode ; Governor mode?
cjne @Temp1, #4, governor_speed_check ; Yes
jmp calc_governor_target_exit ; No
governor_speed_check:
; Stop governor for stop RC pulse
clr C
mov A, New_Rcp ; Check RC pulse against stop value
subb A, #RCP_STOP ; Is pulse below stop value?
jc governor_deactivate ; Yes - deactivate
; Skip speed check if governor is alrady active
mov A, Gov_Active
jnz governor_target_calc
; Check speed (do not run governor for low speeds)
mov Temp1, #05h ; Default high range activation limit value (~62500 eRPM)
clr C
mov Temp2, #Pgm_Gov_Range
cjne @Temp2, #2, ($+5)
mov Temp1, #12h ; Low range activation limit value (~17400 eRPM)
clr C
mov A, Comm_Period4x_L
subb A, #00h
mov A, Comm_Period4x_H
subb A, Temp1
jc governor_activate ; If speed above min limit - run governor
governor_deactivate:
mov Current_Pwm, Requested_Pwm ; Set current pwm to requested
clr A
mov Gov_Target_L, A ; Set target to zero
mov Gov_Target_H, A
mov Gov_Integral_L, A ; Set integral to zero
mov Gov_Integral_H, A
mov Gov_Integral_X, A
mov Gov_Active, A
jmp calc_governor_target_exit
governor_activate:
mov Gov_Active, #1
governor_target_calc:
; Governor calculations
clr C
mov Temp2, #Pgm_Gov_Range
mov A, @Temp2 ; Check high or low range (Temp2 has #Pgm_Gov_Range)
subb A, #2
jz calc_governor_target_low
mov A, Governor_Req_Pwm ; Load governor requested pwm
cpl A ; Calculate 255-pwm (invert pwm)
; Calculate comm period target (1 + 2*((255-Requested_Pwm)/256) - 0.25)
rlc A ; Msb to carry
rlc A ; To bit0
mov Temp2, A ; Now 1 lsb is valid for H
rrc A
mov Temp1, A ; Now 7 msbs are valid for L
mov A, Temp2
anl A, #01h ; Calculate H byte
inc A ; Add 1
mov Temp2, A
mov A, Temp1
anl A, #0FEh ; Calculate L byte
clr C
subb A, #40h ; Subtract 0.25
mov Temp1, A
mov A, Temp2
subb A, #0
mov Temp2, A
jmp calc_governor_store_target
calc_governor_target_low:
mov A, Governor_Req_Pwm ; Load governor requested pwm
cpl A ; Calculate 255-pwm (invert pwm)
; Calculate comm period target (2 + 8*((255-Requested_Pwm)/256) - 0.25)
rlc A ; Msb to carry
rlc A ; To bit0
rlc A ; To bit1
rlc A ; To bit2
mov Temp2, A ; Now 3 lsbs are valid for H
rrc A
mov Temp1, A ; Now 4 msbs are valid for L
mov A, Temp2
anl A, #07h ; Calculate H byte
inc A ; Add 1
inc A ; Add 1 more
mov Temp2, A
mov A, Temp1
anl A, #0F8h ; Calculate L byte
clr C
subb A, #40h ; Subtract 0.25
mov Temp1, A
mov A, Temp2
subb A, #0
mov Temp2, A
calc_governor_store_target:
; Store governor target
mov Gov_Target_L, Temp1
mov Gov_Target_H, Temp2
calc_governor_target_exit:
ret
ENDIF
IF MODE == 2 ; Multi
calc_governor_target:
;读取 Closed loop mode
mov Temp1, #Pgm_Gov_Mode ; Closed loop mode?
cjne @Temp1, #1, governor_target_calc ; Yes - branch
;Closed loop mode = 第4项 Off
jmp calc_governor_target_exit ; No
governor_target_calc:
; Stop governor for stop RC pulse
clr C
mov A, New_Rcp ; Check RC pulse against stop value
subb A, #RCP_STOP ; Is pulse below stop value?
jc governor_deactivate ; Yes - deactivate
jmp governor_activate ; No - activate
governor_deactivate:
mov Current_Pwm, Requested_Pwm ; Set current pwm to requested
clr A
mov Gov_Target_L, A ; Set target to zero
mov Gov_Target_H, A
mov Gov_Integral_L, A ; Set integral to zero
mov Gov_Integral_H, A
mov Gov_Integral_X, A
mov Gov_Active, A
jmp calc_governor_target_exit
governor_activate:
mov Temp1, #Pgm_Gov_Mode ; Store gov mode
mov A, @Temp1
mov Temp5, A
mov Gov_Active, #1
mov A, Requested_Pwm ; Load requested pwm
mov Governor_Req_Pwm, A ; Set governor requested pwm
; Calculate comm period target 2*(51000/Requested_Pwm)
mov Temp1, #38h ; Load 51000
mov Temp2, #0C7h
mov Temp3, Comm_Period4x_L ; Load comm period
mov Temp4, Comm_Period4x_H
; Set speed range. Bare Comm_Period4x corresponds to 400k rpm, because it is 500n units
;Closed loop mode = 第1项 HiRange
clr C
mov A, Temp4
rrc A
mov Temp4, A
mov A, Temp3
rrc A
mov Temp3, A ; 200k eRPM range here
; Check range
mov A, Temp5
dec A
dec A
dec A
dec A
jz governor_activate_range_set ; 200k eRPM? - branch
;Closed loop mode = 第2项 MidRange
governor_activate_100k:
clr C
mov A, Temp4
rrc A
mov Temp4, A
mov A, Temp3
rrc A
mov Temp3, A ; 100k eRPM range here
mov A, Temp5 ; Check range again
dec A
dec A
dec A
jz governor_activate_range_set ; 100k eRPM? - branch
;Closed loop mode = 第3项 LoRange
governor_activate_50k:
clr C
mov A, Temp4
rrc A
mov Temp4, A
mov A, Temp3
rrc A
mov Temp3, A ; 50k eRPM range here
governor_activate_range_set:
call div_u16_by_u16
; Store governor target
mov Gov_Target_L, Temp1
mov Gov_Target_H, Temp2
calc_governor_target_exit:
ret
ENDIF
; Second governor routine - calculate governor proportional error
calc_governor_prop_error:
; Exit if governor is inactive
mov A, Gov_Active
jz calc_governor_prop_error_exit
IF MODE <= 1 ; Main or tail
; Load comm period and divide by 2
clr C
mov A, Comm_Period4x_H
rrc A
mov Temp2, A
mov A, Comm_Period4x_L
rrc A
mov Temp1, A
; Calculate error
clr C
mov A, Gov_Target_L
subb A, Temp1
mov Temp1, A
mov A, Gov_Target_H
subb A, Temp2
mov Temp2, A
ENDIF
IF MODE == 2 ; Multi
; Calculate error
clr C
mov A, Gov_Target_L
subb A, Governor_Req_Pwm
mov Temp1, A
mov A, Gov_Target_H
subb A, #0
mov Temp2, A
ENDIF
; Check error and limit
jnc governor_check_prop_limit_pos ; Check carry
clr C
mov A, Temp1
subb A, #80h ; Is error too negative?
mov A, Temp2
subb A, #0FFh
jc governor_limit_prop_error_neg ; Yes - limit
jmp governor_store_prop_error
governor_check_prop_limit_pos:
clr C
mov A, Temp1
subb A, #7Fh ; Is error too positive?
mov A, Temp2
subb A, #00h
jnc governor_limit_prop_error_pos ; Yes - limit
jmp governor_store_prop_error
governor_limit_prop_error_pos:
mov Temp1, #7Fh ; Limit to max positive (2's complement)
mov Temp2, #00h
jmp governor_store_prop_error
governor_limit_prop_error_neg:
mov Temp1, #80h ; Limit to max negative (2's complement)
mov Temp2, #0FFh
governor_store_prop_error:
; Store proportional
mov Gov_Proportional_L, Temp1
mov Gov_Proportional_H, Temp2
calc_governor_prop_error_exit:
ret
; Third governor routine - calculate governor integral error
calc_governor_int_error:
; Exit if governor is inactive
mov A, Gov_Active
jz calc_governor_int_error_exit
; Add proportional to integral
mov A, Gov_Proportional_L
add A, Gov_Integral_L
mov Temp1, A
mov A, Gov_Proportional_H
addc A, Gov_Integral_H
mov Temp2, A
mov Bit_Access, Gov_Proportional_H ; Sign extend high byte
clr A
jnb Bit_Access.7, ($+4)
cpl A
addc A, Gov_Integral_X
mov Temp3, A
; Check integral and limit
jnb ACC.7, governor_check_int_limit_pos ; Check sign bit
clr C
mov A, Temp3
subb A, #0F0h ; Is error too negative?
jc governor_limit_int_error_neg ; Yes - limit
jmp governor_check_pwm
governor_check_int_limit_pos:
clr C
mov A, Temp3
subb A, #0Fh ; Is error too positive?
jnc governor_limit_int_error_pos ; Yes - limit
jmp governor_check_pwm
governor_limit_int_error_pos:
mov Temp1, #0FFh ; Limit to max positive (2's complement)
mov Temp2, #0FFh
mov Temp3, #0Fh
jmp governor_check_pwm
governor_limit_int_error_neg:
mov Temp1, #00h ; Limit to max negative (2's complement)
mov Temp2, #00h
mov Temp3, #0F0h
governor_check_pwm:
; Check current pwm
clr C
mov A, Current_Pwm
subb A, Pwm_Limit ; Is current pwm at or above pwm limit?
jnc governor_int_max_pwm ; Yes - branch
mov A, Current_Pwm ; Is current pwm at zero?
jz governor_int_min_pwm ; Yes - branch
ajmp governor_store_int_error ; No - store integral error
governor_int_max_pwm:
mov A, Gov_Proportional_H
jb ACC.7, calc_governor_int_error_exit ; Is proportional error negative - branch (high byte is always zero)
ajmp governor_store_int_error ; Positive - store integral error
governor_int_min_pwm:
mov A, Gov_Proportional_H
jnb ACC.7, calc_governor_int_error_exit ; Is proportional error positive - branch (high byte is always zero)
governor_store_int_error:
; Store integral
mov Gov_Integral_L, Temp1
mov Gov_Integral_H, Temp2
mov Gov_Integral_X, Temp3
calc_governor_int_error_exit:
ret
; Fourth governor routine - calculate governor proportional correction
calc_governor_prop_correction:
; Exit if governor is inactive
mov A, Gov_Active
jnz calc_governor_prop_corr
jmp calc_governor_prop_corr_exit
calc_governor_prop_corr:
; Load proportional gain
mov Temp1, #Pgm_Gov_P_Gain_Decoded; Load proportional gain
mov A, @Temp1
mov Temp3, A ; Store in Temp3
; Load proportional
clr C
mov A, Gov_Proportional_L ; Nominal multiply by 2
rlc A
mov Temp1, A
mov A, Gov_Proportional_H
rlc A
mov Temp2, A
; Apply gain
call mult_s16_by_u8_div_16
; Check error and limit (to low byte)
mov A, Temp2
jnb ACC.7, governor_check_prop_corr_limit_pos ; Check sign bit
clr C
mov A, Temp1
subb A, #80h ; Is error too negative?
mov A, Temp2
subb A, #0FFh
jc governor_limit_prop_corr_neg ; Yes - limit
ajmp governor_apply_prop_corr
governor_check_prop_corr_limit_pos:
clr C
mov A, Temp1
subb A, #7Fh ; Is error too positive?
mov A, Temp2
subb A, #00h
jnc governor_limit_prop_corr_pos ; Yes - limit
ajmp governor_apply_prop_corr
governor_limit_prop_corr_pos:
mov Temp1, #7Fh ; Limit to max positive (2's complement)
mov Temp2, #00h
ajmp governor_apply_prop_corr
governor_limit_prop_corr_neg:
mov Temp1, #80h ; Limit to max negative (2's complement)
mov Temp2, #0FFh
governor_apply_prop_corr:
; Test proportional sign
mov A, Temp1
jb ACC.7, governor_corr_neg_prop ; If proportional negative - go to correct negative
; Subtract positive proportional
clr C
mov A, Governor_Req_Pwm
subb A, Temp1
mov Temp1, A
; Check result
jc governor_corr_prop_min_pwm ; Is result negative?
clr C
mov A, Temp1 ; Is result below pwm min?
subb A, #1
jc governor_corr_prop_min_pwm ; Yes
jmp governor_store_prop_corr ; No - store proportional correction
governor_corr_prop_min_pwm:
mov Temp1, #1 ; Load minimum pwm
jmp governor_store_prop_corr
governor_corr_neg_prop:
; Add negative proportional
mov A, Temp1
cpl A
add A, #1
add A, Governor_Req_Pwm
mov Temp1, A
; Check result
jc governor_corr_prop_max_pwm ; Is result above max?
jmp governor_store_prop_corr ; No - store proportional correction
governor_corr_prop_max_pwm:
mov Temp1, #255 ; Load maximum pwm
governor_store_prop_corr:
; Store proportional pwm
mov Gov_Prop_Pwm, Temp1
calc_governor_prop_corr_exit:
ret
; Fifth governor routine - calculate governor integral correction
calc_governor_int_correction:
; Exit if governor is inactive
mov A, Gov_Active
jnz calc_governor_int_corr
jmp calc_governor_int_corr_exit
calc_governor_int_corr:
; Load integral gain
mov Temp1, #Pgm_Gov_I_Gain_Decoded; Load integral gain
mov A, @Temp1
mov Temp3, A ; Store in Temp3
; Load integral
mov Temp1, Gov_Integral_H
mov Temp2, Gov_Integral_X
; Apply gain
call mult_s16_by_u8_div_16
; Check integral and limit
mov A, Temp2
jnb ACC.7, governor_check_int_corr_limit_pos ; Check sign bit
clr C
mov A, Temp1
subb A, #01h ; Is integral too negative?
mov A, Temp2
subb A, #0FFh
jc governor_limit_int_corr_neg ; Yes - limit
jmp governor_apply_int_corr
governor_check_int_corr_limit_pos:
clr C
mov A, Temp1
subb A, #0FFh ; Is integral too positive?
mov A, Temp2
subb A, #00h
jnc governor_limit_int_corr_pos ; Yes - limit
jmp governor_apply_int_corr
governor_limit_int_corr_pos:
mov Temp1, #0FFh ; Limit to max positive (2's complement)
mov Temp2, #00h
jmp governor_apply_int_corr
governor_limit_int_corr_neg:
mov Temp1, #01h ; Limit to max negative (2's complement)
mov Temp2, #0FFh
governor_apply_int_corr:
; Test integral sign
mov A, Temp2
jb ACC.7, governor_corr_neg_int ; If integral negative - go to correct negative
; Subtract positive integral
clr C
mov A, Gov_Prop_Pwm
subb A, Temp1
mov Temp1, A
; Check result
jc governor_corr_int_min_pwm ; Is result negative?
clr C
mov A, Temp1 ; Is result below pwm min?
subb A, #1
jc governor_corr_int_min_pwm ; Yes
jmp governor_store_int_corr ; No - store correction
governor_corr_int_min_pwm:
mov Temp1, #0 ; Load minimum pwm
jmp governor_store_int_corr
governor_corr_neg_int:
; Add negative integral
mov A, Temp1
cpl A
add A, #1
add A, Gov_Prop_Pwm
mov Temp1, A
; Check result
jc governor_corr_int_max_pwm ; Is result above max?
jmp governor_store_int_corr ; No - store correction
governor_corr_int_max_pwm:
mov Temp1, #255 ; Load maximum pwm
governor_store_int_corr:
; Store current pwm
mov Current_Pwm, Temp1
calc_governor_int_corr_exit:
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Measure lipo cells
;
; No assumptions
;
; Measure voltage and calculate lipo cells
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
measure_lipo_cells:
IF MODE == 1 ; Tail
; If tail, then exit
jmp measure_lipo_exit
ENDIF
measure_lipo_start:
; Load programmed low voltage limit
;读取Low voltage limit
mov Lipo_Cell_Count, #0 ;2013.8.23 防止接收机拿掉后再接上时,电池检测出错
mov Temp1, #Pgm_Low_Voltage_Lim ; Load limit
mov A, @Temp1
mov Bit_Access, A ; Store in Bit_Access
; Set commutation to BpFET on
; call comm5comm6
CnFET_off ; Cn off
BnFET_on ; Bn on
Set_Comp_Phase_C ; Set comparator to phase C
mov Comm_Phase, #6
; Start adc
Start_Adc
; Wait for ADC conversion to complete
Get_Adc_Status
jb AD0BUSY, measure_lipo_cells
; Read ADC result
Read_Adc_Result
; Stop ADC
Stop_Adc
; Switch power off
call switch_power_off
; Set limit step
mov Lipo_Adc_Limit_L, #ADC_LIMIT_L
mov Lipo_Adc_Limit_H, #ADC_LIMIT_H
clr C
mov A, #ADC_LIMIT_H ; Divide 2.8V value by 2
rrc A
mov Temp6, A
mov A, #ADC_LIMIT_L
rrc A
mov Temp5, A
mov A, #ADC_LIMIT_L ; Calculate 1.4+2.8V=4.2V value
add A, Temp5
add A, #3 ;加宽一节电池电压范围 4.3V 2013.8.16
mov Temp5, A
mov A, #ADC_LIMIT_H
addc A, Temp6
mov Temp6, A
mov A, Temp5 ; Copy step
mov Temp3, A
mov A, Temp6
mov Temp4, A
;***************************************************
; Lipo节数检测
;***************************************************
measure_lipo_cell_loop:
; Check voltage against xS lower limit
inc Lipo_Cell_Count ;增加电池节数累加 2013.5.29
clr C
mov A, Temp1
subb A, Temp3 ; Voltage above limit?
mov A, Temp2
subb A, Temp4
jc measure_lipo_adjust ; No - branch 读取到电压范围
; Set xS voltage limit
mov A, Lipo_Adc_Limit_L
add A, #ADC_LIMIT_L
mov Lipo_Adc_Limit_L, A
mov A, Lipo_Adc_Limit_H
addc A, #ADC_LIMIT_H
mov Lipo_Adc_Limit_H, A
; Set (x+1)S lower limit
mov A, Temp3
add A, Temp5 ; Add step
mov Temp3, A
mov A, Temp4
addc A, Temp6
mov Temp4, A
jmp measure_lipo_cell_loop ; Check for one more battery cell
measure_lipo_adjust:
mov Temp7, Lipo_Adc_Limit_L
mov Temp8, Lipo_Adc_Limit_H
; Calculate 3.125%
clr C
mov A, Lipo_Adc_Limit_H
rrc A
mov Temp2, A
mov A, Lipo_Adc_Limit_L
rrc A
mov Temp1, A ; After this 50%
clr C
mov A, Temp2
rrc A
mov Temp2, A
mov A, Temp1
rrc A
mov Temp1, A ; After this 25%
; mov A, Lipo_Adc_Limit_L ; Set adc reference for voltage compensation
; add A, Temp1 ;低压低字节+低压低字节偏移量
; mov Lipo_Adc_Reference_L, A ;存低压低字节
; mov A, Lipo_Adc_Limit_H
; addc A, Temp2 ;低压高字节+低压高字节偏移量
; mov Lipo_Adc_Reference_H, A ;存低压高字节
; ; Divide three times to get to 3.125% 6.25% 2013.5.30
mov Temp3, #2 ;3
measure_lipo_divide_loop:
clr C
mov A, Temp2
rrc A
mov Temp2, A
mov A, Temp1
rrc A
mov Temp1, A
djnz Temp3, measure_lipo_divide_loop
; Add the programmed number of 0.1V (or 3.125% increments)
mov Temp3, Bit_Access ; Load programmed limit (Bit_Access has Pgm_Low_Voltage_Lim)
; dec Temp3
; mov A,Temp3 ;增加判断指令,如果没有这条指令能判断????
; jnz measure_lipo_limit_on ; Is low voltage limiting on?
cjne Temp3, #4, measure_lipo_limit_on
mov Lipo_Adc_Limit_L, #0 ; No - set limit to zero
mov Lipo_Adc_Limit_H, #0
jmp measure_lipo_exit
measure_lipo_limit_on:
dec Temp3
mov A, Temp3
jz measure_lipo_update
;Bit_Access>2时,低压保护值=基值+偏移量
;Low voltage limit > 第2项时
measure_lipo_add_loop:
clr C
mov A, Temp7 ; Add 3.125%
add A, Temp1
mov Temp7, A
mov A, Temp8
addc A, Temp2
mov Temp8, A
; clr C
; mov A, Temp7 ; Add 3.125%
; add A, Temp1
; mov Temp7, A
; mov A, Temp8
; addc A, Temp2
; mov Temp8, A
djnz Temp3, measure_lipo_add_loop
;存低压保护值
;Low voltage limit = 第2项 3.0V
measure_lipo_update:
; Set ADC limit
mov Lipo_Adc_Limit_L, Temp7
mov Lipo_Adc_Limit_H, Temp8
measure_lipo_exit:
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Start ADC conversion
;
; No assumptions
;
; Start conversion used for measuring power supply voltage
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
start_adc_conversion:
; Start adc
Start_Adc
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Check temperature, power supply voltage and limit power
;
; No assumptions
;
; Used to limit main motor power in order to maintain the required voltage
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
check_temp_voltage_and_limit_power:
; Load programmed low voltage limit
mov Temp1, #Pgm_Low_Voltage_Lim ;读低压保护选项
mov A, @Temp1
mov Temp8, A ; Store in Temp8
; Wait for ADC conversion to complete
Get_Adc_Status
jb AD0BUSY, check_temp_voltage_and_limit_power
; Read ADC result
Read_Adc_Result ;读AD值
; Stop ADC
Stop_Adc ;禁止AD转换
inc Adc_Conversion_Cnt ; Increment conversion counter
clr C
mov A, Adc_Conversion_Cnt ; Is conversion count equal to temp rate?
subb A, #TEMP_CHECK_RATE
jc check_voltage_start ; No - check voltage AD转换次数 < 8次 ?
mov Adc_Conversion_Cnt, #0 ; Yes - temperature check. Reset counter
mov A, Temp2 ; Is temperature reading below 256?
jnz temp_average_inc_dec ; No - proceed
mov A, Current_Average_Temp ; Yes - decrement average
jz temp_average_updated ; Already zero - no change
jmp temp_average_dec ; Decrement
temp_average_inc_dec:
clr C
mov A, Temp1 ; Check if current temperature is above or below average
subb A, Current_Average_Temp
jz temp_average_updated_load_acc ; Equal - no change
mov A, Current_Average_Temp ; Above - increment average
jnc temp_average_inc
jz temp_average_updated ; Below - decrement average if average is not already zero
temp_average_dec:
dec A ; Decrement average
jmp temp_average_updated
temp_average_inc:
inc A ; Increment average
jz temp_average_dec
jmp temp_average_updated
temp_average_updated_load_acc:
mov A, Current_Average_Temp
temp_average_updated:
mov Current_Average_Temp, A
clr C
subb A, #TEMP_LIMIT ; Is temperature below first limit?
mov Temp1, A
jc temp_check_exit ; Yes - exit
mov Pwm_Limit, #192 ; No - limit pwm
clr C
mov A, Temp1 ; Is temperature below second limit
subb A, #TEMP_LIMIT_STEP
mov Temp1, A
jc temp_check_exit ; Yes - exit
mov Pwm_Limit, #128 ; No - limit pwm
clr C
mov A, Temp1 ; Is temperature below third limit
subb A, #TEMP_LIMIT_STEP
mov Temp1, A
jc temp_check_exit ; Yes - exit
mov Pwm_Limit, #64 ; No - limit pwm
clr C
mov A, Temp1 ; Is temperature below final limit
subb A, #TEMP_LIMIT_STEP
mov Temp1, A
jc temp_check_exit ; Yes - exit
mov Pwm_Limit, #16 ; No - limit pwm 2013.8.5最高温度时速度由0改成16
temp_check_exit:
Set_Adc_Ip_Volt ; Select adc input for next conversion
ret
check_voltage_start:
IF MODE == 0 OR MODE == 2 ; Main or multi
; Check if low voltage limiting is enabled
mov A, Temp8
clr C
subb A, #4 ; Is low voltage limit disabled?
jz check_voltage_good ; Yes - voltage declared good
; Check if ADC is saturated
clr C
mov A, Temp1 ;读取AD值低字节
subb A, #0FFh
mov A, Temp2 ;读取AD值高字节
subb A, #03h ;判断AD是否超出10位AD范围
jnc check_voltage_good ; ADC saturated, can not make judgement
; Check voltage against limit
clr C
mov A, Temp1
subb A, Lipo_Adc_Limit_L
mov A, Temp2
subb A, Lipo_Adc_Limit_H
jnc check_voltage_good ; If voltage above limit - branch 电压值 > 低压设置值
mov Temp1, #Pgm_Low_Voltage_Ctl ;读低压保护控制方式选项
mov A, @Temp1
clr C
subb A, #1 ;
jz check_voltage_next_way
mov A, Pwm_Limit
subb A, #5
jnc check_limit_count
setb LOW_LIMIT_STOP ;设置低压保护控制方式2 低压停止标志
ljmp run_to_wait_for_power_on
check_voltage_next_way:
; Decrease pwm limit
mov A, Pwm_Limit
subb A, #80 ;更改低压保护方式 2013.05.31
;////// jz check_voltage_lim ; If limit zero - branch
jc check_voltage_lim ; If limit <100 - branch
check_limit_count:
mov A, Limit_Count
jz ($+6)
dec Limit_Count ;递减低压保护变量 2013.7.5
ajmp check_voltage_lim
mov Limit_Count, #5 ; 2013.7.5
dec Pwm_Limit ; Decrement limit
jmp check_voltage_lim
;Low voltage limit = 第1项
check_voltage_good:
; Increase pwm limit
mov Limit_Count, #5 ; 2013.7.5
mov A, Pwm_Limit
cpl A
jz check_voltage_lim ; If limit max - branch
inc Pwm_Limit ; Increment limit
check_voltage_lim:
mov Temp1, Pwm_Limit ; Set limit
clr C
mov A, Current_Pwm
subb A, Temp1
jnc check_voltage_spoolup_lim ; If current pwm above limit - branch and limit
mov Temp1, Current_Pwm ; Set current pwm (no limiting)
check_voltage_spoolup_lim:
mov Current_Pwm_Limited, Temp1 ;取小值
; Slow spoolup
clr C
mov A, Current_Pwm_Limited
subb A, Pwm_Limit_Spoolup
jc check_voltage_exit ; If current pwm below limit - branch
mov Current_Pwm_Limited, Pwm_Limit_Spoolup ;取小值
mov A, Pwm_Limit_Spoolup ; Check if spoolup limit is max
cpl A
jz check_voltage_exit ; If max - branch
mov Pwm_Limit, Pwm_Limit_Spoolup ; Set pwm limit to spoolup limit during ramp (to avoid governor integral buildup)
check_voltage_exit:
ENDIF
; Set adc mux for next conversion
clr C
mov A, Adc_Conversion_Cnt ; Is next conversion for temperature?
cjne A, #(TEMP_CHECK_RATE-1), ($+6)
Set_Adc_Ip_Temp ; Select temp sensor for next conversion
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Set startup PWM routine
;
; No assumptions
;
; Used for pwm control during startup
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
set_startup_pwm:
; Set pwm values according to startup phase flags
jnb Flags1.SETTLE_PHASE, ($+5) ; Is it motor start settle phase? 是否启动定位?
mov Temp1, #PWM_SETTLE ; Yes - set settle power
jnb Flags1.STEPPER_PHASE, ($+5) ; Is it motor start stepper phase? 是否步进启动?
mov Temp1, #PWM_STEPPER ; Yes - set stepper power
; Update pwm variables if any startup phase flag is set
mov A, Flags1
anl A, #((1 SHL SETTLE_PHASE)+(1 SHL STEPPER_PHASE))
jz startup_pwm_exit ; If no startup phase set - exit
; Adjust startup power
mov A, Temp1 ; Multiply startup power by programmed value
mov Temp2, #Pgm_Startup_Pwr_Decoded
mov B, @Temp2
mul AB
xch A, B
mov C, B.7 ; Multiply result by 2 (unity gain is 128)
rlc A
mov Temp1, A ; Transfer to Temp1
clr C
mov A, Temp1 ; Check against limit
subb A, Pwm_Limit
jc startup_pwm_set_pwm ; If pwm below limit - branch
mov Temp1, Pwm_Limit ; Limit pwm
startup_pwm_set_pwm:
; Set pwm variables
mov Requested_Pwm, Temp1 ; Update requested pwm
mov Current_Pwm, Temp1 ; Update current pwm
mov Current_Pwm_Limited, Temp1 ; Update limited version of current pwm
jnb Flags1.SETTLE_PHASE, startup_pwm_exit ; Is it motor start settle phase?
clr C ; Yes - update spoolup beginning pwm (will use PWM_SETTLE or PWM_SETTLE/2)
mov A, Temp1
mov Pwm_Spoolup_Beg, A
startup_pwm_exit:
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Initialize all timings routine
;
; No assumptions
;
; Part of initialization before motor start
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
initialize_all_timings:
; Load programmed startup rpm
;读取Startup rpm
; mov Temp1, #Pgm_Startup_Rpm ; Load startup rpm
; mov A, @Temp1
; mov Temp8, A ; Store in Temp8
; Check startup rpm setting and set step accordingly
; clr C
; mov A, Temp8
; subb A, #5
; jnc stepper_step_high
; clr C
; mov A, Temp8
; subb A, #4
; jnc stepper_step_med_high
; clr C
; mov A, Temp8
; subb A, #3
; jnc stepper_step_med
; clr C
; mov A, Temp8
; subb A, #2
; jnc stepper_step_med_low
; clr C
; mov A, Temp8
; subb A, #1
; jnc stepper_step_low
;Startup_Rpm = 第5项
;stepper_step_high:
; mov Stepper_Step_Beg_L, #low(2000 SHL 1)
; mov Stepper_Step_Beg_H, #high(2000 SHL 1)
; mov Stepper_Step_End_L, #low(670 SHL 1)
; mov Stepper_Step_End_H, #high(670 SHL 1)
; ajmp stepper_step_set
;Startup_Rpm = 第4项
;stepper_step_med_high:
; mov Stepper_Step_Beg_L, #low(2400 SHL 1)
; mov Stepper_Step_Beg_H, #high(2400 SHL 1)
; mov Stepper_Step_End_L, #low(800 SHL 1)
; mov Stepper_Step_End_H, #high(800 SHL 1)
; ajmp stepper_step_set
;Startup_Rpm = 第3项
;stepper_step_med:
; mov Stepper_Step_Beg_L, #low(3000 SHL 1) ; ~3300 eRPM
; mov Stepper_Step_Beg_H, #high(3000 SHL 1)
; mov Stepper_Step_End_L, #low(1000 SHL 1) ; ~10000 eRPM
; mov Stepper_Step_End_H, #high(1000 SHL 1)
; ajmp stepper_step_set
;Startup_Rpm = 第2项
;stepper_step_med_low:
; mov Stepper_Step_Beg_L, #low(3750 SHL 1)
; mov Stepper_Step_Beg_H, #high(3750 SHL 1)
; mov Stepper_Step_End_L, #low(1250 SHL 1)
; mov Stepper_Step_End_H, #high(1250 SHL 1)
; ajmp stepper_step_set
;Startup_Rpm = 第1项
;stepper_step_low:
; mov Stepper_Step_Beg_L, #low(4500 SHL 1)
; mov Stepper_Step_Beg_H, #high(4500 SHL 1)
; mov Stepper_Step_End_L, #low(1500 SHL 1)
; mov Stepper_Step_End_H, #high(1500 SHL 1)
; ajmp stepper_step_set
;stepper_step_set:
; mov Wt_Stepper_Step_L, Stepper_Step_Beg_L ; Initialize stepper step time
; mov Wt_Stepper_Step_H, Stepper_Step_Beg_H
mov Comm_Period4x_L, #00h ; Set commutation period registers
mov Comm_Period4x_H, #08h
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Calculate next commutation timing routine
;
; No assumptions
;
; Called immediately after each commutation
; Also sets up timer 1 to wait advance timing
; Two entry points are used
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;calc_next_comm_timing_start: ; Entry point for startup
; mov Temp1, Wt_Stepper_Step_L ; Set up stepper step wait
; mov Temp2, Wt_Stepper_Step_H
; jmp read_timer
calc_next_comm_timing: ; Entry point for run phase
mov Temp1, Wt_Advance_L ; Set up advance timing wait
mov Temp2, Wt_Advance_H
read_timer:
; Set up next wait
mov TMR3CN, #00h ; Timer3 disabled
clr C
clr A
subb A, Temp1 ; Set wait to zero cross scan value
mov TMR3L, A
clr A
subb A, Temp2
mov TMR3H, A
mov TMR3CN, #04h ; Timer3 enabled
setb Flags0.T3_PENDING
; Read commutation time
mov TMR2CN, #20h ; Timer2 disabled
mov Temp1, TMR2L ; Load timer value
mov Temp2, TMR2H
mov TMR2CN, #24h ; Timer2 enabled
; Calculate this commutation time
mov Temp3, Prev_Comm_L
mov Temp4, Prev_Comm_H
mov Prev_Comm_L, Temp1 ; Store timestamp as previous commutation
mov Prev_Comm_H, Temp2
clr C
mov A, Temp1
subb A, Temp3 ; Calculate the new commutation time
mov Temp1, A
mov A, Temp2
subb A, Temp4
mov Temp2, A
; Calculate next zero cross scan timeout
mov Temp3, Comm_Period4x_L ; Comm_Period4x(-l-h-x) holds the time of 4 commutations
mov Temp4, Comm_Period4x_H
clr C
mov A, Temp4
rrc A ; Divide by 2
mov Temp6, A
mov A, Temp3
rrc A
mov Temp5, A
clr C
mov A, Temp6
rrc A ; Divide by 2 again
mov Temp6, A
mov A, Temp5
rrc A
mov Temp5, A
clr C
mov A, Temp3
subb A, Temp5 ; Subtract a quarter
mov Temp3, A
mov A, Temp4
subb A, Temp6
mov Temp4, A
mov A, Temp3
add A, Temp1 ; Add the new time
mov Temp3, A
mov A, Temp4
addc A, Temp2
mov Temp4, A
mov Comm_Period4x_L, Temp3 ; Store Comm_Period4x_X
mov Comm_Period4x_H, Temp4
jc calc_next_comm_slow ; If period larger than 0xffff - go to slow case
ret
calc_next_comm_slow:
mov Comm_Period4x_L, #0FFh ; Set commutation period registers to very slow timing (0xffff)
mov Comm_Period4x_H, #0FFh
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Wait advance timing routine
;
; No assumptions
;
; Waits for the advance timing to elapse
; Also sets up timer 1 to wait the zero cross scan wait time
; And has a separate entry point for just setting up zero cross scan wait
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
wait_advance_timing:
jnb Flags0.T3_PENDING, ($+5)
ajmp wait_advance_timing
setup_zc_scan_wait:
mov TMR3CN, #00h ; Timer3 disabled
clr C
clr A
subb A, Wt_Zc_Scan_L ; Set wait to zero cross scan value
mov TMR3L, A
clr A
subb A, Wt_Zc_Scan_H
mov TMR3H, A
mov TMR3CN, #04h ; Timer3 enabled
setb Flags0.T3_PENDING
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Calculate new wait times routine
;
; No assumptions
;
; Calculates new wait times
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
calc_new_wait_times:
; Load programmed commutation timing
;读取Commutation timing
mov Temp1, #Pgm_Comm_Timing ; Load timing setting
mov A, @Temp1
mov Temp8, A ; Store in Temp8
mov Temp7, #(COMM_TIME_RED SHL 1)
jnb Flags0.DEMAG_DETECTED, calc_new_wait_check_startup ; Demag detected?
mov Temp8, #5 ; Yes - set high timing
calc_new_wait_check_startup:
jnb Flags1.DIRECT_STARTUP_PHASE, calc_new_wait_dir_start_set ; Set timing for direct start
mov Temp8, #3 ; Set medium timing
mov Temp7, #0 ; Set no comm time reduction
calc_new_wait_dir_start_set:
; Load current commutation timing
mov Temp2, Comm_Period4x_H ; Load Comm_Period4x
mov Temp1, Comm_Period4x_L
mov Temp3, #4 ; Divide 4 times
divide_wait_times:
clr C
mov A, Temp2
rrc A ; Divide by 2
mov Temp2, A
mov A, Temp1
rrc A
mov Temp1, A
djnz Temp3, divide_wait_times
clr C
mov A, Temp1
subb A, Temp7
mov Temp1, A
mov A, Temp2
subb A, #0
mov Temp2, A
jc load_min_time ; Check that result is still positive
clr C
mov A, Temp1
subb A, #(COMM_TIME_MIN SHL 1)
mov A, Temp2
subb A, #0
jnc adjust_timing ; Check that result is still above minumum
load_min_time:
mov Temp1, #(COMM_TIME_MIN SHL 1)
clr A
mov Temp2, A
adjust_timing:
mov A, Temp2 ; Copy values
mov Temp4, A
mov A, Temp1
mov Temp3, A
clr C
mov A, Temp2
rrc A ; Divide by 2
mov Temp6, A
mov A, Temp1
rrc A
mov Temp5, A
clr C
mov A, Temp8 ; (Temp8 has Pgm_Comm_Timing)
subb A, #3 ; Is timing normal?
jz store_times_decrease ; Yes - branch
mov A, Temp8
jb ACC.0, adjust_timing_two_steps ; If an odd number - branch
;Commutation timing = 第2、4项
mov A, Temp1 ; Add 7.5?and store in Temp1/2
add A, Temp5
mov Temp1, A
mov A, Temp2
addc A, Temp6
mov Temp2, A
mov A, Temp5 ; Store 7.5?in Temp3/4
mov Temp3, A
mov A, Temp6
mov Temp4, A
jmp store_times_up_or_down
;Commutation timing = 第1、5项
adjust_timing_two_steps:
mov A, Temp1 ; Add 15?and store in Temp1/2
add A, Temp1
mov Temp1, A
mov A, Temp2
addc A, Temp2
mov Temp2, A
mov Temp3, #(COMM_TIME_MIN SHL 1) ; Store minimum time in Temp3/4
clr A
mov Temp4, A
store_times_up_or_down:
clr C
mov A, Temp8
subb A, #3 ; Is timing higher than normal?
jc store_times_decrease ; No - branch
;Commutation timing = 第4、5项
store_times_increase:
mov Wt_Comm_L, Temp3 ; Now commutation time (~60? divided by 4 (~15?nominal)
mov Wt_Comm_H, Temp4
mov Wt_Advance_L, Temp1 ; New commutation advance time (~15?nominal)
mov Wt_Advance_H, Temp2
mov Wt_Zc_Scan_L, Temp5 ; Use this value for zero cross scan delay (7.5?
mov Wt_Zc_Scan_H, Temp6
ret
;Commutation timing = 第1、2、3项
store_times_decrease:
mov Wt_Comm_L, Temp1 ; Now commutation time (~60? divided by 4 (~15?nominal)
mov Wt_Comm_H, Temp2
mov Wt_Advance_L, Temp3 ; New commutation advance time (~15?nominal)
mov Wt_Advance_H, Temp4
mov Wt_Zc_Scan_L, Temp5 ; Use this value for zero cross scan delay (7.5?
mov Wt_Zc_Scan_H, Temp6
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Wait before zero cross scan routine
;
; No assumptions
;
; Waits for the zero cross scan wait time to elapse
; Also sets up timer 1 to wait the zero cross scan timeout time
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
wait_before_zc_scan:
jnb Flags0.T3_PENDING, ($+5)
ajmp wait_before_zc_scan
mov TMR3CN, #00h ; Timer3 disabled
clr C
clr A
subb A, Comm_Period4x_L ; Set wait to zero comm period 4x value
mov TMR3L, A
clr A
subb A, Comm_Period4x_H
mov TMR3H, A
mov TMR3CN, #04h ; Timer3 enabled
setb Flags0.T3_PENDING
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Wait for comparator to go low/high routines
;
; No assumptions
;
; Waits for the zero cross scan wait time to elapse
; Then scans for comparator going low/high
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
wait_for_comp_out_low:
mov Comp_Wait_Reads, #0
mov Bit_Access, #00h ; Desired comparator output
jmp wait_for_comp_out_start
wait_for_comp_out_high:
mov Comp_Wait_Reads, #0
mov Bit_Access, #40h ; Desired comparator output
wait_for_comp_out_start:
setb EA ; Enable interrupts
inc Comp_Wait_Reads
jb Flags0.T3_PENDING, ($+4) ; Has zero cross scan timeout elapsed?
ret ; Yes - return
; Set default comparator response times
mov CPT0MD, #0 ; Set fast response (100ns) as default
IF COMP1_USED==1
mov CPT1MD, #0 ; Set fast response (100ns) as default
ENDIF
; Select number of comparator readings based upon current rotation speed
mov A, Comm_Period4x_H ; Load rotation period
clr C
rrc A ; Divide by 4
clr C
rrc A
mov Temp1, A
inc Temp1 ; Add one to be sure it is always larger than zero
jz comp_wait_on_comp_able ; If minimum number of readings - jump directly to reading
; For damped mode, do fewer comparator readings (since comparator info is primarily only available in the pwm on period)
jnb Flags2.PGM_PWMOFF_DAMPED, comp_wait_set_max_readings
clr C
rrc A ; Divide by 4 again
clr C
rrc A
mov Temp1, A
inc Temp1 ; Add one to be sure it is always larger than zero
comp_wait_set_max_readings:
clr C
mov A, Temp1 ; Limit to a max of 10
subb A, #10
jc ($+4)
mov Temp1, #10
jnb Flags2.PGM_PWM_HIGH_FREQ, comp_wait_set_response_time ; Jump if pwm frequency is low
clr C
mov A, Temp1 ; Limit to a max of 4
subb A, #4
jc ($+4)
mov Temp1, #4
comp_wait_set_response_time:
clr C
mov A, Comm_Period4x_H ; Is Comm_Period4x_H less than 1ms?
subb A, #8
jc comp_wait_on_comp_able ; Yes - jump
mov CPT0MD, #2 ; Set medium response (300ns)
IF COMP1_USED==1
mov CPT1MD, #2 ; Set medium response (300ns)
ENDIF
clr C
mov A, Comm_Period4x_H ; Is Comm_Period4x_H less than 2ms?
subb A, #16
jc comp_wait_on_comp_able ; Yes - jump
mov CPT0MD, #3 ; Set slow response (1000ns)
IF COMP1_USED==1
mov CPT1MD, #3 ; Set slow response (1000ns)
ENDIF
comp_wait_on_comp_able:
jb Flags0.T3_PENDING, ($+6) ; Has zero cross scan timeout elapsed?
setb EA ; Enable interrupts
ret ; Yes - return
mov Temp2, #COMP_PWM_HIGH_ON_DELAY ; Wait time after pwm has been switched on (motor wire electrical settling)
jb Flags2.PGM_PWM_HIGH_FREQ, ($+5)
mov Temp2, #COMP_PWM_LOW_ON_DELAY
setb EA ; Enable interrupts
nop ; Allocate only just enough time to capture interrupt
nop
clr EA ; Disable interrupts
jb Flags0.PWM_ON, pwm_wait_startup ; If pwm on - proceed
mov Temp2, #COMP_PWM_HIGH_OFF_DELAY ; Wait time after pwm has been switched off (motor wire electrical settling)
jb Flags2.PGM_PWM_HIGH_FREQ, ($+5)
mov Temp2, #COMP_PWM_LOW_OFF_DELAY
jnb Flags2.CURR_PWMOFF_COMP_ABLE, comp_wait_on_comp_able ; If comparator is not usable in pwm off - go back
pwm_wait_startup:
jnb Flags1.DIRECT_STARTUP_PHASE, pwm_wait ; Set a long delay from pwm on/off events during direct startup
mov Temp2, #120
pwm_wait:
clr C
mov A, TL1
subb A, Temp2
IF DAMPED_MODE_ENABLE==0
jc comp_wait_on_comp_able ; Re-evaluate pwm cycle for slower escs
ENDIF
IF DAMPED_MODE_ENABLE==1 ; Assume same pwm cycle for fast escs
jb Flags1.DIRECT_STARTUP_PHASE, ($+5)
jc pwm_wait
jc comp_wait_on_comp_able ; Re-evaluate pwm cycle during direct start
ENDIF
comp_read:
Read_Comp_Out ; Read comparator output
cpl A
anl A, #40h
cjne A, Bit_Access, ($+5) ; If comparator output is correct - proceed
ajmp wait_for_comp_out_start ; If comparator output is not correct - go back and restart
djnz Temp1, comp_wait_on_comp_able ; Decrement readings counter - repeat comparator reading if not zero
setb EA ; Enable interrupts
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Evaluate comparator integrity
;
; No assumptions
;
; Checks comparator signal behaviour versus expected behaviour
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
evaluate_comparator_integrity:
clr Flags0.DEMAG_DETECTED ; Clear demag detected flag
; Check if demag compensation is enabled
;读取Demag compensation
mov Temp1, #Pgm_Demag_Comp ; Load programmed demag compensation
mov A, @Temp1
dec A
jz eval_comp_no_demag
; Check if a demag situation has occurred
mov A, Comp_Wait_Reads ; Check if there were no waits (there shall be some). If none a demag situation has occurred
dec A
jnz eval_comp_no_demag
;Demag compensation = 第2项
setb Flags0.DEMAG_DETECTED ; Set demag detected flag
;Demag compensation = 第1项
eval_comp_no_demag:
jnb Flags1.DIRECT_STARTUP_PHASE, eval_comp_check_timeout
inc Direct_Startup_Ok_Cnt ; Increment ok counter
jb Flags0.T3_PENDING, eval_comp_exit
mov Direct_Startup_Ok_Cnt, #0 ; Reset ok counter
jmp eval_comp_exit
eval_comp_check_timeout:
jb Flags0.T3_PENDING, eval_comp_exit ; Has timeout elapsed?
dec SP ; Routine exit without "ret" command
dec SP
ljmp run_to_wait_for_power_on ; Yes - exit run mode
eval_comp_exit:
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Setup commutation timing routine
;
; No assumptions
;
; Sets up and starts wait from commutation to zero cross
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
setup_comm_wait:
mov TMR3CN, #00h ; Timer3 disabled
clr C
clr A
subb A, Wt_Comm_L ; Set wait commutation value
mov TMR3L, A
clr A
subb A, Wt_Comm_H
mov TMR3H, A
mov TMR3CN, #04h ; Timer3 enabled
setb Flags0.T3_PENDING
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Wait for commutation routine
;
; No assumptions
;
; Waits from zero cross to commutation
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
wait_for_comm:
; Store motor power
mov Temp7, Current_Pwm_Limited
; Check if a demag situation has occurred
jnb Flags0.DEMAG_DETECTED, wait_for_comm_wait; Demag detected?
; Load programmed demag compensation
mov Temp1, #Pgm_Demag_Comp_Power_Decoded ; Yes - load programmed demag compensation power decoded
mov A, @Temp1
mov Temp8, A ; Store in Temp8
; Check for first power off
cjne Temp8, #1, wait_for_comm_blind
setb Flags0.DEMAG_CUT_POWER ; Turn off motor power
mov Current_Pwm_Limited, #0
All_nFETs_off
; Wait a blind wait
wait_for_comm_blind:
call setup_zc_scan_wait ; Setup a zero cross scan wait (7.5 deg)
wait_demag_default_zc1:
jnb Flags0.DEMAG_CUT_POWER, ($+6) ; Cut motor power if set
mov Current_Pwm_Limited, #0
jnb Flags0.T3_PENDING, ($+5)
ajmp wait_demag_default_zc1
; Check for second power off
cjne Temp8, #2, wait_for_comm_second_blind_wait
setb Flags0.DEMAG_CUT_POWER ; Turn off motor power
mov Current_Pwm_Limited, #0
All_nFETs_off
; Check for another blind wait
wait_for_comm_second_blind_wait:
mov Temp1, #Pgm_Demag_Comp_Wait_Decoded ; Yes - load programmed demag compensation wait decoded
cjne @Temp1, #1, wait_for_comm_power3
call setup_zc_scan_wait ; Setup a zero cross scan wait (7.5 deg)
wait_demag_default_zc2:
jnb Flags0.DEMAG_CUT_POWER, ($+6) ; Cut motor power if set
mov Current_Pwm_Limited, #0
jnb Flags0.T3_PENDING, ($+5)
ajmp wait_demag_default_zc2
wait_for_comm_power3:
; Check for third power off
cjne Temp8, #3, wait_for_comm_setup
setb Flags0.DEMAG_CUT_POWER ; Turn off motor power
mov Current_Pwm_Limited, #0
All_nFETs_off
wait_for_comm_setup:
call setup_comm_wait ; Setup commutation wait
wait_for_comm_wait:
jnb Flags0.DEMAG_CUT_POWER, ($+6) ; Cut motor power if set
mov Current_Pwm_Limited, #0
jnb Flags0.T3_PENDING, ($+5)
ajmp wait_for_comm_wait
jnb Flags0.DEMAG_DETECTED, wait_for_comm_exit ; Was there a demag situation?
clr Flags0.DEMAG_CUT_POWER ; Restore motor power again
mov Current_Pwm_Limited, Temp7
wait_for_comm_exit:
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Commutation routines
;
; No assumptions
;
; Performs commutation switching
; Damped routines uses all pfets on when in pwm off to dampen the motor
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;******************************************************
; 关B down 并 开A down或Cdown
;******************************************************
comm1comm2:
clr EA ; Disable all interrupts
BpFET_off ; Bp off
jb Flags2.PGM_PWMOFF_DAMPED, comm12_damp
jmp comm12_nondamp
comm12_damp:
IF DAMPED_MODE_ENABLE == 0
mov DPTR, #pwm_cnfet_apfet_on_fast
jb Flags2.PGM_PWMOFF_DAMPED_LIGHT, comm12_nondamp
ENDIF
IF DAMPED_MODE_ENABLE == 1
mov DPTR, #pwm_cnfet_apfet_on_safe
ENDIF
jnb Flags2.CURR_PWMOFF_DAMPED, comm12_nondamp ; If pwm off not damped - branch
CpFET_off
mov A, #NFETON_DELAY ; Delay
djnz ACC, $
comm12_nondamp:
ApFET_on ; Ap on
Set_Comp_Phase_B ; Set comparator to phase B
mov Comm_Phase, #2
setb EA ; Enable all interrupts
ret
comm2comm3:
clr EA ; Disable all interrupts
jb Flags2.PGM_PWMOFF_DAMPED, comm23_damp
jmp comm23_nondamp
comm23_damp:
IF DAMPED_MODE_ENABLE == 0
mov DPTR, #pwm_bnfet_apfet_on_fast
ENDIF
IF DAMPED_MODE_ENABLE == 1
mov DPTR, #pwm_bnfet_apfet_on_safe
ENDIF
jnb Flags2.CURR_PWMOFF_DAMPED, comm23_nfet ; If pwm off not damped - branch
BpFET_off
CpFET_off
mov A, #NFETON_DELAY ; Delay
djnz ACC, $
jmp comm23_nfet
comm23_nondamp:
mov DPTR, #pwm_bfet_on
comm23_nfet:
CnFET_off ; Cn off
jnb Flags0.PWM_ON, comm23_cp ; Is pwm on?
BnFET_on ; Yes - Bn on
comm23_cp:
Set_Comp_Phase_C ; Set comparator to phase C
mov Comm_Phase, #3
setb EA ; Enable all interrupts
ret
comm3comm4:
clr EA ; Disable all interrupts
ApFET_off ; Ap off
jb Flags2.PGM_PWMOFF_DAMPED, comm34_damp
jmp comm34_nondamp
comm34_damp:
IF DAMPED_MODE_ENABLE == 0
mov DPTR, #pwm_bnfet_cpfet_on_fast
jb Flags2.PGM_PWMOFF_DAMPED_LIGHT, comm34_nondamp
ENDIF
IF DAMPED_MODE_ENABLE == 1
mov DPTR, #pwm_bnfet_cpfet_on_safe
ENDIF
jnb Flags2.CURR_PWMOFF_DAMPED, comm34_nondamp ; If pwm off not damped - branch
BpFET_off
mov A, #NFETON_DELAY ; Delay
djnz ACC, $
comm34_nondamp:
CpFET_on ; Cp on
Set_Comp_Phase_A ; Set comparator to phase A
mov Comm_Phase, #4
setb EA ; Enable all interrupts
ret
comm4comm5:
clr EA ; Disable all interrupts
jb Flags2.PGM_PWMOFF_DAMPED, comm45_damp
jmp comm45_nondamp
comm45_damp:
IF DAMPED_MODE_ENABLE == 0
mov DPTR, #pwm_anfet_cpfet_on_fast
ENDIF
IF DAMPED_MODE_ENABLE == 1
mov DPTR, #pwm_anfet_cpfet_on_safe
ENDIF
jnb Flags2.CURR_PWMOFF_DAMPED, comm45_nfet ; If pwm off not damped - branch
ApFET_off
BpFET_off
mov A, #NFETON_DELAY ; Delay
djnz ACC, $
jmp comm45_nfet
comm45_nondamp:
mov DPTR, #pwm_afet_on
comm45_nfet:
BnFET_off ; Bn off
jnb Flags0.PWM_ON, comm45_cp ; Is pwm on?
AnFET_on ; Yes - An on
comm45_cp:
Set_Comp_Phase_B ; Set comparator to phase B
mov Comm_Phase, #5
setb EA ; Enable all interrupts
ret
comm5comm6:
clr EA ; Disable all interrupts
CpFET_off ; Cp off
jb Flags2.PGM_PWMOFF_DAMPED, comm56_damp
jmp comm56_nondamp
comm56_damp:
IF DAMPED_MODE_ENABLE == 0
mov DPTR, #pwm_anfet_bpfet_on_fast
jb Flags2.PGM_PWMOFF_DAMPED_LIGHT, comm56_nondamp
ENDIF
IF DAMPED_MODE_ENABLE == 1
mov DPTR, #pwm_anfet_bpfet_on_safe
ENDIF
jnb Flags2.CURR_PWMOFF_DAMPED, comm56_nondamp ; If pwm off not damped - branch
ApFET_off
mov A, #NFETON_DELAY ; Delay
djnz ACC, $
comm56_nondamp:
BpFET_on ; Bp on
Set_Comp_Phase_C ; Set comparator to phase C
mov Comm_Phase, #6
setb EA ; Enable all interrupts
ret
comm6comm1:
clr EA ; Disable all interrupts
jb Flags2.PGM_PWMOFF_DAMPED, comm61_damp
jmp comm61_nondamp
comm61_damp:
IF DAMPED_MODE_ENABLE == 0
mov DPTR, #pwm_cnfet_bpfet_on_fast
ENDIF
IF DAMPED_MODE_ENABLE == 1
mov DPTR, #pwm_cnfet_bpfet_on_safe
ENDIF
jnb Flags2.CURR_PWMOFF_DAMPED, comm61_nfet ; If pwm off not damped - branch
ApFET_off
CpFET_off
mov A, #NFETON_DELAY ; Delay
djnz ACC, $
jmp comm61_nfet
comm61_nondamp:
mov DPTR, #pwm_cfet_on
comm61_nfet:
AnFET_off ; An off
jnb Flags0.PWM_ON, comm61_cp ; Is pwm on?
CnFET_on ; Yes - Cn on
comm61_cp:
Set_Comp_Phase_A ; Set comparator to phase A
mov Comm_Phase, #1
setb EA ; Enable all interrupts
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Switch power off routine
;
; No assumptions
;
; Switches all fets off
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
switch_power_off:
mov DPTR, #pwm_nofet_on ; Set DPTR register to pwm_nofet_on label
All_pFETs_Off ; Turn off all pfets
All_nFETs_Off ; Turn off all nfets
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Decrement stepper step routine
;
; No assumptions
;
; Decrements the stepper step
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;decrement_stepper_step:
; clr C
; mov A, Wt_Stepper_Step_L
; subb A, Stepper_Step_End_L ; Minimum Stepper_Step_End
; mov A, Wt_Stepper_Step_H
; subb A, Stepper_Step_End_H
; jnc decrement_step ; Branch if same or higher than minimum
; ret
;decrement_step:
; Load programmed startup acceleration
;读取Startup acceleration
; mov Temp1, #Pgm_Startup_Accel ; Load startup accel
; mov A, @Temp1
; mov Temp8, A ; Store in Temp8
; Check acceleration setting and set step size accordingly
; clr C
; mov A, Temp8
; subb A, #5
; jnc dec_step_high
; clr C
; mov A, Temp8
; subb A, #4
; jnc dec_step_med_high
; clr C
; mov A, Temp8
; subb A, #3
; jnc dec_step_med
; clr C
; mov A, Temp8
; subb A, #2
; jnc dec_step_med_low
; clr C
; mov A, Temp8
; subb A, #1
; jnc dec_step_low
;Start acceleration = 第5项
;dec_step_high:
; clr C
; mov A, Wt_Stepper_Step_L
; subb A, #low(30 SHL 1)
; mov Temp1, A
; jmp decrement_step_exit
;Start acceleration = 第4项
;dec_step_med_high:
; clr C
; mov A, Wt_Stepper_Step_L
; subb A, #low(20 SHL 1)
; mov Temp1, A
; jmp decrement_step_exit
;Start acceleration = 第3项
;dec_step_med:
; clr C
; mov A, Wt_Stepper_Step_L
; subb A, #low(13 SHL 1)
; mov Temp1, A
; jmp decrement_step_exit
;Start acceleration = 第2项
;dec_step_med_low:
; clr C
; mov A, Wt_Stepper_Step_L
; subb A, #low(9 SHL 1)
; mov Temp1, A
; jmp decrement_step_exit
;Start acceleration = 第1项
;dec_step_low:
; clr C
; mov A, Wt_Stepper_Step_L
; subb A, #low(5 SHL 1)
; mov Temp1, A
; jmp decrement_step_exit
;decrement_step_exit:
; mov A, Wt_Stepper_Step_H
; subb A, #0
; mov Temp2, A
; mov Wt_Stepper_Step_L, Temp1
; mov Wt_Stepper_Step_H, Temp2
; ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Stepper timer wait
;
; No assumptions
;
; Waits for the stepper step timer to elapse
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;stepper_timer_wait:
; jnb Flags0.T3_PENDING, ($+6) ; Timer pending?
; ljmp stepper_timer_wait ; Yes, go back
; ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Set default parameters
;
; No assumptions
;
; Sets default programming parameters
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
set_default_parameters:
IF MODE == 0 ; Main
mov Temp1, #Pgm_Gov_P_Gain
mov @Temp1, #DEFAULT_PGM_MAIN_P_GAIN
mov Temp1, #Pgm_Gov_I_Gain
mov @Temp1, #DEFAULT_PGM_MAIN_I_GAIN
mov Temp1, #Pgm_Gov_Mode
mov @Temp1, #DEFAULT_PGM_MAIN_GOVERNOR_MODE
mov Temp1, #Pgm_Gov_Range
mov @Temp1, #DEFAULT_PGM_MAIN_GOVERNOR_RANGE
mov Temp1, #Pgm_Low_Voltage_Lim
mov @Temp1, #DEFAULT_PGM_MAIN_LOW_VOLTAGE_LIM
mov Temp1, #Pgm_Startup_Pwr
mov @Temp1, #DEFAULT_PGM_MAIN_STARTUP_PWR
mov Temp1, #Pgm_Startup_Rpm
mov @Temp1, #DEFAULT_PGM_MAIN_STARTUP_RPM
mov Temp1, #Pgm_Startup_Accel
mov @Temp1, #DEFAULT_PGM_MAIN_STARTUP_ACCEL
mov Temp1, #Pgm_Startup_Method
mov @Temp1, #DEFAULT_PGM_MAIN_STARTUP_METHOD
mov Temp1, #Pgm_Comm_Timing
mov @Temp1, #DEFAULT_PGM_MAIN_COMM_TIMING
mov Temp1, #Pgm_Throttle_Rate
mov @Temp1, #DEFAULT_PGM_MAIN_THROTTLE_RATE
mov Temp1, #Pgm_Damping_Force
mov @Temp1, #DEFAULT_PGM_MAIN_DAMPING_FORCE
mov Temp1, #Pgm_Pwm_Freq
mov @Temp1, #DEFAULT_PGM_MAIN_PWM_FREQ
mov Temp1, #Pgm_Demag_Comp
mov @Temp1, #DEFAULT_PGM_MAIN_DEMAG_COMP
mov Temp1, #Pgm_Direction_Rev
mov @Temp1, #DEFAULT_PGM_MAIN_DIRECTION_REV
mov Temp1, #Pgm_Input_Pol
mov @Temp1, #DEFAULT_PGM_MAIN_RCP_PWM_POL
mov Temp1, #Pgm_Motor_Idle
mov @Temp1, #0
ENDIF
IF MODE == 1 ; Tail
mov Temp1, #Pgm_Motor_Gain
mov @Temp1, #DEFAULT_PGM_TAIL_GAIN
mov Temp1, #Pgm_Motor_Idle
mov @Temp1, #DEFAULT_PGM_TAIL_IDLE_SPEED
mov Temp1, #Pgm_Startup_Pwr
mov @Temp1, #DEFAULT_PGM_TAIL_STARTUP_PWR
mov Temp1, #Pgm_Startup_Rpm
mov @Temp1, #DEFAULT_PGM_TAIL_STARTUP_RPM
mov Temp1, #Pgm_Startup_Accel
mov @Temp1, #DEFAULT_PGM_TAIL_STARTUP_ACCEL
mov Temp1, #Pgm_Startup_Method
mov @Temp1, #DEFAULT_PGM_TAIL_STARTUP_METHOD
mov Temp1, #Pgm_Comm_Timing
mov @Temp1, #DEFAULT_PGM_TAIL_COMM_TIMING
mov Temp1, #Pgm_Throttle_Rate
mov @Temp1, #DEFAULT_PGM_TAIL_THROTTLE_RATE
mov Temp1, #Pgm_Damping_Force
mov @Temp1, #DEFAULT_PGM_TAIL_DAMPING_FORCE
mov Temp1, #Pgm_Pwm_Freq
mov @Temp1, #DEFAULT_PGM_TAIL_PWM_FREQ
mov Temp1, #Pgm_Demag_Comp
mov @Temp1, #DEFAULT_PGM_TAIL_DEMAG_COMP
mov Temp1, #Pgm_Direction_Rev
mov @Temp1, #DEFAULT_PGM_TAIL_DIRECTION_REV
mov Temp1, #Pgm_Input_Pol
mov @Temp1, #DEFAULT_PGM_TAIL_RCP_PWM_POL
mov Temp1, #Pgm_Gov_Mode
mov @Temp1, #4
ENDIF
IF MODE == 2 ; Multi
mov Temp1, #Pgm_Fir_Key ;2013.8.27 增加关键字默认值
mov @Temp1, #DEFAULT_PGM_MULTI_FIRST_KEYWORD
mov Temp1, #Pgm_Gov_P_Gain
mov @Temp1, #DEFAULT_PGM_MAIN_P_GAIN ;Pgm_Gov_P_Gain=9 P增益
mov Temp1, #Pgm_Gov_I_Gain
mov @Temp1, #DEFAULT_PGM_MAIN_I_GAIN ;Pgm_Gov_I_Gain=9 I增益
mov Temp1, #Pgm_Gov_Mode
mov @Temp1, #DEFAULT_PGM_MAIN_GOVERNOR_MODE ;Pgm_Gov_Mode=4
mov Temp1, #Pgm_Motor_Gain
mov @Temp1, #DEFAULT_PGM_MULTI_GAIN ;gm_Motor_Gain=3
mov Temp1, #Pgm_Low_Voltage_Lim
mov @Temp1, #DEFAULT_PGM_MULTI_LOW_VOLTAGE_LIM ;Pgm_Low_Voltage_Lim=1 低压保护:1=Off 2=3.0V/c 3=3.1V/c 4=3.2V/c 5=3.3V/c 6=3.4V/c
mov Temp1, #Pgm_Low_Voltage_Ctl
mov @Temp1, #DEFAULT_PGM_MULTI_LOW_VOLTAGE_CTL ;Pgm_Low_Voltage_Ctl=1 低压保护: 1=功率逐渐降低到31% 2=关闭输出
mov Temp1, #Pgm_Startup_Pwr
mov @Temp1, #DEFAULT_PGM_MULTI_STARTUP_PWR ;Pgm_Startup_Pwr=10
mov Temp1, #Pgm_Startup_Rpm
mov @Temp1, #DEFAULT_PGM_MULTI_STARTUP_RPM ;Pgm_Startup_Rpm=1 启动转速:1=0.67 2=0.8 3=1.00 4=1.25 5=1.5
mov Temp1, #Pgm_Startup_Accel
mov @Temp1, #DEFAULT_PGM_MULTI_STARTUP_ACCEL ;Pgm_Startup_Accel=5
; mov Temp1, #Pgm_Startup_Method
; mov @Temp1, #DEFAULT_PGM_MULTI_STARTUP_METHOD ;Pgm_Startup_Method=2 启动方式:1=步进启动 2=直接启动
mov Temp1, #Pgm_Comm_Timing
mov @Temp1, #DEFAULT_PGM_MULTI_COMM_TIMING ;Pgm_Comm_Timing=3 进角时间:1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High
mov Temp1, #Pgm_Throttle_Rate
mov @Temp1, #DEFAULT_PGM_MULTI_THROTTLE_RATE ;Pgm_Throttle_Rate=13 油门范围:1=2 2=3 3=4 4=6 5=8 6=12 7=16 8=24 9=32 10=48 11=64 12=128 13=255
mov Temp1, #Pgm_Damping_Force
mov @Temp1, #DEFAULT_PGM_MULTI_DAMPING_FORCE ;Pgm_Damping_Force=6 刹车力度:1=VeryLow 2=Low 3=MediumLow 4=MediumHigh 5=High 6=Highest
mov Temp1, #Pgm_Pwm_Freq
mov @Temp1, #DEFAULT_PGM_MULTI_PWM_FREQ ;Pgm_Pwm_Freq=1 1=Low 2=High 3=DampedLight 4=Damped
mov Temp1, #Pgm_Demag_Comp
mov @Temp1, #DEFAULT_PGM_MULTI_DEMAG_COMP ;Pgm_Demag_Comp=2 1=Disabled 2=15/0 3=15/7.5 4=7.5/7.5 5=7.5/15 (degrees blind advance / power off)
mov Temp1, #Pgm_Direction_Rev
mov @Temp1, #DEFAULT_PGM_MULTI_DIRECTION_REV ;Pgm_Direction_Rev=1 方向设置:1=正转 2=反转
mov Temp1, #Pgm_Input_Pol
mov @Temp1, #DEFAULT_PGM_MULTI_RCP_PWM_POL ;Pgm_Input_Pol=1 接收信号极性设置:1=Positive(正) 2=Negative(负)
mov Temp1, #Pgm_Motor_Idle
mov @Temp1, #0 ;Pgm_Motor_Idle=0
ENDIF
mov Temp1, #Pgm_Enable_TX_Program
mov @Temp1, #DEFAULT_PGM_ENABLE_TX_PROGRAM ;Pgm_Enable_TX_Program=1 1=Enabled 0=Disabled
mov Temp1, #Pgm_Main_Rearm_Start
mov @Temp1, #DEFAULT_PGM_MAIN_REARM_START ;Pgm_Main_Rearm_Start=0 1=Enabled 0=Disabled
mov Temp1, #Pgm_Gov_Setup_Target
mov @Temp1, #DEFAULT_PGM_MAIN_GOV_SETUP_TARGET ;Pgm_Gov_Setup_Target=180 Target for governor in setup mode. Corresponds to 70% throttle
mov Temp1, #Pgm_Ppm_Min_Throttle
mov @Temp1, #DEFAULT_PGM_PPM_MIN_THROTTLE ;Pgm_Ppm_Min_Throttle=37 最小油门:4*37+1000=1148
mov Temp1, #Pgm_Ppm_Max_Throttle
mov @Temp1, #DEFAULT_PGM_PPM_MAX_THROTTLE ;Pgm_Ppm_Max_Throttle=208 最大油门:4*208+1000=1832
mov Temp1, #Pgm_Beep_Strength
mov @Temp1, #DEFAULT_PGM_MAIN_BEEP_STRENGTH ;Pgm_Beep_Strength=120 声强设置
mov Temp1, #Pgm_Beacon_Strength
mov @Temp1, #DEFAULT_PGM_MAIN_BEACON_STRENGTH ;Pgm_Beacon_Strength=200 灯亮长Beacon strength????
mov Temp1, #Pgm_Beacon_Delay
mov @Temp1, #DEFAULT_PGM_MAIN_BEACON_DELAY ;Pgm_Beacon_Delay=4 灯亮时间????1=30s 2=1m 3=2m 4=3m 5=Infinite
mov Temp1, #Pgm_BEC_Voltage_High
mov @Temp1, #DEFAULT_PGM_BEC_VOLTAGE_HIGH ;Pgm_BEC_Voltage_High=0 0=Low 1= High
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Decode parameters
;
; No assumptions
;
; Decodes programming parameters
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
decode_parameters:
; Load programmed damping force
;读取Damping force
mov Temp1, #Pgm_Damping_Force; Load damping force
mov A, @Temp1
mov Temp8, A ; Store in Temp8
; Decode damping
;Damping force = 第1项
clr Flags2.PGM_PWMOFF_DAMPED
clr Flags2.PGM_PWMOFF_DAMPED_LIGHT
clr Flags2.PGM_PWMOFF_DAMPED_FULL
clr Flags2.CURR_PWMOFF_DAMPED
setb Flags2.CURR_PWMOFF_COMP_ABLE
mov Damping_Period, #9 ; Set default
mov Damping_On, #1
mov Rcp_Stop_Limit,#250
clr C
cjne Temp8, #1, decode_damping_2 ; Look for 2
jmp decode_damping_done
;Damping force = 第2项
decode_damping_2:
setb Flags2.PGM_PWMOFF_DAMPED
; setb Flags2.PGM_PWMOFF_DAMPED_LIGHT
; clr Flags2.PGM_PWMOFF_DAMPED_FULL
setb Flags2.CURR_PWMOFF_DAMPED
clr Flags2.CURR_PWMOFF_COMP_ABLE
mov Damping_Period, #5
mov Damping_On, #1
mov Rcp_Stop_Limit,#60
clr C
cjne Temp8, #2, decode_damping_3 ; Look for 3
jmp decode_damping_done
;Damping force = 第3项
decode_damping_3:
; setb Flags2.PGM_PWMOFF_DAMPED
setb Flags2.PGM_PWMOFF_DAMPED_LIGHT
; clr Flags2.PGM_PWMOFF_DAMPED_FULL
; setb Flags2.CURR_PWMOFF_DAMPED
; clr Flags2.CURR_PWMOFF_COMP_ABLE
mov Damping_Period, #5
mov Damping_On, #2
mov Rcp_Stop_Limit,#30
clr C
cjne Temp8, #3, decode_damping_4 ; Look for 4
jmp decode_damping_done
;Damping force = 第4项
decode_damping_4:
; setb Flags2.PGM_PWMOFF_DAMPED
; setb Flags2.PGM_PWMOFF_DAMPED_LIGHT
; clr Flags2.PGM_PWMOFF_DAMPED_FULL
; setb Flags2.CURR_PWMOFF_DAMPED
; clr Flags2.CURR_PWMOFF_COMP_ABLE
mov Damping_Period, #5
mov Damping_On, #3
mov Rcp_Stop_Limit,#25
clr C
cjne Temp8, #4, decode_damping_5 ; Look for 5
jmp decode_damping_done
;Damping force = 第5项
decode_damping_5:
; setb Flags2.PGM_PWMOFF_DAMPED
; setb Flags2.PGM_PWMOFF_DAMPED_LIGHT
setb Flags2.PGM_PWMOFF_DAMPED_FULL
; setb Flags2.CURR_PWMOFF_DAMPED
; clr Flags2.CURR_PWMOFF_COMP_ABLE
mov Damping_Period, #5
mov Damping_On, #4
mov Rcp_Stop_Limit,#20
clr C
cjne Temp8, #5, decode_damping_6; Look for 6
jmp decode_damping_done
;Damping force = 第6项
decode_damping_6:
; setb Flags2.PGM_PWMOFF_DAMPED
; setb Flags2.PGM_PWMOFF_DAMPED_LIGHT
; setb Flags2.PGM_PWMOFF_DAMPED_FULL
; setb Flags2.CURR_PWMOFF_DAMPED
; clr Flags2.CURR_PWMOFF_COMP_ABLE
mov Damping_Period, #5
mov Damping_On, #5
mov Rcp_Stop_Limit,#10
;***********************************************
; 读取编程PWM频率(1)
;带硬刹/软刹
;***********************************************
decode_damping_done:
; Load programmed pwm frequency
;读取Pwm frequency
mov Temp1, #Pgm_Pwm_Freq ; Load pwm freq
mov A, @Temp1
mov Temp8, A ; Store in Temp8
IF MODE == 0 ; Main
clr Flags2.PGM_PWMOFF_DAMPED_LIGHT
clr C
cjne Temp8, #3, ($+5)
setb Flags2.PGM_PWMOFF_DAMPED_LIGHT
clr Flags2.PGM_PWMOFF_DAMPED_FULL
ENDIF
IF MODE >= 1 ; Tail or multi
;////// clr Flags2.PGM_PWMOFF_DAMPED_LIGHT
;////// clr C
;////// cjne Temp8, #3, ($+5)
;Pwm frequency = 第3项
;////// setb Flags2.PGM_PWMOFF_DAMPED_LIGHT
;////// clr Flags2.PGM_PWMOFF_DAMPED_FULL
;////// clr C
;////// cjne Temp8, #4, ($+5)
;Pwm frequency = 第4项
;////// setb Flags2.PGM_PWMOFF_DAMPED_FULL
ENDIF
;Pwm frequency = 第1项
;////// clr Flags2.PGM_PWMOFF_DAMPED ; Set damped flag if fully damped or damped light is set
;////// mov A, #((1 SHL PGM_PWMOFF_DAMPED_FULL)+(1 SHL PGM_PWMOFF_DAMPED_LIGHT))
;////// anl A, Flags2 ; Check if any damped mode is set
;////// jz ($+4)
;Pwm frequency = 第2项
;////// setb Flags2.PGM_PWMOFF_DAMPED
;Pwm frequency = 第1项
;////// clr Flags2.CURR_PWMOFF_DAMPED ; Set non damped status as start
;////// jz ($+4)
;Pwm frequency = 第2项
;////// setb Flags2.CURR_PWMOFF_DAMPED ; Set non damped status as start if damped
;Pwm frequency = 第1项
;////// setb Flags2.CURR_PWMOFF_COMP_ABLE ; Set comparator usable status
;////// jz ($+4)
;Pwm frequency = 第2项
;////// clr Flags2.CURR_PWMOFF_COMP_ABLE ; Set comparator not usable status if damped
;***********************************************
; 读取编程电机旋转方向
;***********************************************
;读取Rotation direction
;Rotation direction = 第1项
clr Flags3.PGM_DIR_REV
mov Temp1, #Pgm_Direction_Rev
mov A, @Temp1
jnb ACC.1, ($+5)
;Rotation direction = 第2项
setb Flags3.PGM_DIR_REV
;***********************************************
; 读取编程输入信号RC PWM脉冲有效极性
;***********************************************
;读取Input pwm polarity
;Input pwm polarity = 第1项
clr Flags3.PGM_RCP_PWM_POL
mov Temp1, #Pgm_Input_Pol
mov A, @Temp1
jnb ACC.1, ($+5)
;Input pwm polarity = 第2项
setb Flags3.PGM_RCP_PWM_POL
;***********************************************
; 读取编程PWM频率(2)
;不带硬刹/软刹
;***********************************************
clr C
mov A, Temp8
subb A, #1
jz decode_pwm_freq_low
;Pwm frequency = 第1项
mov CKCON, #01h ; Timer0 set for clk/4 (22kHz pwm)
setb Flags2.PGM_PWM_HIGH_FREQ
jmp decode_pwm_freq_end
;Pwm frequency = 第2项
decode_pwm_freq_low:
mov CKCON, #00h ; Timer0 set for clk/12 (8kHz pwm)
clr Flags2.PGM_PWM_HIGH_FREQ
decode_pwm_freq_end:
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Decode governor gain
;
; No assumptions
;
; Decodes governor gains
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
decode_governor_gains:
; Decode governor gains
;读取 Closed loop P gain
mov Temp1, #Pgm_Gov_P_Gain ; Decode governor P gain
mov A, @Temp1
dec A
mov DPTR, #GOV_GAIN_TABLE
movc A, @A+DPTR
mov Temp1, #Pgm_Gov_P_Gain_Decoded
mov @Temp1, A
;读取 Closed loop I gain
mov Temp1, #Pgm_Gov_I_Gain ; Decode governor P gain
mov A, @Temp1
dec A
mov DPTR, #GOV_GAIN_TABLE
movc A, @A+DPTR
mov Temp1, #Pgm_Gov_I_Gain_Decoded
mov @Temp1, A
call switch_power_off ; Reset DPTR
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Decode throttle rate
;
; No assumptions
;
; Decodes throttle rate
;
;读取中点油门范围
;**** **** **** **** **** **** **** **** **** **** **** **** ****
decode_throttle_rate:
; Decode throttle rate
;读取 Throttle change rate
mov Temp1, #Pgm_Throttle_Rate
mov A, @Temp1
dec A
mov DPTR, #THROTTLE_RATE_TABLE
movc A, @A+DPTR
mov Temp1, #Pgm_Throttle_Rate_Decoded
mov @Temp1, A
call switch_power_off ; Reset DPTR
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Decode startup power
;
; No assumptions
;
; Decodes startup power
;
;编程启动力度
;**** **** **** **** **** **** **** **** **** **** **** **** ****
decode_startup_power:
; Decode startup power
;读取 Startup power
mov Temp1, #Pgm_Startup_Pwr
mov A, @Temp1
dec A
mov DPTR, #STARTUP_POWER_TABLE
movc A, @A+DPTR
mov Temp1, #Pgm_Startup_Pwr_Decoded
mov @Temp1, A
call switch_power_off ; Reset DPTR
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Decode demag compensation
;
; No assumptions
;
; Decodes throttle rate
;
;编程demag compensation参数
;**** **** **** **** **** **** **** **** **** **** **** **** ****
decode_demag_comp:
; Decode demag compensation
;读取Demag compensation
mov Temp1, #Pgm_Demag_Comp
mov A, @Temp1
dec A
mov DPTR, #DEMAG_WAIT_TABLE
movc A, @A+DPTR
mov Temp1, #Pgm_Demag_Comp_Wait_Decoded
mov @Temp1, A
mov Temp1, #Pgm_Demag_Comp
mov A, @Temp1
dec A
mov DPTR, #DEMAG_POWER_TABLE
movc A, @A+DPTR
mov Temp1, #Pgm_Demag_Comp_Power_Decoded
mov @Temp1, A
call switch_power_off ; Reset DPTR
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Set BEC voltage
;
; No assumptions
;
; Sets the BEC output voltage low or high
;
;读取 BEC
;**** **** **** **** **** **** **** **** **** **** **** **** ****
set_bec_voltage:
; Set bec voltage
IF DUAL_BEC_VOLTAGE == 1
Set_BEC_Lo ; Set default to low
;读取 Pgm_BEC_Voltage_High
mov Temp1, #Pgm_BEC_Voltage_High
mov A, @Temp1
jz set_bec_voltage_exit
Set_BEC_Hi ; Set to high
set_bec_voltage_exit:
ENDIF
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Find throttle gain
;
; The difference between max and min throttle must be more than 520us (a Pgm_Ppm_xxx_Throttle difference of 130)
;
; Finds throttle gain from throttle calibration values
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
find_throttle_gain:
; Load programmed minimum and maximum throttle
;读取Pgm_Ppm_Min_Throttle和Pgm_Ppm_Max_Throttle增量
mov Temp1, #Pgm_Ppm_Min_Throttle
mov A, @Temp1
mov Temp3, A
mov Temp1, #Pgm_Ppm_Max_Throttle
mov A, @Temp1
mov Temp4, A
; Check if full range is chosen
jnb Flags3.FULL_THROTTLE_RANGE, find_throttle_gain_calculate
mov Temp3, #0
mov Temp4, #255
find_throttle_gain_calculate:
; Calculate difference
clr C
mov A, Temp4
subb A, Temp3
mov Temp5, A
; Check that difference is minimum 130
clr C
subb A, #130
jnc ($+4)
mov Temp5, #130
; Find gain
mov Ppm_Throttle_Gain, #0
test_gain:
inc Ppm_Throttle_Gain
mov A, Temp5
mov B, Ppm_Throttle_Gain ; A has difference, B has gain
mul AB
clr C
mov A, B
subb A, #128
jc test_gain
ret
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Main program start
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;**** **** **** **** **** **** **** **** **** **** **** **** ****
reset:
; Select register bank 0 for main program routines
clr PSW.3 ; Select register bank 0 for main program routines
; Disable the WDT.
anl PCA0MD, #NOT(40h) ; Clear watchdog enable bit
; Initialize stack
mov SP, #0c0h ; Stack = 64 upper bytes of RAM
; Initialize VDD monitor
orl VDM0CN, #080h ; Enable the VDD monitor
mov Temp2, #3
wait_100us:
djnz ACC, $
djnz Temp2,wait_100us
; call wait1ms ; Wait at least 100us
mov RSTSRC, #02h ; Set VDD monitor as a reset source (PORSF)
; Set clock frequency
orl OSCICN, #03h ; Set clock divider to 1
mov A, OSCICL
add A, #04h ; 24.5MHz to 24MHz (~0.5% per step)
jc reset_cal_done ; Is carry set? - skip next instruction
mov OSCICL, A
reset_cal_done:
; Ports initialization
mov P0, #P0_INIT
mov P0MDOUT, #P0_PUSHPULL
mov P0MDIN, #P0_DIGITAL
mov P0SKIP, #P0_SKIP
mov P1, #P1_INIT
mov P1MDOUT, #P1_PUSHPULL
mov P1MDIN, #P1_DIGITAL
mov P1SKIP, #P1_SKIP
IF PORT3_EXIST == 1
mov P2, #P2_INIT
ENDIF
mov P2MDOUT, #P2_PUSHPULL
IF PORT3_EXIST == 1
mov P2MDIN, #P2_DIGITAL
mov P2SKIP, #P2_SKIP
mov P3, #P3_INIT
mov P3MDOUT, #P3_PUSHPULL
mov P3MDIN, #P3_DIGITAL
ENDIF
mov XBR1, #41h ; Xbar enabled, CEX0 routed to pin Rcp_In
; Switch power off
call switch_power_off
; Clear RAM
clr A ; Clear accumulator
mov Temp1, A ; Clear Temp1
clear_ram:
mov @Temp1, A ; Clear RAM
djnz Temp1, clear_ram ; Is A not zero? - jump
; Set default programmed parameters
call set_default_parameters
; Read all programmed parameters
call read_all_eeprom_parameters
; Decode parameters
call decode_parameters
; Decode governor gains
call decode_governor_gains
; Decode throttle rate
call decode_throttle_rate
; Decode startup power
call decode_startup_power
; Decode demag compensation
call decode_demag_comp
; Set BEC voltage
call set_bec_voltage
; Find throttle gain from stored min and max settings
call find_throttle_gain
; Set beep strength
;读取超强设置
mov Temp1, #Pgm_Beep_Strength
mov Beep_Strength, @Temp1
; Switch power off
call switch_power_off
; Timer control
mov TCON, #50h ; Timer0 and timer1 enabled
; Timer mode
mov TMOD, #02h ; Timer0 as 8bit
; Timer2: clk/12 for 128us and 32ms interrupts
mov TMR2CN, #24h ; Timer2 enabled, low counter interrups enabled
; Timer3: clk/12 for commutation timing
mov TMR3CN, #04h ; Timer3 enabled
; PCA
mov PCA0CN, #40h ; PCA enabled
; Initializing beep 上电叫3声
call wait1s
call wait1s
; Enable interrupts
mov IE, #22h ; Enable timer0 and timer2 interrupts
mov IP, #02h ; High priority to timer0 interrupts
mov EIE1, #90h ; Enable timer3 and PCA0 interrupts
mov EIP1, #10h ; High priority to PCA interrupts
; Initialize comparator
mov CPT0CN, #80h ; Comparator enabled, no hysteresis
mov CPT0MD, #03h ; Comparator response time 1us
IF COMP1_USED==1
mov CPT1CN, #80h ; Comparator enabled, no hysteresis
mov CPT1MD, #03h ; Comparator response time 1us
ENDIF
; Initialize ADC
Initialize_Adc ; Initialize ADC operation
call wait1ms
setb EA ; Enable all interrupts
; Measure number of lipo cells
call Measure_Lipo_Cells ; Measure number of lipo cells
; Initialize rc pulse
Rcp_Int_Enable ; Enable interrupt
Rcp_Int_First ; Enable interrupt and set to first edge
Rcp_Clear_Int_Flag ; Clear interrupt flag
clr Flags2.RCP_EDGE_NO ; Set first edge flag
call wait200ms
; Set initial arm variable
mov Initial_Arm, #1
; mov Pca_First_Int, #1
; Measure PWM frequency
measure_pwm_freq_init:
setb Flags0.RCP_MEAS_PWM_FREQ ; Set measure pwm frequency flag
; clr C ;2014.08.08 信号滤波
; mov A, Pgm_Pulse_Cnt ;2014.08.08 信号滤波
; subb A, #5 ;2014.08.08 信号滤波
; jc measure_pwm_freq_init ;2014.08.08 信号滤波
; mov Pca_First_Int, #0 ;2014.08.08 信号滤波
; call wait200ms
measure_pwm_freq_start:
mov Temp3, #5 ; Number of pulses to measure
; mov Temp3, #1
measure_pwm_freq_loop:
; Check if period diff was accepted
mov A, Rcp_Period_Diff_Accepted
; jnz ($+4)
jnz measure_pwm
call wait3ms
mov A, New_RCP
clr C
subb A,#230
jc ($+7)
mov Pgm_Pulse_Cnt, #0
; mov Temp3, #5
ajmp measure_pwm_freq_start
mov A, New_RCP
clr C
subb A,#30
jnc ($+7)
mov Pgm_Pulse_Cnt, #0
; mov Temp3, #5
ajmp measure_pwm_freq_start
inc Pgm_Pulse_Cnt
mov A, Pgm_Pulse_Cnt
clr C
subb A, #5
jnc ($+6)
mov Temp3, #5 ; Reset number of pulses to measure
ajmp measure_pwm_freq_loop
; mov Temp3, #1
measure_pwm:
call wait3ms ; Wait for next pulse (NB: Uses Temp1/2!)
mov A, New_Rcp ; Load value
clr C
subb A, #RCP_VALIDATE ; Higher than validate level?
jc measure_pwm_freq_start ; No - start over
mov A, Flags3 ; Check pwm frequency flags
; anl A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
anl A, #(1 SHL RCP_PWM_FREQ_1KHZ)
mov Prev_Rcp_Pwm_Freq, Curr_Rcp_Pwm_Freq ; Store as previous flags for next pulse
mov Curr_Rcp_Pwm_Freq, A ; Store current flags for next pulse
cjne A, Prev_Rcp_Pwm_Freq, measure_pwm_freq_start ; Go back if new flags not same as previous
djnz Temp3, measure_pwm_freq_loop ; Go back if not required number of pulses seen
; Clear measure pwm frequency flag
clr Flags0.RCP_MEAS_PWM_FREQ
; Set up RC pulse interrupts after pwm frequency measurement
Rcp_Int_First ; Enable interrupt and set to first edge
Rcp_Clear_Int_Flag ; Clear interrupt flag
clr Flags2.RCP_EDGE_NO ; Set first edge flag
call wait100ms ; Wait for new RC pulse
; Validate RC pulse
;Pgm_Main_Rearm_Start = 第1项 enabled
validate_rcp_start:
call wait3ms ; Wait for next pulse (NB: Uses Temp1/2!)
mov Temp1, #RCP_VALIDATE ; Set validate level as default
; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
mov A, #(1 SHL RCP_PWM_FREQ_1KHZ)
anl A, Flags3 ; Check pwm frequency flags
jnz ($+4) ; If a flag is set (PWM) - branch
mov Temp1, #0 ; Set level to zero for PPM (any level will be accepted)
clr C
mov A, New_Rcp ; Load value
subb A, Temp1 ; Higher than validate level?
jc validate_rcp_start ; No - start over
; Beep arm sequence start signal
;上电检测到信号后叫第1声(信号准备就绪)
;////// clr EA ; Disable all interrupts
;////// call beep_f1 ; Signal that RC pulse is ready
;////// call beep_f1
;////// call beep_f1
;////// setb EA ; Enable all interrupts
call wait200ms
; Arming sequence start
mov Gov_Arm_Target, #0 ; Clear governor arm target
arming_start:
call wait3ms
;读取Pgm_Enable_TX_Program
mov Temp1, #Pgm_Enable_TX_Program; Yes - start programming mode entry if enabled
mov A, @Temp1
clr C
subb A, #1 ; Is TX programming enabled?
jnc arming_initial_arm_check ; Yes - proceed
jmp program_by_tx_checked ; No - branch
;Pgm_Enable_TX_Program = 1 enabled
arming_initial_arm_check:
mov A, Initial_Arm ; Yes - check if it is initial arm sequence
clr C
subb A, #1 ; Is it the initial arm sequence?
jnc arming_ppm_check ; Yes - proceed
jmp wait_for_power_on ; No - branch
arming_ppm_check:
mov Temp1, #Pgm_Ppm_Min_Throttle ; Store
mov A, @Temp1
mov Min_Throttle, A
; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
mov A, #(1 SHL RCP_PWM_FREQ_1KHZ)
anl A, Flags3 ; Check pwm frequency flags
jz throttle_high_cal_start ; If no flag is set (PPM) - branch
; PWM tx program entry
; clr C
; mov A, New_Rcp ; Load new RC pulse value
; subb A, #200 ; Is RC pulse max?
; jc program_by_tx_entry_wait_pwm ; Yes - proceed
; subb A, #RCP_MAX ; Is RC pulse max?
; jnc program_by_tx_entry_pwm ; Yes - proceed
; jmp program_by_tx_checked ; No - branch
;program_by_tx_entry_pwm:
; clr EA ; Disable all interrupts
; call beep_f4
; setb EA ; Enable all interrupts
; call wait100ms
; clr C
; mov A, New_Rcp ; Load new RC pulse value
; subb A, #RCP_STOP ; Below stop?
; subb A, #200
; jnc program_by_tx_entry_pwm ; No - start over
;program_by_tx_entry_wait_pwm:
clr EA
call beep_f2
call beep_f3
call beep_f1
mov TMOD, #11h ;T0/T1 工作方式1
mov CKCON, #02h ;T0/T1 48分频
mov P0MDIN, #80h
mov P0SKIP, #0FFh
call program_by_card ; Yes - enter programming mode
; ajmp program_by_card_entry
;program_by_tx_entry_wait_pwm:
; clr EA ; Disable all interrupts
; call beep_f1
; call wait10ms
; call beep_f1
; setb EA ; Enable all interrupts
; call wait100ms
; clr C
; mov A, New_Rcp ; Load new RC pulse value
; subb A, #RCP_MAX ; At or above max?
; jc program_by_tx_entry_wait_pwm ; No - start over
; call program_by_tx ; Yes - enter programming mode
; jmp program_by_tx_checked
; PPM throttle calibration and tx program entry
;计算PPM最大,最小油门并存储
throttle_high_cal_start:
mov Temp8, #5 ; Set 3 seconds wait time
throttle_high_cal:
setb Flags3.FULL_THROTTLE_RANGE ; Set range to 1000-2020us
call Find_Throttle_Gain ; Set throttle gain
call wait100ms ; Wait for new throttle value
clr EA ; Disable interrupts (freeze New_Rcp value)
clr Flags3.FULL_THROTTLE_RANGE ; Set programmed range
call Find_Throttle_Gain ; Set throttle gain
clr C
mov A, New_Rcp ; Load new RC pulse value
subb A, #220 ; Is RC pulse above midstick? 1840
setb EA ; Enable interrupts
jc ($+6)
djnz Temp8, throttle_high_cal
ajmp throttle_high_cal_save
clr C
mov A, New_Rcp ; Load new RC pulse value
subb A, Min_Throttle ; Is RC pulse above midstick? 1148
jnc ($+4)
ajmp arm_target_updated ; No - branch 检测低油门
clr EA
call beep_f1;
call wait100ms
setb EA
ajmp throttle_high_cal_start
throttle_high_cal_save:
; call wait1s
clr C
mov A, New_Rcp ; Limit to max 250
subb A, #5 ; Subtract about 2% and ensure that it is 250 or lower
mov Temp1, #Pgm_Ppm_Max_Throttle ; Store
mov @Temp1, A
call set_commu_sum_to_zero ;////////////////////////////////////**************************
call erase_and_store_all_in_eeprom
clr EA
call beep_f1;/////////////////////////////////////////成功存储最大油门叫声
call beep_f1;/////////////////////////////////////////成功存储最大油门叫声
call wait30ms;/////////////////////////////////////////成功存储最大油门叫声
call beep_f4;/////////////////////////////////////////成功存储最大油门叫声
call beep_f4;/////////////////////////////////////////成功存储最大油门叫声
setb EA
call wait1s
call wait1s
wait_loop_1:
clr C
mov A, New_Rcp ; Load new RC pulse value
subb A, #215 ;Is RC pulse above midstick?
jnc program_by_tx_entry_wait_ppm
clr C
mov A, New_Rcp ; Load new RC pulse value
subb A, #60 ;Is RC pulse above midstick?
jnc wait_loop_1
ajmp throttle_low_cal_start
;PPM编程模式
program_by_tx_entry_wait_ppm:
call program_by_tx ; Yes - enter programming mode 成功进入编程模式
;最小油门设置及退出
throttle_low_cal_start:
mov Temp8, #5 ; Set 3 seconds wait time
throttle_low_cal:
; call wait1s
setb Flags3.FULL_THROTTLE_RANGE ; Set range to 1000-2020us
call Find_Throttle_Gain ; Set throttle gain
call wait100ms
clr EA ; Disable interrupts (freeze New_Rcp value)
clr Flags3.FULL_THROTTLE_RANGE ; Set programmed range
call Find_Throttle_Gain ; Set throttle gain
clr C
mov A, New_Rcp ; Load new RC pulse value
subb A, #60 ; Below midstick?
setb EA ; Enable interrupts
jnc throttle_low_cal_start ; No - start over 在中点油门以上,则继续等待,直到检测到在中点油门以下
djnz Temp8, throttle_low_cal ; Yes - continue to wait
; call wait3ms
mov A, New_Rcp
add A, #5 ; Add about 2%
mov Temp1, #Pgm_Ppm_Min_Throttle ; Store
mov @Temp1, A
call set_commu_sum_to_zero ;////////////////////////////////////**************************
call erase_and_store_all_in_eeprom
; clr EA ; Disable all interrupts
; mov RSTSRC, #12h ; Generate hardware reset 强制复位系统
; Set default programmed parameters
; call set_default_parameters
; Read all programmed parameters
call read_all_eeprom_parameters
; Decode parameters
call decode_parameters
; Decode governor gains
call decode_governor_gains
; Decode throttle rate
call decode_throttle_rate
; Decode startup power
call decode_startup_power
; Decode demag compensation
call decode_demag_comp
; Set BEC voltage
call set_bec_voltage
; Find throttle gain from stored min and max settings
call find_throttle_gain
program_by_tx_checked:
clr C
mov A, New_Rcp ; Load new RC pulse value
subb A, Gov_Arm_Target ; Is RC pulse larger than arm target?
jc arm_target_updated ; No - do not update
mov Gov_Arm_Target, New_Rcp ; Yes - update arm target
arm_target_updated:
call wait100ms ; Wait for new throttle value
clr C
mov A, New_Rcp ; Load new RC pulse value
subb A, #RCP_STOP ; Below stop?
jc arm_end_beep ; Yes - proceed ;最小油门计算好 及 编程结束叫声
jmp arm_target_updated ; No - start over
;上电检测到信号后叫第2声(信号检测结束)
arm_end_beep:
;改变上电叫方式
clr EA ; Disable all interrupts
call beep_f1
call beep_f1
call beep_f1
call wait1s
; Beep arm sequence end signal
;*************************************************
; 增加Lipo节数叫声 2013.5.29
;*************************************************
mov Temp8,Lipo_Cell_Count ;
lipo_cell_beep:
call beep_f1
call beep_f1
call wait30ms
djnz Temp8,lipo_cell_beep
call wait200ms
call wait200ms
;///// call beep_f4 ; Signal that rcpulse is ready
;///// call beep_f4
;///// call beep_f4
;改变信号检测OK叫声方式 2013.5.29
call beep_f1
call wait30ms
call wait30ms
call beep_f2
call wait30ms
call wait30ms
call beep_f3
call wait30ms
call wait30ms
setb EA ; Enable all interrupts
call wait100ms
; Measure number of lipo cells
call Measure_Lipo_Cells ; Measure number of lipo cells
; Clear initial arm variable
mov Initial_Arm, #0
; Armed and waiting for power on
wait_for_power_on:
mov Temp8, #50
clr LOW_LIMIT_STOP ; 清低压保护控制方式2 停止标志
;////// clr A
;////// mov Power_On_Wait_Cnt_L, A ; Clear wait counter
;////// mov Power_On_Wait_Cnt_H, A
wait_for_power_on_loop:
;////// inc Power_On_Wait_Cnt_L ; Increment low wait counter
;////// mov A, Power_On_Wait_Cnt_L
;////// cpl A
;////// jnz wait_for_power_on_no_beep; Counter wrapping (about 1 sec)?
;////// inc Power_On_Wait_Cnt_H ; Increment high wait counter
;********************************************************
; 读取油门最低未操作等待叫声时间
;********************************************************
;读取Pgm_Beacon_Delay
;////// mov Temp1, #Pgm_Beacon_Delay
;////// mov A, @Temp1
;////// mov Temp1, #40 ; Approximately 30 sec
;////// dec A
;////// jz beep_delay_set
;////// mov Temp1, #80 ; Approximately 1 min
;////// dec A
;////// jz beep_delay_set
;////// mov Temp1, #160 ; Approximately 2 min
;////// dec A
;////// jz beep_delay_set
;////// mov Temp1, #240 ; Approximately 3 min
;////// dec A
;////// jz beep_delay_set
;////// mov Power_On_Wait_Cnt_H, #0 ; Reset counter for infinite delay
;//////beep_delay_set:
;////// clr C
;////// mov A, Power_On_Wait_Cnt_H
;////// subb A, Temp1 ; Check against chosen delay
;////// jc wait_for_power_on_no_beep; Has delay elapsed?
;********************************************************
; 读取油门最低未操作等待叫声声强设置
;********************************************************
;////// dec Power_On_Wait_Cnt_H ; Decrement high wait counter
;读取Pgm_Beacon_Strength
;////// mov Temp1, #Pgm_Beacon_Strength
;////// mov Beep_Strength, @Temp1
;////// clr EA ; Disable all interrupts
;////// All_pFETs_Off;///////////////////////////////////////*****************************
;////// call beep_f4 ; Signal that there is no signal
;////// setb EA ; Enable all interrupts
;读取Pgm_Beep_Strength
;////// mov Temp1, #Pgm_Beep_Strength
;////// mov Beep_Strength, @Temp1
;////// call wait100ms ; Wait for new RC pulse to be measured
wait_for_power_on_no_beep:
call wait3ms
mov A, Rcp_Timeout_Cnt ; Load RC pulse timeout counter value
jnz wait_for_power_on_ppm_not_missing ; If it is not zero - proceed
; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
; anl A, Flags3 ; Check pwm frequency flags
; jnz wait_for_power_on_ppm_not_missing ; If a flag is set (PWM) - branch
jmp measure_pwm_freq_init ; If ppm and pulses missing - go back to measure pwm frequency
wait_for_power_on_ppm_not_missing:
clr C
mov A, New_Rcp ; Load new RC pulse value
; subb A, #RCP_STOP ; Higher than stop (plus some hysteresis)?
subb A, #(RCP_STOP+7) ; Higher than stop (plus some hysteresis)?
jc wait_for_power_on ; No - start over
djnz Temp8, wait_for_power_on_no_beep
jb LOW_LIMIT_STOP, wait_for_power_on_loop
call wait100ms ; Wait to see if start pulse was only a glitch
mov A, Rcp_Timeout_Cnt ; Load RC pulse timeout counter value
jnz ($+5) ; If it is not zero - proceed
ljmp measure_pwm_freq_init ; If it is zero (pulses missing) - go back to measure pwm frequency
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Start entry point
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
init_start:
setb ET0
call switch_power_off
clr A
mov Requested_Pwm, A ; Set requested pwm to zero
mov Governor_Req_Pwm, A ; Set governor requested pwm to zero
mov Current_Pwm, A ; Set current pwm to zero
mov Current_Pwm_Limited, A ; Set limited current pwm to zero
mov Pwm_Limit, #0FFh ; Set pwm limit to max
mov Temp1, #Pgm_Motor_Idle
mov Pwm_Motor_Idle, @Temp1 ; Set idle pwm to programmed value
mov Gov_Target_L, A ; Set target to zero
mov Gov_Target_H, A
mov Gov_Integral_L, A ; Set integral to zero
mov Gov_Integral_H, A
mov Gov_Integral_X, A
mov Adc_Conversion_Cnt, A
mov Gov_Active, A
mov Flags0, A ; Clear flags0
mov Flags1, A ; Clear flags1
mov Rcp_Stop_Cnt, A ; Set RC pulse stop count to zero
mov Rcp_Stop_Limit, A
mov Lipo_Cell_Count, A
mov Limit_Count, A
mov New_Rcp, #Rcp_MIN
call initialize_all_timings ; Initialize timing
;**** **** **** **** ****
; Settle phase beginning
;**** **** **** **** ****
mov Adc_Conversion_Cnt, #TEMP_CHECK_RATE ; Make sure a temp reading is done
Set_Adc_Ip_Temp
call wait1ms
call start_adc_conversion
read_initial_temp:
Get_Adc_Status
jb AD0BUSY, read_initial_temp
Read_Adc_Result ; Read initial temperature
mov A, Temp2
jnz ($+3) ; Is reading below 256?
mov Temp1, A ; Yes - set average temperature value to zero
mov Current_Average_Temp, Temp1 ; Set initial average temperature
call check_temp_voltage_and_limit_power
mov Adc_Conversion_Cnt, #TEMP_CHECK_RATE ; Make sure a temp reading is done next time
Set_Adc_Ip_Temp
; Go to the desired startup mode
; mov Temp1, #Pgm_Startup_Method
; mov A, @Temp1
; jnb ACC.0, direct_method_start
; jmp stepper_method_start
direct_method_start:
; Set up start operating conditions
mov Temp1, #Pgm_Pwm_Freq
mov A, @Temp1
mov Temp7, A ; Store setting in Temp7
mov @Temp1, #1 ; Set nondamped low frequency pwm mode
call decode_parameters ; (Decode_parameters uses Temp1 and Temp8)
mov Temp1, #Pgm_Pwm_Freq
mov A, Temp7
mov @Temp1, A ; Restore settings
; Set max allowed power
setb Flags1.SETTLE_PHASE ; Set settle phase power as max
clr EA ; Disable interrupts to avoid that Requested_Pwm is overwritten
call set_startup_pwm
mov Pwm_Limit, Requested_Pwm
mov Pwm_Limit_Spoolup, Requested_Pwm
setb EA
clr Flags1.SETTLE_PHASE
mov Current_Pwm_Limited, #0 ; Set low pwm again after calling set_startup_pwm
mov Spoolup_Limit_Cnt, #0
mov Spoolup_Limit_Skip, #1
; Begin startup sequence
setb Flags1.MOTOR_SPINNING ; Set motor spinning flag
setb Flags1.DIRECT_STARTUP_PHASE ; Set direct startup phase flag
mov Direct_Startup_Ok_Cnt, #0 ; Reset ok counter
call comm5comm6 ; Initialize commutation
call comm6comm1
call calc_next_comm_timing ; Set virtual commutation point
call initialize_all_timings ; Initialize timing
jmp run1
;stepper_method_start:
; ; Set up start operating conditions
; mov Temp1, #Pgm_Pwm_Freq
; mov A, @Temp1
; mov Temp7, A ; Store setting in Temp7
; mov @Temp1, #3 ; Set damped light mode
; mov Temp1, #Pgm_Damping_Force
; mov A, @Temp1
; mov Temp6, A ; Store setting in Temp6
; mov @Temp1, #5 ; Set high damping force
; call decode_parameters ; (Decode_parameters uses Temp1 and Temp8)
; mov Temp1, #Pgm_Pwm_Freq
; mov A, Temp7
; mov @Temp1, A ; Restore settings
; mov Temp1, #Pgm_Damping_Force
; mov A, Temp6
; mov @Temp1, A
; Begin startup sequence
; setb Flags1.MOTOR_SPINNING ; Set motor spinning flag
; setb Flags1.SETTLE_PHASE ; Set motor start settling phase flag
; setb Flags2.CURR_PWMOFF_DAMPED; Set damped status, in order to ensure that pfets will be turned off in an initial pwm on
; call comm5comm6 ; Initialize commutation
; call comm6comm1
; call set_startup_pwm
; call wait1ms
; call comm1comm2
; call wait1ms
; call wait1ms
; call comm2comm3
; call wait3ms
; call comm3comm4
; call wait3ms
; call wait3ms
; call comm4comm5
; call wait10ms ; Settle rotor
; call comm5comm6
; call wait3ms
; call wait1ms
; clr Flags1.SETTLE_PHASE ; Clear settling phase flag
; setb Flags1.STEPPER_PHASE ; Set motor start stepper phase flag
; ;**** **** **** **** ****
; ; Stepper phase beginning
; ;**** **** **** **** ****
;stepper_rot_beg:
; call start_adc_conversion
; call check_temp_voltage_and_limit_power
; call set_startup_pwm
; mov Adc_Conversion_Cnt, #TEMP_CHECK_RATE ; Make sure a temp reading is done next time
; Set_Adc_Ip_Temp
; call comm6comm1 ; Commutate
; call calc_next_comm_timing_start ; Update timing and set timer
; call calc_new_wait_times
; call decrement_stepper_step
; call stepper_timer_wait
; call comm1comm2
; call calc_next_comm_timing_start
; call calc_new_wait_times
; call decrement_stepper_step
; call stepper_timer_wait
; call comm2comm3
; call calc_next_comm_timing_start
; call calc_new_wait_times
; call decrement_stepper_step
; call stepper_timer_wait
; call comm3comm4
; call calc_next_comm_timing_start
; call calc_new_wait_times
; call decrement_stepper_step
; call stepper_timer_wait
; call comm4comm5
; call calc_next_comm_timing_start
; call calc_new_wait_times
; call decrement_stepper_step
; call stepper_timer_wait
; call comm5comm6
; call calc_next_comm_timing_start
; call calc_new_wait_times
; call decrement_stepper_step
; ; Check stepper step versus end criteria
; clr C
; mov A, Wt_Stepper_Step_L
; subb A, Stepper_Step_End_L ; Minimum Stepper_Step_End
; mov A, Wt_Stepper_Step_H
; subb A, Stepper_Step_End_H
; jc stepper_rot_exit ; Branch if lower than minimum
; ; Wait for step
; call stepper_timer_wait
; clr C
; mov A, New_Rcp ; Load new pulse value
; subb A, #RCP_STOP ; Check if pulse is below stop value
; jnc stepper_rot_beg
; jmp run_to_wait_for_power_on
;stepper_rot_exit:
; ; Wait for step
; call stepper_timer_wait
; ; Clear stepper phase
; clr Flags1.STEPPER_PHASE ; Clear motor start stepper phase flag
; ; Set dondamped low pwm frequency
; mov Temp1, #Pgm_Pwm_Freq
; mov A, @Temp1
; mov Temp7, A ; Store setting in Temp7
; mov @Temp1, #2 ; Set nondamped low frequency pwm mode
; call decode_parameters ; (Decode_parameters uses Temp1 and Temp8)
; mov Temp1, #Pgm_Pwm_Freq
; mov A, Temp7
; mov @Temp1, A ; Restore settings
; ; Set spoolup power variables (power is now controlled from RCP)
; mov Pwm_Limit, Requested_Pwm
; mov Pwm_Limit_Spoolup, Pwm_Spoolup_Beg
; mov Current_Pwm_Limited, Pwm_Spoolup_Beg
; mov Spoolup_Limit_Cnt, #0
; mov Spoolup_Limit_Skip, #1
; ; Set direct startup phase to aquire sync quickly
; setb Flags1.DIRECT_STARTUP_PHASE ; Set direct startup phase flag
; mov Direct_Startup_Ok_Cnt, #0 ; Reset ok counter
; clr EA ; Disable interrupts
; ApFET_off ; Ap off. Turn off unused pfets (to turn off damping fets that might be on)
; CpFET_off ; Cp off
; mov A, #45 ; 8us delay for pfets to go off
; djnz ACC, $
; setb EA ; Enable interrupts
; call comm6comm1
; call calc_next_comm_timing ; Calculate next timing and start advance timing wait
; call wait_advance_timing ; Wait advance timing and start zero cross wait
; call calc_new_wait_times
; call wait_before_zc_scan ; Wait zero cross wait and start zero cross timeout
; mov Adc_Conversion_Cnt, #0 ; Make sure a voltage reading is done next time
; Set_Adc_Ip_Volt ; Set adc measurement to voltage
; jmp run1
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Run entry point
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
damped_transition:
; Transition from nondamped to damped if applicable
call decode_parameters ; Set programmed parameters
call comm6comm1
mov Adc_Conversion_Cnt, #0 ; Make sure a voltage reading is done next time
Set_Adc_Ip_Volt ; Set adc measurement to voltage
; Run 1 = B(p-on) + C(n-pwm) - comparator A evaluated
; Out_cA changes from high to low
run1:
call wait_for_comp_out_high ; Wait zero cross wait and wait for high
call evaluate_comparator_integrity ; Check whether comparator reading has been normal
call setup_comm_wait ; Setup wait time from zero cross to commutation
call calc_governor_target ; Calculate governor target
call wait_for_comm ; Wait from zero cross to commutation
call comm1comm2 ; Commutate
call calc_next_comm_timing ; Calculate next timing and start advance timing wait
call wait_advance_timing ; Wait advance timing and start zero cross wait
call calc_new_wait_times
call wait_before_zc_scan ; Wait zero cross wait and start zero cross timeout
; Run 2 = A(p-on) + C(n-pwm) - comparator B evaluated
; Out_cB changes from low to high
run2:
call wait_for_comp_out_low
call evaluate_comparator_integrity
call setup_comm_wait
call calc_governor_prop_error
call wait_for_comm
call comm2comm3
call calc_next_comm_timing
call wait_advance_timing
call calc_new_wait_times
call wait_before_zc_scan
; Run 3 = A(p-on) + B(n-pwm) - comparator C evaluated
; Out_cC changes from high to low
run3:
call wait_for_comp_out_high
call evaluate_comparator_integrity
call setup_comm_wait
call calc_governor_int_error
call wait_for_comm
call comm3comm4
call calc_next_comm_timing
call wait_advance_timing
call calc_new_wait_times
call wait_before_zc_scan
; Run 4 = C(p-on) + B(n-pwm) - comparator A evaluated
; Out_cA changes from low to high
run4:
call wait_for_comp_out_low
call evaluate_comparator_integrity
call setup_comm_wait
call calc_governor_prop_correction
call wait_for_comm
call comm4comm5
call calc_next_comm_timing
call wait_advance_timing
call calc_new_wait_times
call wait_before_zc_scan
; Run 5 = C(p-on) + A(n-pwm) - comparator B evaluated
; Out_cB changes from high to low
run5:
call wait_for_comp_out_high
call evaluate_comparator_integrity
call setup_comm_wait
call calc_governor_int_correction
call wait_for_comm
call comm5comm6
call calc_next_comm_timing
call wait_advance_timing
call calc_new_wait_times
call wait_before_zc_scan
; Run 6 = B(p-on) + A(n-pwm) - comparator C evaluated
; Out_cC changes from low to high
run6:
call wait_for_comp_out_low
call start_adc_conversion
call evaluate_comparator_integrity
call setup_comm_wait
call check_temp_voltage_and_limit_power
call wait_for_comm
call comm6comm1
call calc_next_comm_timing
call wait_advance_timing
call calc_new_wait_times
call wait_before_zc_scan
; Check if it is direct startup
jnb Flags1.DIRECT_STARTUP_PHASE, normal_run_checks
; Set spoolup power variables
IF MODE == 0 OR MODE == 2
mov Pwm_Limit, Pwm_Spoolup_Beg ; Set initial max power
mov Pwm_Limit_Spoolup, Pwm_Spoolup_Beg ; Set initial slow spoolup power
ENDIF
IF MODE == 1
mov Pwm_Limit, #0FFh ; Allow full power
mov Pwm_Limit_Spoolup, #0FFh
ENDIF
mov Spoolup_Limit_Cnt, #0
mov Spoolup_Limit_Skip, #1
; Check startup ok counter
clr C
mov A, Direct_Startup_Ok_Cnt ; Load ok counter
subb A, #100 ; Is counter above requirement?
jc direct_start_check_rcp ; No - proceed
clr Flags1.DIRECT_STARTUP_PHASE ; Clear direct startup phase flag
setb Flags1.INITIAL_RUN_PHASE ; Set initial run phase flag
mov Startup_Rot_Cnt, #20 ; Set startup rotation count
jmp normal_run_checks
direct_start_check_rcp:
clr C
mov A, New_Rcp ; Load new pulse value
subb A, #RCP_STOP ; Check if pulse is below stop value
jc ($+5)
ljmp run1 ; Continue to run
jmp run_to_wait_for_power_on
normal_run_checks:
; Check if it is initial run phase
jnb Flags1.INITIAL_RUN_PHASE, initial_run_phase_done; If not initial run phase - branch
; Decrement startup rotaton count
mov A, Startup_Rot_Cnt
dec A
; Check number of nondamped rotations
jnz normal_run_check_startup_rot ; Branch if counter is not zero
clr Flags1.INITIAL_RUN_PHASE ; Clear initial run phase flag
ljmp damped_transition ; Do damped transition if counter is zero
normal_run_check_startup_rot:
mov Startup_Rot_Cnt, A ; Not zero - store counter
clr C
mov A, New_Rcp ; Load new pulse value
subb A, #RCP_STOP ; Check if pulse is below stop value
jc ($+5)
ljmp run1 ; Continue to run
jmp run_to_wait_for_power_on
initial_run_phase_done:
; Exit run loop after a given time
clr C
mov A, Rcp_Stop_Cnt ; Load stop RC pulse counter value
;///// subb A, #RCP_STOP_LIMIT ; Is number of stop RC pulses above limit?
subb A, Rcp_Stop_Limit ; Is number of stop RC pulses above limit?
jnc run_to_wait_for_power_on ; Yes, go back to wait for poweron
run6_check_rcp_timeout:
; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
; anl A, Flags3 ; Check pwm frequency flags
; jnz run6_check_speed ; If a flag is set (PWM) - branch
mov A, Rcp_Timeout_Cnt ; Load RC pulse timeout counter value
jz run_to_wait_for_power_on ; If it is zero - go back to wait for poweron
run6_check_speed:
clr C
mov A, Comm_Period4x_H ; Is Comm_Period4x more than 32ms (~1220 eRPM)?
subb A, #0F0h
jnc run_to_wait_for_power_on ; Yes - go back to motor start
jmp run1 ; Go back to run 1
run_to_wait_for_power_on:
call switch_power_off
mov Temp1, #Pgm_Pwm_Freq
mov A, @Temp1
mov Temp7, A ; Store setting in Temp7
mov @Temp1, #1 ; Set low pwm mode (in order to turn off damping)
call decode_parameters ; (Decode_parameters uses Temp1 and Temp8)
mov Temp1, #Pgm_Pwm_Freq
mov A, Temp7
mov @Temp1, A ; Restore settings
clr A
mov Requested_Pwm, A ; Set requested pwm to zero
mov Governor_Req_Pwm, A ; Set governor requested pwm to zero
mov Current_Pwm, A ; Set current pwm to zero
mov Current_Pwm_Limited, A ; Set limited current pwm to zero
mov Pwm_Motor_Idle, A ; Set motor idle to zero
clr Flags1.MOTOR_SPINNING ; Clear motor spinning flag
call wait1ms ; Wait for pwm to be stopped
call switch_power_off
call wait10ms
clr ET0
jb Flags2.PGM_PWMOFF_DAMPED, light_damp
ajmp damp_exit
light_damp:
jb Flags2.PGM_PWMOFF_DAMPED_LIGHT, ($+7)
setb P1.BnFET
ajmp damp_exit
jb Flags2.PGM_PWMOFF_DAMPED_FULL, high_damp
A_B_nFETs_On
ajmp damp_exit
high_damp:
All_nFETs_On
damp_exit:
IF MODE == 0 ; Main
mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
anl A, Flags3 ; Check pwm frequency flags
jnz run_to_next_state_main ; If a flag is set (PWM) - branch
mov A, Rcp_Timeout_Cnt ; Load RC pulse timeout counter value
jnz run_to_next_state_main ; If it is not zero - branch
jmp measure_pwm_freq_init ; If it is zero (pulses missing) - go back to measure pwm frequency
run_to_next_state_main:
mov Temp1, #Pgm_Startup_Method ; Check if it is stepped startup
mov A, @Temp1
jnb ACC.0, run_to_next_state_main_wait_done ; If direct startup - jump
call wait1s ; 3 second delay before new startup (in stepped mode)
call wait1s
call wait1s
run_to_next_state_main_wait_done:
;读取Pgm_Main_Rearm_Start
mov Temp1, #Pgm_Main_Rearm_Start
mov A, @Temp1
clr C
subb A, #1 ; Is re-armed start enabled?
jc jmp_wait_for_power_on ; No - do like tail and start immediately
jmp validate_rcp_start ; Yes - go back to validate RC pulse
;Pgm_Main_Rearm_Start = 第2项 disabled
jmp_wait_for_power_on:
jmp wait_for_power_on ; Go back to wait for power on
ENDIF
IF MODE >= 1 ; Tail or multi
; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ))
; anl A, Flags3 ; Check pwm frequency flags
; jnz jmp_wait_for_power_on ; If a flag is set (PWM) - branch
mov A, Rcp_Timeout_Cnt ; Load RC pulse timeout counter value
jnz jmp_wait_for_power_on ; If it is not zero - go back to wait for poweron
jmp measure_pwm_freq_init ; If it is zero (pulses missing) - go back to measure pwm frequency
jmp_wait_for_power_on:
jmp wait_for_power_on_loop ; Go back to wait for power on
ENDIF
;**** **** **** **** **** **** **** **** **** **** **** **** ****
$include (BLHeliTxPgm.inc) ; Include source code for programming the ESC with the TX
;**** **** **** **** **** **** **** **** **** **** **** **** ****
END