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

所以时钟配置程序如下 :
  1.     ;****************************** 设置系统时钟为24M *****************************
  2.     ;
  3.     ; 1:时钟源为 HFOSC1 (48M)  ,然后配置为 2分频
  4.     ; 2
  5.     ;
  6.     ;*****************************************************************************
  7.     Set_MCU_Clk_24MHz MACRO
  8.     mov CLKSEL, #13h; Set clock to 24MHz
  9.     mov SFRPAGE, #10h
  10.     mov PFE0CN, #00h; Set flash timing for 24MHz
  11.     mov SFRPAGE, #00h
  12.     mov Clock_Set_At_48MHz, #0
  13.     ENDM
复制代码
  1.    ;****************************** 设置系统时钟为48M *****************************
  2.     ;
  3.     ; 1:时钟源为 HFOSC1 (48M) SYSCLK 为  clock source(原时钟的1分频)
  4.     ; 1:
  5.     ;
  6.     ;*****************************************************************************
  7.     Set_MCU_Clk_48MHz MACRO
  8.     mov SFRPAGE, #10h
  9.     mov PFE0CN, #30h; Set flash timing for 48MHz
  10.     mov SFRPAGE, #00h
  11.     mov CLKSEL, #03h; Set clock to 48MHz
  12.     mov Clock_Set_At_48MHz, #1
  13.     ENDM
复制代码

##  1.1页寄存器使用说明  ##

你所用的每个寄存器都有个寄存地址,而寄存器页的页码就是指向你的寄存地址的。当你需要使用某个寄存器时,就必须把SFRPAGE指向你所要用的寄存器页上面去
举例如下:
  1.     void Init_ADC0()

  2.     {

  3.      char SFRPAGE_SAVE = SFRPAGE;  // 保存当前的SFR页

  4.      SFRPAGE = ADC0_PAGE;          //把页码改到以下几个寄存器所在的页码

  5.      ADC0CN = 0x00;                // 每次向AD0BUSY 写1 时启动ADC0 转换

  6.      REF0CN = 0x03;                // ADC0电压基准取自VREF0引脚,内部电压基准缓冲器工作

  7.      AMX0CF = 0x00;                // AIN inputs are single-ended (default)

  8.      AMX0SL = 0x00;                // 选择ADC 输入为AIN0.0   

  9.                                   // ADC0CF = (SYSCLK/SAR_CLK) << 3; // ADC 转换时钟 = 2.5MHz

  10.      ADC0CF |= 0x00;  // PGA 增益 = 1 (默认)

  11.                                   // EIE2 |= 0x02;   // 允许ADC0 转换结束中断

  12.      SFRPAGE = SFRPAGE_SAVE;      //回复寄存器页

  13.     }
复制代码



这个程序中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模式

代码如下 :
  1.   Enable_Power_Pwm_Module MACRO
  2.     IF FETON_DELAY == 0
  3.             mov PCA0CPM0, #4Ah  ; Enable comparator of module, enable match, set pwm mode
  4.     ELSE
  5.             mov PCA0CPM0, #42h  ; Enable comparator of module, set pwm mode
  6.     ENDIF
  7.     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倍

代码如下 :

  1. Initialize_Adc MACRO
  2.             mov REF0CN, #0Ch; Set vdd (3.3V) as reference. Enable temp sensor and bias
  3.     IF MCU_48MHZ == 0
  4.             mov ADC0CF, #59h; ADC clock 2MHz, PGA gain 1
  5.     ELSE
  6.             mov ADC0CF, #0B9h   ; ADC clock 2MHz, PGA gain 1
  7.     ENDIF
  8.             mov ADC0MX, #10h; Select temp sensor input
  9.             mov ADC0CN0, #80h   ; ADC enabled
  10.             mov ADC0CN1, #01h   ; Common mode buffer enabled
  11.     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 ++

代码如下 :

  1.     IF MCU_48MHZ == 1
  2.             t0_int:
  3.     clr TCON_TF0; Clear interrupt flag
  4.             inc Timer0_X
  5.     reti
  6.     ENDIF
复制代码


# 定时器2中断服务函数说明 -- t2_int #

说明 :

