找回密码
 立即注册

QQ登录

只需一步,快速开始

开启左侧

航模电调 DIY —— 第2季 , Mini51 如何控制 BLDC 转动

[复制链接]
Angus 发表于 2015-9-23 17:49:15 | 显示全部楼层 |阅读模式
本帖最后由 Angus 于 2018-11-4 20:06 编辑

CPU 控制 BLDC 转动的过程是检过零与换相轮流做,如下图, 鼠标左击看大图。

13.png


看上图,黑块时间是检测过零时间,约占用了 CPU 的 1/4 时间。

这里说一下 Mini51 D版芯片的自动换相功能:
    每次换相后,要改变驱动 上MOS 的  PWM 输出引脚,改变驱动 下MOS 的 GPIO 输出 0 或 1 的状态,还要改变比较器的输入脚——换一相检测过 0 了。 Mini51 系列有个 换相寄存器:PWM-> PHCHG——phase change 之意, 写这一个寄存器,完成上面三件事。


Untitled.png

    还有一个下一相寄存器:PWM-> PHCHGNXT,这个寄存器定义与上述寄存器相同,Timer0 溢出时,PWM-> PHCHGNXT 的值会自动写入换相寄存器 PWM-> PHCHG 中。在 Timer1 中断代码里,检到过 0 时,就准备好下一相数据 PWM-> PHCHGNXT,并写好 Timer0 的溢出时间——换相时刻点

Mini51 A 版芯片无此功能,购买芯片要问清楚,要买 D 版芯片。

void TMR1_IRQHandler(void)                                    
{  
    TIMER0->CMPR   = ~0 ;                                       // 拉长 Timer0 时间,防止检过 0 时 Timer0 自动换相了
    TIMER1->ISR      = ~0 ;                                                             // 清中断标志                  
    DeadLine_Detec = PeriodNow << 1 ;                                           // 检过 0 超时时间, 防止中断内死等
    do{
        if((*pPhase) & DetectUpBit){                     
              if(ACMP->SR & AcmpOutBit){ ++StepCount; break; }           //  检到上过 0
        }
        else{                                    
              if((ACMP->SR & AcmpOutBit)==0){ ++StepCount; break;}    // 检到下过 0
        }
    }while(TIMER0->DR < DeadLine_Detec) ;   
    PeriodLast = (TIMER1->DR - ZeroTick) & 0xFFFFFF ;                   // 两次过 0 时刻相减,得当前周期。
    ZeroTick   = TIMER1->DR ;                                                       // 本次过 0 时刻,下次计算周期用
    PeriodNow  = (PeriodNow + PeriodLast)>>1 ;                             // 软件滤波   
    if(PeriodNow > Period_Max) PeriodNow = Period_Max ;  
    TIMER0->CMPR  = TIMER0->DR + (PeriodNow >> 1) ;                //  延时周期的 1/2 时间后,换相
    TIMER1->CMPR  = TIMER1->DR + ((PeriodNow*3)>>2)  ;           //  延时周期的 3/4 时间后, Timer1 再次中断检过 0
    if(++pPhase   > pPhaseEnd) pPhase -= 6 ;   
    PWM-> PHCHGNXT = *pPhase ;      // 这是下一相数据, Timer0 计数到 CMPR 时会自动写入PWM-> PHCHG 改变输出
}

改变导通角:
   
改变 TIMER0 的定时即可,比如写成 TIMER0->CMPR  = TIMER0->DR + (PeriodNow >> 2) ; 过 0 后 1/4 周期换相,就等于换相超前了 15 度。


正反转
    转向由指针 pPhase 指向的数组决定。指向不同的数组,不仅可以实现正反转,还可改变上 MOS 或下 MOS 做 PWM等功能。  

150 度方波
     Timer1 中断返回时刚好是过 0 时刻,这时立即换成两相同时输出,Timer0 定时到会自动变成下一相输出,这样就成了 150度方波 。

下载 Mini51 电调全部代码,请到"航模电调 DIY——第3季 Mini51ZDE 电调代码: http://www.nuvoton-mcu.com/forum.php?mod=viewthread&tid=1459&extra=page%3D1


















回复

使用道具 举报

xiaoxiao2013 发表于 2015-9-25 15:06:08 | 显示全部楼层
有两个问题需要请教版主
第一个:过零检测电路是有延时的,代码里用周期的一半其实已经超过了30度,如果速度非常高,有可能换相滞后的严重;
第二个:每次换相时立即配置过零比较器,比较器配置后就会工作,当执行定时器1中断时,不论是否到了过零点,比较器都会有输出,这样岂不是检测不准过零位置?
以上两个问题不知我理解的对不对,希望能得到版主的指点,非常感谢。
回复 支持 反对

使用道具 举报

 楼主| Angus 发表于 2015-9-25 15:53:36 | 显示全部楼层
本帖最后由 Angus 于 2015-10-31 11:16 编辑
xiaoxiao2013 发表于 2015-9-25 15:06
有两个问题需要请教版主
第一个:过零检测电路是有延时的,代码里用周期的一半其实已经超过了30度,如果速 ...

第一个问题:检过 0 电路延时长短与 RC 常数有关,我们推荐电路 RC 常数是 7us, 20万转的电转速换相周期是 50us, 7us 延时影响不大。还可以调整 Timer0 的时间,把 RC 延时补尝回来 。为了容易理解,这里没讲这么复杂。

第二个问题:换相的同时换了比较器输入脚,比较器输出马上改变,但这时软件不做判断,过一段时间 Timer1 中断时,才判断比较器的输出是否过0。配置定时器时,保证Timer0 先换相,一段时间后 Timer1 才发生中断开始判是否过 0 。
回复 支持 反对

使用道具 举报

ketose 发表于 2016-4-16 12:35:12 | 显示全部楼层
学习了。。。 null.png null1.png null2.png null3.png null4.png null5.png null6.png null7.png null8.png null9.png
回复 支持 反对

使用道具 举报

hnxtwangqiang 发表于 2016-8-21 21:42:07 | 显示全部楼层
版主您好:
请教一个问题,当TIMER1在中断里面查询过零点的时候,此时PWM信号在工作状态,比较器的输入端会有PWM信号在里面,而您这边的RC常数非常小,不能滤掉PWM的信号,比较器输出的信号应该也是和PWM同步变化的,您这边是如何判断过零点的?
回复 支持 反对

使用道具 举报

 楼主| Angus 发表于 2016-9-28 17:40:15 | 显示全部楼层
hnxtwangqiang 发表于 2016-8-21 21:42
版主您好:
请教一个问题,当TIMER1在中断里面查询过零点的时候,此时PWM信号在工作状态,比较器的输入端 ...

低速启转时,换相周期很长,多检测几次以确认是过0点,不会影响转动。速度加快后,反电势变强, PWM 影响就可以忽略了
回复 支持 反对

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则

新唐MCU