5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年)
标题: BLHeli_S 源码解析讨论 [打印本页]
作者: 逗倪豌儿 时间: 2016-10-22 16:41
标题: BLHeli_S 源码解析讨论
本帖最后由 逗倪豌儿 于 2016-10-24 09:32 编辑
# 1.时钟配置说明 #
对每次 FLASH 读或取指操作,系统为 FLASH存储器提供一个内部 FLASH 读选通信号。FLASH读选通信号持续一或两个系统时钟周期,由 FLRT(PFE0CN.4)决定。如果系统时钟大于 25 MHz,则 FLRT 位必须被设置为逻辑 1,否则,从 FLASH读取的数据或指令不是实际的 FLASH内容。
更新 FLRT步骤如下
- 第一步:设置SFRPAGE地址为 PFE0CN页地址(0X10) 即 mov SFRPAGE, #10h
- 第二步:
如果系统时钟SYSCLK小于等于25M 则
禁止指令预取引擎(PFE0CN寄存器中的 PFEN位清 0),设置 PFE0CN.5 = 0
FLASH读选通信号为一个系统时钟 设置 PFE0CN.4 = 0 即mov SFRPAGE, #10h
如果系统时钟SYSCLK大于 25 MH 则
使能指令预取引擎(PFE0CN寄存器中的 PFEN位清 0),设置 PFE0CN.5 = 1
FLASH读选通信号为两个系统时钟 设置 PFE0CN.4 = 1 即mov PFE0CN, #30h
- 第三步:设置 SFRPAGE页地址为 00H。即 mov SFRPAGE, #00h
所以时钟配置程序如下 :
- ;****************************** 设置系统时钟为24M *****************************
- ;
- ; 1:时钟源为 HFOSC1 (48M) ,然后配置为 2分频
- ; 2
- ;
- ;*****************************************************************************
- Set_MCU_Clk_24MHz MACRO
- mov CLKSEL, #13h; Set clock to 24MHz
- mov SFRPAGE, #10h
- mov PFE0CN, #00h; Set flash timing for 24MHz
- mov SFRPAGE, #00h
- mov Clock_Set_At_48MHz, #0
- ENDM
复制代码- ;****************************** 设置系统时钟为48M *****************************
- ;
- ; 1:时钟源为 HFOSC1 (48M) SYSCLK 为 clock source(原时钟的1分频)
- ; 1:
- ;
- ;*****************************************************************************
- Set_MCU_Clk_48MHz MACRO
- mov SFRPAGE, #10h
- mov PFE0CN, #30h; Set flash timing for 48MHz
- mov SFRPAGE, #00h
- mov CLKSEL, #03h; Set clock to 48MHz
- mov Clock_Set_At_48MHz, #1
- ENDM
复制代码
## 1.1页寄存器使用说明 ##
你所用的每个寄存器都有个寄存地址,而寄存器页的页码就是指向你的寄存地址的。当你需要使用某个寄存器时,就必须把SFRPAGE指向你所要用的寄存器页上面去
举例如下:
- void Init_ADC0()
- {
- char SFRPAGE_SAVE = SFRPAGE; // 保存当前的SFR页
- SFRPAGE = ADC0_PAGE; //把页码改到以下几个寄存器所在的页码
- ADC0CN = 0x00; // 每次向AD0BUSY 写1 时启动ADC0 转换
- REF0CN = 0x03; // ADC0电压基准取自VREF0引脚,内部电压基准缓冲器工作
- AMX0CF = 0x00; // AIN inputs are single-ended (default)
- AMX0SL = 0x00; // 选择ADC 输入为AIN0.0
- // ADC0CF = (SYSCLK/SAR_CLK) << 3; // ADC 转换时钟 = 2.5MHz
- ADC0CF |= 0x00; // PGA 增益 = 1 (默认)
- // EIE2 |= 0x02; // 允许ADC0 转换结束中断
- SFRPAGE = SFRPAGE_SAVE; //回复寄存器页
- }
复制代码
这个程序中char SFRPAGE_SAVE = SFRPAGE; 和 SFRPAGE = SFRPAGE_SAVE; 是使在调用这个子函数后页码能够回到调用前的页码
----------
# 2.脉冲捕获--获取油门值说明 (Get_Rcp_Capture_Values) #
函数说明
- 1:脉冲捕获使用定时器0,计数周期 41.67ns;
- 2:该函数是在定时器 0中断中执行。
操作步骤如下:
- 1:关闭定时器0
- 2:保存计数值 Temp1 = TL0 Temp2 = TH0 Temp3 = Timer0_X (该值在定时器0中断中被自加)
- 3:如果定时器0和其他的中断同时产生了,那么定时器0会被挂起,如果被挂起则把Temp3++, 否则 Temp3 保持原来的值
- 4:把定时器0 计数器清0 即TL0 =0 TH0 = 0
- 5:把 Timer0_X 清零,即 Timer0_X = 0
- 6:从新使能定时器 0
- 7: 如果48M Temp1 = Temp1 *2 Temp2 = Temp2 *2 Temp3 = Temp3 *2,如果不是 Temp1 Temp2 Temp3 保持原有值
该函数的作用是读取脉冲捕获的计数器值 参数返回放到 Temp1 和 Temp2 中
----------
# 3. PCA初始化函数说明 -- Initialize_PCA #
说明:
- 1: 使能PCA0
- 2: PCA0时钟选择系统时钟
- 3: 如果延时为0 如果48M,则设置PCA0为11位PWM ,否则设置为10位模式 ,设置PWM 边沿对齐
- 4: 如果延时不为0 如果48M 则设置PCA0为10位PWM ,否则设置为9位模式 , 设置PWM 中间对齐
----------
# 4.上电PWM模式设置--Enable_Power_Pwm_Module #
说明:
1. 如果延时为0 使能比较器CPM0,使能匹配功能, 使能PCA为PWM模式
2. 如果延时为0 使能比较器CPM0, 禁能匹配功能, 使能PCA为PWM模式
代码如下 :
- Enable_Power_Pwm_Module MACRO
- IF FETON_DELAY == 0
- mov PCA0CPM0, #4Ah ; Enable comparator of module, enable match, set pwm mode
- ELSE
- mov PCA0CPM0, #42h ; Enable comparator of module, set pwm mode
- ENDIF
- ENDM
复制代码 ----------
# ADC 初始化函数 -- Initialize_Adc #
说明:设置采样频率为 2M
- 1:设置VDD作为电压基准,使能内部温度传感器
- 2:设置ADC转换clk = PCLK/(REF0CN >>3 -1) ,所以,
如果是48M 则48/ (B9H >>3 -1)= 2.18M
如果是24M 则24/ (59h >>3 -1)= 2.4M
- 3:设置ADC增益为 1倍
代码如下 :
- Initialize_Adc MACRO
- mov REF0CN, #0Ch; Set vdd (3.3V) as reference. Enable temp sensor and bias
- IF MCU_48MHZ == 0
- mov ADC0CF, #59h; ADC clock 2MHz, PGA gain 1
- ELSE
- mov ADC0CF, #0B9h ; ADC clock 2MHz, PGA gain 1
- ENDIF
- mov ADC0MX, #10h; Select temp sensor input
- mov ADC0CN0, #80h ; ADC enabled
- mov ADC0CN1, #01h ; Common mode buffer enabled
- ENDM
复制代码
作者: 逗倪豌儿 时间: 2016-10-22 16:44
本帖最后由 逗倪豌儿 于 2016-10-24 09:33 编辑
定时器资源使用如下 :
1. 定时器 0 : 定时周期41.67ns, 用于RC;
2. 定时器 2 : 定时周期500ns, 用于RC 和换向时间;
3. 定时器 3 : 定时周期500ns, 用于换向时间;
4. PCA0 : 用于硬件PWM ;
# 定时器0中断服务函数说明 -- t0_int #
- 1.清除定时器中断标志
- 2.Timer0_X ++
代码如下 :
- IF MCU_48MHZ == 1
- t0_int:
- clr TCON_TF0; Clear interrupt flag
- inc Timer0_X
- reti
- ENDIF
复制代码
# 定时器2中断服务函数说明 -- t2_int #
说明 :
1. 保护现场
2. 清除中断标志位
3. Timer2_X ++
4. Skip_T2_Int 取反
5. 如果 Rcp_Timeout_Cntd =0 即RC脉冲超时计数如果为0 则退出中断,恢复现场,否则 Rcp_Timeout_Cntd --
代码如下 :
- t2_int: ; Happens every 32ms
- push PSW ; Preserve registers through interrupt
- push ACC
- clr TMR2CN0_TF2H ; Clear interrupt flag
- inc Timer2_X
- IF MCU_48MHZ == 1
- mov A, Clock_Set_At_48MHz
- jz t2_int_start ;24MHz 跳转 t2_int_start
- ;48MHz往下执行
- ; Check skip variable
- mov A, Skip_T2_Int
- jz t2_int_start; Execute this interrupt
- ; Skip_T2_Int =0 跳转 t2_int_start (把Skip_T2_Int 置 1)
- ; 否则往下执行
- mov Skip_T2_Int, #0 ; Skip_T2_Int = 0
- ajmpt2_int_exit ;
- t2_int_start:
- mov Skip_T2_Int, #1 ; Skip next interrupt
- ENDIF
- ; Update RC pulse timeout counter
- mov A, Rcp_Timeout_Cntd ; RC pulse timeout count zero?
- jz t2_int_exit ; Yes - do not decrement
- dec Rcp_Timeout_Cntd; No decrement
- t2_int_exit:
- pop ACC ; Restore preserved registers
- pop PSW
- reti
复制代码
# 定时器3中断服务函数 -- t3_int #
说明:
- 1:关闭所有中断
- 2:给定时器3的计数器赋值,下次进中断设置个短的延时
- 3:清除Flags0.T3_PENDING 标志
- 4:清除 定时器3的中断标志 TMR3CN0
- 5:打开所有的中断
代码如下 :
- t3_int: ; Used for commutation timing
- clr IE_EA ; Disable all interrupts
- anl EIE1, #7Fh ; Disable timer3 interrupts
- mov TMR3RLL, #0FAh ; Set a short delay before next interrupt
- mov TMR3RLH, #0FFh
- clr Flags0.T3_PENDING ; Flag that timer has wrapped
- anl TMR3CN0, #07Fh ; Timer3 interrupt flag cleared
- setb IE_EA ; Enable all interrupts
- reti
复制代码
作者: 逗倪豌儿 时间: 2016-10-22 16:44
本帖最后由 逗倪豌儿 于 2016-10-24 09:33 编辑
# 默认参数加载函数 -- set_default_parameters #
----------
说明 :
从_Pgm_Gov_P_Gain 地址开始 每一个字节存一个变量
参数地址 默认参数 参数意义
_Pgm_Gov_P_Gain 0FFh P 参数
_Pgm_Gov_P_Gain + 1 0FFh I 参数
_Pgm_Gov_P_Gain + 2 0FFh Governor mode 调节模式
_Pgm_Gov_P_Gain + 3 0FFh Low voltage limit 低压限制值
_Pgm_Gov_P_Gain + 4 0FFh Multi gain
_Pgm_Gov_P_Gain + 5 0FFh 保留
_Pgm_Gov_P_Gain + 6 DEFAULT_PGM_STARTUP_PWR
_Pgm_Gov_P_Gain + 7 0FFh Pwm freq PWM频率
_Pgm_Gov_P_Gain + 8 DEFAULT_PGM_DIRECTION
从 Pgm_Enable_TX_Program 地址开始 每一个字节存一个变量
参数地址 默认参数 参数意义
Pgm_Enable_TX_Program DEFAULT_PGM_ENABLE_TX_PROGRAM
Pgm_Enable_TX_Program + 1 0FFh Main rearm start
Pgm_Enable_TX_Program + 2 0FFh Governor setup target
Pgm_Enable_TX_Program + 3 0FFh Startup rpm
Pgm_Enable_TX_Program + 4 0FFh Startup accel
Pgm_Enable_TX_Program + 5 0FFh Voltage comp
Pgm_Enable_TX_Program + 6 DEFAULT_PGM_COMM_TIMING
Pgm_Enable_TX_Program + 7 0FFh Damping force
Pgm_Enable_TX_Program + 8 0FFh Governor range
Pgm_Enable_TX_Program + 9 0FFh Startup method
Pgm_Enable_TX_Program + A DEFAULT_PGM_MIN_THROTTLE
Pgm_Enable_TX_Program + B DEFAULT_PGM_MAX_THROTTLE
Pgm_Enable_TX_Program + C DEFAULT_PGM_BEEP_STRENGTH
Pgm_Enable_TX_Program + D DEFAULT_PGM_BEACON_STRENGTH
Pgm_Enable_TX_Program + E DEFAULT_PGM_BEACON_DELAY
Pgm_Enable_TX_Program + F 0FFh Throttle rate
Pgm_Enable_TX_Program + 10h DEFAULT_PGM_DEMAG_COMP
Pgm_Enable_TX_Program + 11h 0FFh Bec voltage high
Pgm_Enable_TX_Program + 12h DEFAULT_PGM_CENTER_THROTTLE
Pgm_Enable_TX_Program + 13h 0FFh 保留
Pgm_Enable_TX_Program + 14h DEFAULT_PGM_ENABLE_TEMP_PROT
Pgm_Enable_TX_Program + 15h DEFAULT_PGM_ENABLE_POWER_PROT
Pgm_Enable_TX_Program + 16h 0FFh Enable pwm input
Pgm_Enable_TX_Program + 17h 0FFh Pwm dither
Pgm_Enable_TX_Program + 18h DEFAULT_PGM_BRAKE_ON_STOP
Pgm_Enable_TX_Program + 19h DEFAULT_PGM_LED_CONTROL
# 读取全部eeprom函数: read_all_eeprom_parameters #
执行过程 :
从 Eep_Initialized_L 所代表的地址中读取数据dataL放到 Bit_Access所代表的地址中 ,
如果 读到数据dataL == 055h
把 Eep_Initialized_L +1 所代表的地址中的数据读取出来dataH,放到 Bit_Access所代表的地址中,此时
如果 dataH ==0AAh 则调用read_eeprom_read函数,读取 eeprom中的数据;
如果 dataH != 0AAh 则调用 read_eeprom_store_defaults函数 ,读取默认的eeprom中的数据
如果 读到数据dataL != 055h
则调用 read_eeprom_store_defaults函数 ,读取默认的eeprom中的数据
总结 :如果 [Eep_Initialized_L] = 055h 且 [Eep_Initialized_L +1] = 0AAh 才能调用read_eeprom_read函数,读取 eeprom中的数据;否则会调用 read_eeprom_store_defaults函数 ,读取默认的eeprom中的数据,
# 延时函数#
----------
执行一次是 42.7us 内环是 23 * 42.7 us = 982.1us = 1ms
所以 Temp2的值决定着 要延时多少ms eg : wait30ms中 要把 Temp2 = 30
- ;**** **** **** **** **** **** **** **** **** **** **** **** ****
- ;
- ; Wait xms ~(x*4*250) (Different entry points)
- ;
- ; No assumptions
- ;
- ;**** **** **** **** **** **** **** **** **** **** **** **** ****
- wait1ms:
- mov Temp2, #1
- jmp waitxms_o
- wait3ms:
- mov Temp2, #3
- jmp waitxms_o
- wait10ms:
- mov Temp2, #10
- jmp waitxms_o
- wait30ms:
- mov Temp2, #30
- jmp waitxms_o
- wait100ms:
- mov Temp2, #100
- jmp waitxms_o
- wait200ms:
- mov Temp2, #200
- jmp waitxms_o
- waitxms_o: ; Outer loop
- mov Temp1, #23
- waitxms_m: ; Middle loop
- clr A
- djnz ACC, [ DISCUZ_CODE_0 ]nbsp; ; Inner loop (42.7us - 1024 cycles)
- djnz Temp1, waitxms_m
- djnz Temp2, waitxms_o
- ret
复制代码
# pgm_start 函数 #
1. 初始化 Flash_Key_1和Flash_Key_2为 0
2. 禁能看门口
3. 初始化栈大小
4. 使能VDD电压监视器
5. 如果 是1s电池 不把VDD电压监视器设置为系统复位源,否则设置为系统复位源
6. 选择内部震荡器为系统时钟源
7. 关闭所有的MOS管和PWM输出
8. 初始化 所有IO
9. 初始化交叉开关
10. 再次关闭所有的MOS管和PWM输出
11. 清除RAM
12. 执行设置默认参数到内存中
13. 执行从eeprom中读取参数
14. 取出Pgm_Beep_Strength地址中的数据 放到Beep_Strength中
15. 把 Initial_Arm位置1
16. 禁能所有中断,
17. 发声处理
18. 执行led控制
代码如下 :
- pgm_start:
- ; Initialize flash keys to invalid values
- mov Flash_Key_1, #0
- mov Flash_Key_2, #0
- ; Disable the WDT.
- mov WDTCN, #0DEh ; Disable watchdog
- mov WDTCN, #0ADh
- ; Initialize stack
- mov SP, #0c0h ; Stack = 64 upper bytes of RAM
- ; Initialize VDD monitor
- orl VDM0CN, #080h ; Enable the VDD monitor
- IF ONE_S_CAPABLE == 0
- mov RSTSRC, #06h ; Set missing clock and VDD monitor as a reset source if not 1S capable
- ELSE
- mov RSTSRC, #04h ; Do not set VDD monitor as a reset source for 1S ESCSs, in order to avoid resets due to it
- ENDIF
- ; Set clock frequency
- mov CLKSEL, #00h ; Set clock divider to 1
- ; Switch power off
- call switch_power_off
- ; Ports initialization
- mov P0, #P0_INIT
- mov P0MDIN, #P0_DIGITAL
- mov P0MDOUT, #P0_PUSHPULL
- mov P0, #P0_INIT
- mov P0SKIP, #P0_SKIP
- mov P1, #P1_INIT
- mov P1MDIN, #P1_DIGITAL
- mov P1MDOUT, #P1_PUSHPULL
- mov P1, #P1_INIT
- mov P1SKIP, #P1_SKIP
- mov P2MDOUT, #P2_PUSHPULL
- ; Initialize the XBAR and related functionality
- Initialize_Xbar
- ; Switch power off again, after initializing ports
- 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
- ; Set beep strength
- mov Temp1, #Pgm_Beep_Strength
- mov Beep_Strength, @Temp1
- ; Set initial arm variable
- mov Initial_Arm, #1
- ; Initializing beep
- clr IE_EA ; Disable interrupts explicitly
- call wait200ms
- call beep_f1
- call wait30ms
- call beep_f2
- call wait30ms
- call beep_f3
- call wait30ms
- call led_control
复制代码
作者: 逗倪豌儿 时间: 2016-10-22 16:45
本帖最后由 逗倪豌儿 于 2016-10-24 09:21 编辑
# 外部中断0 服务函数 -- int0_int #
----------
说明:
- 1:禁能所有中断
- 2:禁能PCA中断
- 3:保护现场
- 4:置位 PSW.3,设置为 工作寄存器为Bank1 即 08H-0FH
- 5:打开所有的中断
- 6: 获取脉冲计数值
- 7:根据初始化参数 Flags2.RCP_MULTISHOT,决定是否初执行 int0_int_fall_not_multishot 函数
- 8: Temp3 = Temp2.L Temp1.H
9: 接下来就是无论哪种油门模式,都把转换为1000us 到2000us 然后把相应的油门模式置位,
作者: 逗倪豌儿 时间: 2016-10-22 16:46
标题: 附件是KEIL 编译BLHeli_S的说明文档,和原理图,欢迎拍砖
本帖最后由 逗倪豌儿 于 2016-12-26 15:06 编辑
百度云附件:BLHeli_S最小系统原理图.PDF等
作者: 逗倪豌儿 时间: 2016-10-22 16:46
占楼编辑
作者: 逗倪豌儿 时间: 2016-10-22 16:47
欢迎大家一起学,有什么问题可以一起讨论 后期会更新。。。。
作者: IGV 时间: 2016-10-22 18:32
作者: 盒子炮 时间: 2016-10-22 18:37
高端大气,看不懂……
作者: 用天6玩涡喷 时间: 2016-10-22 19:08
占楼编辑
作者: gushuai123 时间: 2016-10-22 21:22
虽然看不懂但是感觉确实高大上
作者: 板子爱毛毛 时间: 2016-10-23 06:36
仰望高端玩家。。。我就一点没看懂
作者: 阳光哥 时间: 2016-10-23 09:40
好奇bl原作者干什么的,能写出这么好的电调软件 开源 且长期更新
作者: 风中老长 时间: 2016-10-24 01:57
老外流行开源,人人为我,我为人人的精神是国人很难理解的。
此外BB1和BB2的主频分别为24.5MHz和49MHz
作者: 没事打打 时间: 2016-10-24 01:59
看不懂啊.....
作者: 逗倪豌儿 时间: 2016-10-24 09:06
这只是BLHeli_S最新源码的程序,我只是看着程序,对着MCU手册,注释下源码,方便有些人学习BLHeli源码,大家一起完善,有什么关于代码不懂的都可以发帖讨论
作者: 逗倪豌儿 时间: 2016-10-24 09:27
原作者是Steffen Skaug,传说中的S君, 我大华府的开源精神和老外和还是........,你懂的!
作者: 逗倪豌儿 时间: 2016-10-24 09:30
BB2 48M ,差不了几个钱,直接上BB2 mcu 存储大,易于后续二次开发。
作者: 风中老长 时间: 2016-10-24 21:30
挺你一下。
这个帖子最好标明你的BLS软件版本号。
此外根据不同文件分别分析源码是否会好点?
作者: theetboy 时间: 2016-10-29 01:06
BLS 比BL有啥优势啊?
作者: 逗倪豌儿 时间: 2016-10-29 11:41
S用的是硬件互补PWM(需配置死区时间),就是所谓的同步整流,可以在换向的时候,直接打开MOS管续流,而不是单纯的通过MOS管上自带的二极管续流,所以制动效果非常好,就是减速度非常快,对于穿越机来说,电调的响应速度很重要,所以S的强有力的加减速,显得很有优势。
S增加对OneShot125 \OneShot4\MULtilshot油门模式的支持,这个油门刷新率比 普通油门快,所以电调响应会更快些。
作者: theetboy 时间: 2016-10-29 17:29
逗倪豌儿 发表于 2016-10-29 11:41
S用的是硬件互补PWM(需配置死区时间),就是所谓的同步整流,可以在换向的时候,直接打开MOS管续流,而 ...
谢谢科普,但是普通bl电调不是已经支持“OneShot125 \OneShot4\MULtilshot”这些模式了吗?
我的小蜜蜂30A在f3里都开了multishot……
作者: 18513030413 时间: 2016-10-29 22:35
您好,您的blheli源码编译了吗?请问是用什么工具编译的呢?
作者: 逗倪豌儿 时间: 2016-11-2 08:47
win7下Keil编译。
作者: 逗倪豌儿 时间: 2016-11-2 13:36
嗯,目前还在注解阶段,后续整理完毕,会整理该帖,做下整理。
作者: 风中老长 时间: 2016-11-3 12:56
继续顶你一下。跑路了
作者: imdelxy 时间: 2016-11-3 13:41
好贴,必须顶
作者: zhanghankui 时间: 2016-12-14 17:16
太乱了,看不懂是哪个文件里面的
作者: 哇靠~~ 时间: 2016-12-15 11:52
作者: airpoo123 时间: 2016-12-18 11:13
技术贴必须顶! 顺便问下SL-S如何打开D-shot?
作者: sjh2100 时间: 2016-12-25 09:25
楼主威武,我正在看blheli非s源码,开头的定义变量就看的头疼。
作者: zhouyou 时间: 2016-12-26 11:38
本帖最后由 zhouyou 于 2016-12-26 11:40 编辑
以前看过BLHeli好像是v1.3的程序,就给别人建议过可以出硬件兼容的电调,可能目标不在此,所以没做。遥想现在到处是BLH固件的电调。楼主,有机会多交流
作者: 逗倪豌儿 时间: 2016-12-26 15:00
刷最新版本的bs ,飞控开启Dshot即可;
作者: 逗倪豌儿 时间: 2016-12-26 15:07
刚上传的文档中有相应资料说明
作者: 逗倪豌儿 时间: 2016-12-26 15:08
因为现在商家好多都是基于BLHeli改的,So ,硬件一般都支持BLHeli,还有个原因就是BLHeli 硬件成本的确很低,商家有利可图啊!
作者: sjh2100 时间: 2016-12-27 10:04
http://blog.dronetrest.com/what-is-blheli_s-and-why-is-it-better/
作者: sjh2100 时间: 2016-12-27 10:05
谢谢,第一遍的程序还没看完,还没到一半呢。
作者: pmp_mcu 时间: 2017-1-7 22:37
多谢分享,已经编译成功。
作者: sjh2100 时间: 2017-1-9 11:18
请教3个问题。
1) 从 Pgm_Enable_TX_Program 地址开始 每一个字节存一个变量-----这pgm是什么意思?
2)定时器wrap是什么意思?
3)Divide Comm_Period4x 4 times as default怎么翻译,是Comm_Period4x除以4还是平分4次?
作者: 逗倪豌儿 时间: 2017-1-9 18:39
1 pgm就是允许用户自行配制的参数,说白了就是用户对这些参数是可以修改配置的
2 wrap意识溢出的意识,就是定时器的计数器溢出了
3 Divide Comm_Period4x 4 times as default 默认是 4倍;是Comm_Period4x除以4
作者: sjh2100 时间: 2017-1-10 09:47
本帖最后由 sjh2100 于 2017-2-9 23:18 编辑
谢谢您的回复。pgm这样我就理解成programable,wrap如果是溢出,我觉得应该是overflow,Comm_Period4x除以4应该是Divide Comm_Period4x by 4。我能吐槽这个老外英文吗,我都先百度翻译。
我看了一下是除以16,他是用了:
swap A
anl A, #00Fh
和
swap A
anl A, #00F0h
来实现的。而不是右移4次。右移4次需要多次对C操作。
**********************************麻烦您看看以下几行程序,非s版程序。
; Load current commutation timing
mov A, Comm_Period4x_H ; Divide 4 times
swap A
anl A, #00Fh
mov Temp2, A;高四位
mov A, Comm_Period4x_H
swap A
anl A, #0F0h
mov Temp1, A;第四位
mov A, Comm_Period4x_L
swap A
anl A, #00Fh
add A, Temp1;+低字节高四位
mov Temp1, A;结果在temp2temp1中。以上没有问题
*******************************
mov A, Temp4 ; If erpm below 156k - go to normal case
subb A, #2
jc ($+4)
clr Flags0.HIGH_RPM ; Clear high rpm bit
mov Temp1, #2 ; Set timing reduction
mov A, Temp4 ; Divide by 2 4 times这里的除法与上面的很不一样
swap A
mov Temp7, A; ;temp7=低字节高字节
mov Temp4, #0
mov A, Temp3
swap A ;temp3保留高字节
anl A, #0Fh
orl A, Temp7
mov Temp3, A ;temp3=高字节低4位_低字节高四位。感觉这行代码没有完成 Divide by 2 4 times的操作。个人以为是bug。
后面几行如下,应该和除法没关系。
clr C
mov A, Temp3
subb A, Temp1
mov Temp3, A
jc load_min_time_fast ; Check that result is still positive
********************
2017——01——10今天下午github无法登陆了!要河蟹?
********************
2017-02-09 在变量定义区发现了:
ISEG AT 080h ; //内部间接寻址绝对数据段
Pgm_Gov_P_Gain: DS 1 ;Programmed governorP gain
故pgm就是Programmed 。
作者: sjh2100 时间: 2017-1-12 09:48
只看红色即可
djnz Startup_Zc_Timeout_Cntd, comp_check_timeout_extend_timeout;▲跳出
comp_check_timeout_timeout_extended:
setb Flags1.COMP_TIMED_OUT
ajmp setup_comm_wait
comp_check_timeout_extend_timeout:;▲跳入。为何用djnz不是往前跳?
call setup_zc_scan_timeout
comp_check_timeout_not_timed_out:
comp_read_ok_jmp:
ajmp comp_check_timeout
clr Flags1.COMP_TIMED_OUT
;ret??? 原文无此ret,下面为另一子程序。奇怪啊
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Setup commutation timing routine
;
; No assumptions
;
; Sets up and starts wait from commutation to zero cross
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
setup_comm_wait:
clr EA
anl EIE1, #7Fh ; Disable timer3 interrupts
mov TMR3CN, #00h ; Timer3 disabled and interrupt flag cleared
mov TMR3L, Wt_Comm_Start_L
mov TMR3H, Wt_Comm_Start_H
mov TMR3CN, #04h ; Timer3 enabled and interrupt flag cleared
; Setup next wait time
mov TMR3RLL, Wt_Adv_Start_L
mov TMR3RLH, Wt_Adv_Start_H
setb Flags0.T3_PENDING
orl EIE1, #80h ; Enable timer3 interrupts
setb EA ; Enable interrupts again
;原文也木有此行no ret ????????????????
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Evaluate comparator integrity
;
; No assumptions
;
; Checks comparator signal behaviour versus expected behaviour
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
evaluate_comparator_integrity:
mov A, Flags1
作者: R/C-man 时间: 2017-1-12 15:28
这个好,顶顶。
作者: 逗倪豌儿 时间: 2017-1-12 16:44
你这里面怎么突然冒出个Temp3,上面都没提到,无法给你解释
作者: 逗倪豌儿 时间: 2017-1-12 16:55
1: Startup_Zc_Timeout_Cntd = 0 就意味着超时了所以要去执行超时处理,直接就往下执行 comp_check_timeout_timeout_extended, 如果不是0 那么就执行comp_check_timeout_extend_timeout ,再去检查下比较器,有什么不妥的吗?
2 : ret??? 原文无此ret,下面为另一子程序。奇怪啊 :这有什么奇怪的 ,这仅仅是个代码段,又不是函数,非得有ret不行,没有ret 就接着往下走执行 setup_comm_wait
3:原文也木有此行no ret ???????????????? 这和第二个问题一样,没有ret 就接着往下顺序执行
PS:你这是汇编水平问题,学学汇编的基本语法吧还是·····
作者: sjh2100 时间: 2017-1-12 19:41
感谢回复。
说的对。
作者: wuduxiaoqiang 时间: 2017-2-15 09:06
给楼主这样无私的分享赞一个
作者: -爱好者- 时间: 2017-2-15 10:13
好东西,做个记号。
作者: 735998700 时间: 2017-2-20 17:15
你好,有幸看到你发的这个帖子,刚好有这个需求,冒昧的打扰下可以帮忙开发一款BLS电调软件吗,付费开发
作者: 逗倪豌儿 时间: 2017-2-21 12:41
你需要改什么需求,还是怎么?
作者: 735998700 时间: 2017-2-21 14:50
我手上是有自己做好的硬件,就是根据我的硬件IO口来改下软件就可以了,我自己软件不懂,所以想请你帮个忙,方便加我QQ细聊吗735998700
作者: xxdcq 时间: 2017-2-21 19:59
51汇编?
作者: snowbun 时间: 2017-3-18 20:10
做个记号,慢慢消化,虽然消化不了
作者: 294689006 时间: 2017-7-17 11:16
留下记号,学习硬件
作者: iamfool 时间: 2017-7-17 17:43
请教楼主,为什么不用C呢?
作者: 897543670 时间: 2017-7-20 19:51
懵进懵出
作者: 逗倪豌儿 时间: 2017-7-27 19:58
flash 装不下
作者: 雨辰h 时间: 2018-10-9 00:19
这个太有用了,谢谢分享!
作者: 2791117081@ 时间: 2018-11-14 20:43
有硬件电路图吗 想做一个看看
作者: QJ寻解惑 时间: 2019-2-26 19:54
本帖最后由 QJ寻解惑 于 2019-2-26 20:04 编辑
楼主您好!我现在使用了BLHeli_s源码,原理图如下:
文件我选了C.INC ,确保了引脚没有错,出现的问题是电机不能顺畅的转起来,输入的信号越大抖动越明显。当我只焊接电机的两个相时,它抖了一几秒钟后会启动保护,所以我觉得不是缺相的问题,应该是程序哪里不兼容了。运转视频如下:
https://v.qq.com/x/page/a0842w86gfl.html
希望楼主能给个联系方式,顺便提点建议。
QQ: 2467863212
欢迎光临 5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年) (http://bbs.5imx.com/) |
Powered by Discuz! X3.3 |