1. 保护现场
2. 清除中断标志位
3. Timer2_X ++
4. Skip_T2_Int 取反
5. 如果 Rcp_Timeout_Cntd =0 即RC脉冲超时计数如果为0 则退出中断,恢复现场,否则 Rcp_Timeout_Cntd --

代码如下 :

  1.    t2_int: ; Happens every 32ms
  2.             push        PSW                 ; Preserve registers through interrupt
  3.             push        ACC
  4.             clr TMR2CN0_TF2H        ; Clear interrupt flag
  5.             inc Timer2_X
  6.     IF MCU_48MHZ == 1
  7.             mov A, Clock_Set_At_48MHz
  8.             jz  t2_int_start         ;24MHz 跳转 t2_int_start
  9.                                                      ;48MHz往下执行
  10.                                                            ; Check skip variable
  11.             mov A, Skip_T2_Int
  12.                    jz  t2_int_start; Execute this interrupt
  13.                                                     ; Skip_T2_Int =0 跳转 t2_int_start (把Skip_T2_Int 置 1)
  14.                                                     ; 否则往下执行
  15.             mov Skip_T2_Int, #0 ; Skip_T2_Int = 0
  16.             ajmpt2_int_exit ;

  17.     t2_int_start:
  18.                    mov Skip_T2_Int, #1 ; Skip next interrupt
  19.     ENDIF

  20.     ; Update RC pulse timeout counter
  21.             mov A, Rcp_Timeout_Cntd ; RC pulse timeout count zero?
  22.     jz  t2_int_exit                 ; Yes - do not decrement

  23.             dec Rcp_Timeout_Cntd; No decrement

  24.     t2_int_exit:
  25.             pop ACC                         ; Restore preserved registers
  26.             pop PSW
  27.     reti
复制代码


# 定时器3中断服务函数 -- t3_int #

说明:

- 1:关闭所有中断
- 2:给定时器3的计数器赋值,下次进中断设置个短的延时
- 3:清除Flags0.T3_PENDING 标志
- 4:清除 定时器3的中断标志 TMR3CN0
- 5:打开所有的中断

代码如下 :

  
  1. t3_int: ; Used for commutation timing
  2.             clr IE_EA                           ; Disable all interrupts
  3.             anl EIE1, #7Fh                  ; Disable timer3 interrupts
  4.             mov TMR3RLL, #0FAh          ; Set a short delay before next interrupt
  5.             mov TMR3RLH, #0FFh
  6.             clr Flags0.T3_PENDING   ; Flag that timer has wrapped
  7.             anl TMR3CN0, #07Fh          ; Timer3 interrupt flag cleared
  8.             setb IE_EA                           ; Enable all interrupts
  9.     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

  
  1. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2.     ;
  3.     ; Wait xms ~(x*4*250)  (Different entry points)
  4.     ;
  5.     ; No assumptions
  6.     ;
  7.     ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  8.     wait1ms:
  9.             mov         Temp2, #1
  10.             jmp                 waitxms_o

  11.     wait3ms:
  12.             mov         Temp2, #3
  13.             jmp         waitxms_o

  14.     wait10ms:   
  15.             mov         Temp2, #10
  16.             jmp         waitxms_o

  17.     wait30ms:   
  18.             mov         Temp2, #30
  19.             jmp         waitxms_o

  20.     wait100ms:  
  21.             mov         Temp2, #100
  22.             jmp         waitxms_o

  23.     wait200ms:  
  24.             mov         Temp2, #200
  25.             jmp         waitxms_o

  26.     waitxms_o:  ; Outer loop
  27.             mov         Temp1, #23
  28.     waitxms_m:  ; Middle loop
  29.             clr         A
  30.             djnz        ACC, [        DISCUZ_CODE_0        ]nbsp; ; Inner loop (42.7us - 1024 cycles)
  31.             djnz        Temp1, waitxms_m
  32.             djnz        Temp2, waitxms_o

  33.     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控制

