5iMX宗旨:分享遥控模型兴趣爱好

5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年)
查看: 15436|回复: 60
打印 上一主题 下一主题

BLHeli_S 源码解析讨论

[复制链接]
跳转到指定楼层
楼主
发表于 2016-10-22 16:41 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式
本帖最后由 逗倪豌儿 于 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
复制代码



欢迎继续阅读楼主其他信息

主题

  • 没有相关信息
  • 没有相关信息
  • 没有相关信息
60
发表于 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

原理图.png (89.75 KB, 下载次数: 53)

原理图.png
59
发表于 2018-11-14 20:43 | 只看该作者
有硬件电路图吗 想做一个看看
58
发表于 2018-10-9 00:19 | 只看该作者
这个太有用了,谢谢分享!
57
 楼主| 发表于 2017-7-27 19:58 | 只看该作者
iamfool 发表于 2017-7-17 17:43
请教楼主,为什么不用C呢?

flash 装不下

56
发表于 2017-7-20 19:51 | 只看该作者
懵进懵出
来自苹果客户端来自苹果客户端
55
发表于 2017-7-17 17:43 | 只看该作者
请教楼主,为什么不用C呢?
54
发表于 2017-7-17 11:16 | 只看该作者
留下记号,学习硬件
53
发表于 2017-3-18 20:10 | 只看该作者
做个记号,慢慢消化,虽然消化不了
52
发表于 2017-2-21 19:59 | 只看该作者
逗倪豌儿 发表于 2016-10-22 16:44
# 默认参数加载函数 -- set_default_parameters #

----------

51汇编?

51
发表于 2017-2-21 14:50 | 只看该作者
逗倪豌儿 发表于 2017-2-21 12:41
你需要改什么需求,还是怎么?

我手上是有自己做好的硬件,就是根据我的硬件IO口来改下软件就可以了,我自己软件不懂,所以想请你帮个忙,方便加我QQ细聊吗735998700
50
 楼主| 发表于 2017-2-21 12:41 | 只看该作者
735998700 发表于 2017-2-20 17:15
你好,有幸看到你发的这个帖子,刚好有这个需求,冒昧的打扰下可以帮忙开发一款BLS电调软件吗,付费开发

...

你需要改什么需求,还是怎么?
49
发表于 2017-2-20 17:15 | 只看该作者
你好,有幸看到你发的这个帖子,刚好有这个需求,冒昧的打扰下可以帮忙开发一款BLS电调软件吗,付费开发

48
发表于 2017-2-15 10:13 | 只看该作者
好东西,做个记号。
47
发表于 2017-2-15 09:06 | 只看该作者
给楼主这样无私的分享赞一个
46
发表于 2017-1-12 19:41 | 只看该作者
逗倪豌儿 发表于 2017-1-12 16:55
1: Startup_Zc_Timeout_Cntd = 0 就意味着超时了所以要去执行超时处理,直接就往下执行 comp_check_time ...

感谢回复。
说的对。

45
 楼主| 发表于 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:你这是汇编水平问题,学学汇编的基本语法吧还是·····





44
 楼主| 发表于 2017-1-12 16:44 | 只看该作者
sjh2100 发表于 2017-1-10 09:47
谢谢您的回复。pgm这样我就理解成programable,wrap如果是溢出,我觉得应该是overflow,Comm_Per ...

你这里面怎么突然冒出个Temp3,上面都没提到,无法给你解释
43
发表于 2017-1-12 15:28 | 只看该作者
这个好,顶顶。
42
发表于 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



您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

关闭

【站内推荐】上一条 /2 下一条

快速回复 返回顶部 返回列表