代码如下 :

      
  1. pgm_start:
  2.             ; Initialize flash keys to invalid values
  3.             mov Flash_Key_1, #0
  4.             mov Flash_Key_2, #0
  5.             ; Disable the WDT.
  6.             mov WDTCN, #0DEh        ; Disable watchdog
  7.             mov WDTCN, #0ADh        
  8.             ; Initialize stack
  9.             mov SP, #0c0h           ; Stack = 64 upper bytes of RAM
  10.             ; Initialize VDD monitor
  11.             orl VDM0CN, #080h       ; Enable the VDD monitor
  12.         IF ONE_S_CAPABLE == 0      
  13.             mov     RSTSRC, #06h    ; Set missing clock and VDD monitor as a reset source if not 1S capable
  14.         ELSE
  15.             mov     RSTSRC, #04h    ; Do not set VDD monitor as a reset source for 1S ESCSs, in order to avoid resets due to it
  16.         ENDIF
  17.             ; Set clock frequency
  18.             mov CLKSEL, #00h        ; Set clock divider to 1
  19.             ; Switch power off
  20.             call    switch_power_off
  21.             ; Ports initialization
  22.             mov P0, #P0_INIT
  23.             mov P0MDIN, #P0_DIGITAL
  24.             mov P0MDOUT, #P0_PUSHPULL
  25.             mov P0, #P0_INIT
  26.             mov P0SKIP, #P0_SKIP               
  27.             mov P1, #P1_INIT
  28.             mov P1MDIN, #P1_DIGITAL
  29.             mov P1MDOUT, #P1_PUSHPULL
  30.             mov P1, #P1_INIT
  31.             mov P1SKIP, #P1_SKIP               
  32.             mov P2MDOUT, #P2_PUSHPULL               
  33.             ; Initialize the XBAR and related functionality
  34.             Initialize_Xbar
  35.             ; Switch power off again, after initializing ports
  36.             call    switch_power_off
  37.             ; Clear RAM
  38.             clr A               ; Clear accumulator
  39.             mov Temp1, A            ; Clear Temp1
  40.             clear_ram:  
  41.             mov @Temp1, A           ; Clear RAM
  42.             djnz Temp1, clear_ram   ; Is A not zero? - jump
  43.             ; Set default programmed parameters
  44.             call    set_default_parameters
  45.             ; Read all programmed parameters
  46.             call read_all_eeprom_parameters
  47.             ; Set beep strength
  48.             mov Temp1, #Pgm_Beep_Strength
  49.             mov Beep_Strength, @Temp1
  50.             ; Set initial arm variable
  51.             mov Initial_Arm, #1
  52.             ; Initializing beep
  53.             clr IE_EA           ; Disable interrupts explicitly
  54.             call wait200ms  
  55.             call beep_f1
  56.             call wait30ms
  57.             call beep_f2
  58.             call wait30ms
  59.             call beep_f3
  60.             call wait30ms
  61.             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
盒子炮 发表于 2016-10-22 18:37
高端大气,看不懂……

这只是BLHeli_S最新源码的程序,我只是看着程序,对着MCU手册,注释下源码,方便有些人学习BLHeli源码,大家一起完善,有什么关于代码不懂的都可以发帖讨论


作者: 逗倪豌儿    时间: 2016-10-24 09:27
阳光哥 发表于 2016-10-23 09:40
好奇bl原作者干什么的,能写出这么好的电调软件 开源 且长期更新

原作者是Steffen Skaug,传说中的S君, 我大华府的开源精神和老外和还是........,你懂的!


作者: 逗倪豌儿    时间: 2016-10-24 09:30
风中老长 发表于 2016-10-24 01:57
老外流行开源,人人为我,我为人人的精神是国人很难理解的。

此外BB1和BB2的主频分别为24.5MHz和49MHz

BB2 48M ,差不了几个钱,直接上BB2 mcu 存储大,易于后续二次开发。


作者: 风中老长    时间: 2016-10-24 21:30
挺你一下。

这个帖子最好标明你的BLS软件版本号。
此外根据不同文件分别分析源码是否会好点?

作者: theetboy    时间: 2016-10-29 01:06
BLS 比BL有啥优势啊?

作者: 逗倪豌儿    时间: 2016-10-29 11:41
theetboy 发表于 2016-10-29 01:06
BLS 比BL有啥优势啊?

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
18513030413 发表于 2016-10-29 22:35
您好,您的blheli源码编译了吗?请问是用什么工具编译的呢?

win7下Keil编译。


作者: 逗倪豌儿    时间: 2016-11-2 13:36
风中老长 发表于 2016-10-24 21:30
挺你一下。

这个帖子最好标明你的BLS软件版本号。

嗯,目前还在注解阶段,后续整理完毕,会整理该帖,做下整理。


作者: 风中老长    时间: 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
airpoo123 发表于 2016-12-18 11:13
技术贴必须顶! 顺便问下SL-S如何打开D-shot?

刷最新版本的bs ,飞控开启Dshot即可;


作者: 逗倪豌儿    时间: 2016-12-26 15:07
sjh2100 发表于 2016-12-25 09:25
楼主威武,我正在看blheli非s源码,开头的定义变量就看的头疼。

刚上传的文档中有相应资料说明


作者: 逗倪豌儿    时间: 2016-12-26 15:08
zhouyou 发表于 2016-12-26 11:38
以前看过BLHeli好像是v1.3的程序,就给别人建议过可以出硬件兼容的电调,可能目标不在此,所以没做。遥想现 ...

因为现在商家好多都是基于BLHeli改的,So ,硬件一般都支持BLHeli,还有个原因就是BLHeli 硬件成本的确很低,商家有利可图啊!


作者: sjh2100    时间: 2016-12-27 10:04
theetboy 发表于 2016-10-29 01:06
BLS 比BL有啥优势啊?

http://blog.dronetrest.com/what-is-blheli_s-and-why-is-it-better/


作者: sjh2100    时间: 2016-12-27 10:05
逗倪豌儿 发表于 2016-12-26 15:07
刚上传的文档中有相应资料说明

谢谢,第一遍的程序还没看完,还没到一半呢。


作者: pmp_mcu    时间: 2017-1-7 22:37
多谢分享,已经编译成功。

作者: sjh2100    时间: 2017-1-9 11:18
逗倪豌儿 发表于 2016-11-2 13:36
嗯,目前还在注解阶段,后续整理完毕,会整理该帖,做下整理。

请教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
sjh2100 发表于 2017-1-9 11:18
请教3个问题。
1) 从 Pgm_Enable_TX_Program 地址开始 每一个字节存一个变量-----这pgm是什么意思?
2 ...

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 编辑
逗倪豌儿 发表于 2017-1-9 18:39
1 pgm就是允许用户自行配制的参数,说白了就是用户对这些参数是可以修改配置的
2 wrap意识溢出的意识, ...

谢谢您的回复。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
逗倪豌儿 发表于 2017-1-9 18:39
1 pgm就是允许用户自行配制的参数,说白了就是用户对这些参数是可以修改配置的
2 wrap意识溢出的意识, ...

只看红色即可
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
sjh2100 发表于 2017-1-10 09:47
谢谢您的回复。pgm这样我就理解成programable,wrap如果是溢出,我觉得应该是overflow,Comm_Per ...

你这里面怎么突然冒出个Temp3,上面都没提到,无法给你解释

作者: 逗倪豌儿    时间: 2017-1-12 16:55
sjh2100 发表于 2017-1-12 09:48
只看红色即可
djnz Startup_Zc_Timeout_Cntd, comp_check_timeout_extend_timeout;▲跳出
comp_check_ ...

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
逗倪豌儿 发表于 2017-1-12 16:55
1: Startup_Zc_Timeout_Cntd = 0 就意味着超时了所以要去执行超时处理,直接就往下执行 comp_check_time ...

感谢回复。
说的对。


作者: 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-20 17:15
你好,有幸看到你发的这个帖子,刚好有这个需求,冒昧的打扰下可以帮忙开发一款BLS电调软件吗,付费开发

...

你需要改什么需求,还是怎么?

作者: 735998700    时间: 2017-2-21 14:50
逗倪豌儿 发表于 2017-2-21 12:41
你需要改什么需求,还是怎么?

我手上是有自己做好的硬件,就是根据我的硬件IO口来改下软件就可以了,我自己软件不懂,所以想请你帮个忙,方便加我QQ细聊吗735998700

作者: xxdcq    时间: 2017-2-21 19:59
逗倪豌儿 发表于 2016-10-22 16:44
# 默认参数加载函数 -- set_default_parameters #

----------

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
iamfool 发表于 2017-7-17 17:43
请教楼主,为什么不用C呢?

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