正点原子 发表于 2022-8-22 10:03:13

《DMF407电机控制专题教程_V1.0》第25章 直流无刷电机无感控制

本帖最后由 正点原子 于 2022-8-20 15:06 编辑

1)实验平台:正点原子DMF407电机开发板
2)平台购买地址: https://detail.tmall.com/item.htm?&id=677230699323
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/docs/boards/stm32dj/ATK-DMF407.html
4)对正点原子电机开发板感兴趣的同学可以加群讨论: 592929122





第25章 直流无刷电机无感控制

      前面的课程我们学习了无刷电机的有感控制,即通过霍尔传感器检测转子位置,实现六步换相,从而使无刷电机旋转起来。本章我们开始来学习无感控制,即不通过位置传感器实现无刷电机的基本驱动。
本章分为如下几个小节:
25.1 直流无刷电机的无感驱动介绍
25.2 硬件设计
25.3 程序设计
25.4 下载验证


25.1 直流无刷电机的无感驱动介绍
      如前面有感控制21.3小节所述,无刷直流电机的工作原理必须有转子磁场位置的信息,以控制逆变器功率器件的开/关实现绕组的换相。例如,三相六状态运行的无刷电机在内部安放三个转子位置传感器确定六个换相点时刻。传统的无刷直流电机转子位置信息是采用机电式或电子式传感器直接检测,如霍尔传感器、光电传感器等,然而,在实际应用中发现,在电机内部安放转子位置传感器有以下问题:
1)在某些高温、低温、高振动、潮湿、污浊空气和高干扰等恶劣的工作环境下由于位置传感器的存在使系统的可靠性降低。
2)位置传感器电气连接线多,不便于安装,而且易引入电磁干扰。
3)传感器的安装精度直接影响电机运行性能。特别是在多极电机安装精度难以保证
4)位置传感器占用电机结构空间,限制了电机的小型化。
      所以无传感器驱动的方式已成为一个新的技术发展方向,虽然无传感器的方式会降低控制精度,但好处是使系统能够在恶劣的工作环境下可靠运行,同时使电机的结构变得简单,体积减小、安装更方便、成本降低。
      无感检测的主要方法有:反电动势过零点检测方法、反电动势积分范有电压比较法、反电动势积分及领相环法、续流二极管法、反电动势三次谱波检测法、感侧量法、C(0) 函数法、扩展卡尔曼滤波法、状态观测器法等。
      这里我们主要使用反电动势过零点检测方法。它的主要核心就是通过检测定子绕组的反电动势过零点来判断转子当前的位置。与有霍尔的方案相比,最明显的优点就是降低了成本、减小了体积。并且电机引线仅 8 根变为 3 根,使接线调试都大为简化。另外,霍尔传感器容易受到温度和磁场等外界环境的影响,故障率较高。因此,无霍尔 BLDC 得到越来越多的应用,在很多场合正逐步取代有霍尔 BLDC。介绍三相 BLDC 电机的无霍尔控制理论。根据特定的应用场合,具体的实现方法会有所不同。
25.1.1 反电动势法控制 BLDC 电机的原理
三相六状态120°通电方式运行的无刷电机在任意时刻总是两相通电工作,另相绕组是浮地不导通的。这时候非导通绕组的端电压(从绕组端部到直流地之间)或相电压(从绕组端部到三相绕组中心点之间)就反映出该相绕组的感应电动势(BEMF,BackElectromotiveForce)。BLDC 电机的 BEMF 波形随转子的位置和速度变化,整体上呈现为梯形。
图 25.1.1.1 给出了电机旋转一个电周期中电流和反电电势的波形,其中实线代表电流,虚线代表反电动势,横坐标为电机旋转的电气角度,根据 BLDC 的“六步换向”控制理论,我们知道在任意时刻三相 BLDC 另有两相通电,另一相开路,三相两两导通,共有6种组合,以一定的顺序每 60°变化一次,这样产生旋转的磁场,拉动永磁体转子跟着转动。这里的 60°指的是电气角度,一个电周期可能并不是对应一个完整的转子机械转动周期。完成一圈机械转动要重复的电周期数取决于转子的磁极对数。每对转子磁极需要完成一个电周期,因此,电周期数/转数等于转子磁极对数。

图25.1.1.1 电流和反电动势波形
控制 BLDC 的关键就是确定换相的时刻。由上图可以看出,在每两个换相点的中间都对应一个反电动势的磁极改变的点,即反电点势从正变化为负或者从负变化为正的点,称为过零点。利用反电动势的这个特性,只要能够准确检测出反电动势的过零点,将其延迟 30°,即为需要换相的时刻。
25.1.2 反电动势的检测方法
从图25.1.1.1中可以看到每次的反电动势过零点都发生在不通电的那一相。例如图25.1.1.1中第一个60°内,A相电流为正,B相电流为负,C相电流为零,这说明电机AB相通电,电流从A相流入B相,C相为开路。反电动势的过零点正好出现在C相。而且由于C相不通电,没有电流,其相电压就与反电动势有直接的对应关系。
在众多检测转子的位置方法中,反电动势检测法最为成熟、应用最广泛的方法,该方法简单可靠、容易实现,但是这种方法也存在一些缺点:
1、低速或转子静止时不适用,这是所有反电动势法的共同缺点。
2、电压比较器对被检测信号中的毛刺、噪声非常敏感等等。
                不过目前反电动势过零点检测方法依旧是当前无感控制中应用最为成熟的一种技术,我们例程同样也是使用的该技术实现的无感驱动。说了这么多,那我们应该如何检测过零点呢?又如何通过过零信号判断当前转子位置呢?接下来我们一步一步来解答。
25.1.3 比较器模式采样过零信号
      由于BLDC电机的Y形连接,三相都接到公共的中性点,相电压无法直接测量。只能测量各相的端电压,通常将非通电绕组的端电压用于无传感器控制时,称为端电压法,即各相对地的电压,然后与中性点电压比较,当端电压从大于中性点电压变为小于中性点电压,或者从小于中性点电压变为大于中性点电压,即为过零点。如图所示。
图25.1.3.1.检测反电动势过零点
但是一般的BLDC电机都没有中性点的外接引线,所以无法直接测量中性点电压。解决这个问题最直接的办法就是重构一个"虚拟中性点”,通过将三相绕组分别通过阻值相等的电压连接到一个公共点而成,这个公共点就是虚拟中性点,如图25.1.3.1( B )所示。将中性点信号和UVW信号通过比较器进行比较就可以获得过零信号。由于使用比较器进行外部硬件比较的方式较为稳定,因此得到广泛应用。
图25.1.3.2 实际过零信号原理图
图25.1.3.2是我们无刷驱动板的比较器采样过零信号的电路,我们以U相来说明:U相反向电动势和中性点信号通过 U8B 比较器输出过零点信号 ZERO_U。
25.1.4 闭环的建立
每一相的反电动势都有两种过零情况:从正变为负和从负变为正。三相共有六种过零情况对应六种换相状态,并且这种对应关系是固定不变的。所以我们可以将这个对应关系写入一个表中,程序中每检测到一个过零点,就通过查表来决定相应IO输出状态,控制下一步哪两相通电;然后切换到当前断开相继续检测反电动势过零点,如此循环,直至建立稳定的闭环。下图为我们店铺无刷电机的过零信号组合所对应的绕组导通情况真值表:
表25.1.4.1 过零信组合对应的绕组导通情况
理论上,过零点总是超前换相点 30°电角度。因此在检测到过零点后,要先延迟 30°电角度再换相。但是在闭环调速过程中,电机旋转一个电气周期的时间不是固定不变的,因此无法预测在检测到过零点后接下来的这 30°电角度是多长时间。那么在检测到过零点之后,怎样决定延时时间呢?
虽然无法预测接下来的 30°电角度是多长,但是刚刚过去的上一个换相周期,即两个换相点之间 60°电角度的长度是可以测量的。于是可以采用近似的办法,用上一个换相周期,即 60°电角度的时间减半,作为接下来的30°电角度延时时间。这种办法是可行的,因为电机的转速是渐变的,相邻两个换相周期的时间相差不会很大。
由于定子绕组的反电动势与电机的转速成正比,所以电机在静止时反电动势为零或低速时反电动势很小,此时无法根据反电动势信号确定转子磁极的位置,因此反电动势法需要采用特殊起动技术,从静止开始加速,直至转速足够大,当反电势能检测到过零信号时,再切换至无刷直流电机运行状态。这个过程称为“三段式”起动,主要包括转子预定位、加速和运行状态切换三个阶段。这样既可以使电机转向可控,又可以保证电机达到一定转速后再进行切换,保证了起动的可靠性。下面就让我们介绍BLDC方波启动技术。
25.1.5 BLDC方波启动技术
25.1.5.1电机转子预定位
要保证无刷直流电机能够正常起动,首先要确定转子在静止时的位置。在轻载条件下,对于具有梯形反电势波形的无刷直流电机来说,一般采用磁制动转子定位方式。系统起动时,任意给定一组触发脉冲,在气隙中形成一个幅值恒定、方向不变的磁通,只要保证其幅值足够大,那么这一磁通就能在一定时间内将电机转子强行定位这个方向上。在应用中,可以在任意一组绕组上通电一定时间,其中预定位的PWM占空比和预定位时间的长短设定值可由具体电机特性和负载决定,在实际应用中调试而得。在预定位成功后,转子在起动前可达到预定的位置,为电机起动做好准备。
25.1.5.2电机的外同步加速
确定了电机转子的初始位置后,由于此时定子绕组中的反电动势仍为零,所以必须人为的改变电机的外施电压和换相信号,使电机由静止逐步加速运动,这一过程称为外同步加速。对于不同的外施电压调整方法和换相信号调整方法,外同步加速可以划分为三类:换相信号频率不变,逐步增大外施电压使电机加速,称为恒频升压法。保持外施电压不变,逐渐增高换相信号的频率,使电机逐步加速,称为恒压升频法。在逐步增大外施电压的同时,增高换相的频率,称为升频升压法。
25.1.5.3电机运行状态的转换
各个方法都有其优点和缺点。如升频升压法是人为地给电机施加一个由低频到高频不断加速的可控同步切换信号,而且电压也在不断地增加。通过调整电机换相频率,即可调整电机起动的速度。调整方法比较简单。但是这个过程比较难实现,切换信号的频率的选择要根据电机的极对数和其它参数来确定,太低电机无法加速,太高电机转速达不到会有噪声甚至无法启动,算法比较困难。无论哪种方法,该过程都是在未检测到反电动势信号时进行,因此对于控制系统来说,此段电机控制是盲区。参数在调试好的时候,可以快速切换至正常运行状态;而参数不理想时,电流可能不稳甚至电机会抖动。因此,在应用中,应根据电机及负载特性设定合理的升速曲线,并在尽可能短的时间内完成切换。
      这一步是关键也是比较难实现的一步,有时软件或者硬件设计的不合理都可能导致起动失败。通常是采用估算的方式来选择切换速度。通过上面的分析可知,无位置传感器无刷直流电机控制系统的难点就是加速及切换阶段,当电机顺利起动后,就可以对电机调速操作。其中,无位置传感器无刷直流电机和有位置传感器电机调速原理一致。但由于无感三段式起动过程,转子位置检测无效,因此,对电机进行的速度PID闭环控制,需在电机起动顺利完成后进行。
至此,我们可以得到一个无感驱动的整体框图:
图25.1.5.3.1 无感驱动的整体框图
25.2 硬件设计
1、例程功能
本实验使用无刷电机接口一连接无刷电机驱动板
当按下KEY0一次电机正转,按一次KEY1电机反转,按下KEY2则停止旋转。
LED0作为程序运行状态指示灯,闪烁周期200ms。
2、硬件资源
1)LED灯:LED0 – PE0
2)独立按键
    KEY0 – PE2
      KEY1 – PE3
      KEY2 – PE4
3)定时器:
      TIM1_CH1:PA8
      TIM1_CH2:PA9
      TIM1_CH3:PA10
   IO:PB13\14\15
   使能引脚:SHDN: PF10
4)过零信号检测引脚
过零U相 – PH10
过零V相 – PH11
过零W相 – PH12
5)无刷电机
6)无刷电机驱动板
7)12-60V的DC电源
3、原理图
图25.2.1 无刷电机接口1原理图
表25.2.1 无刷相关IO口说明
      驱动板和开发板连接只需要使用排线连接即可,电机与驱动板通过接线端子进行连接,实物连接如下。另外需要将JP3跳线帽连接H&Z和ZERO。
图25.2.2 开发板&驱动板连接图
25.3 程序设计
25.3.1 无刷电机无感控制的配置步骤
1)实现电机基本驱动
      实现电机的基础驱动函数,启停、6步换向组合等等
2)预定位
      固定转子在某一位置,然后以一定的速度按顺序换向旋转,实现方波启动
3)过零处理函数
      过滤尖峰电压,判断过零信号发生改变,延迟计数,当延迟30°之后开始换相
4)编写中断服务函数
      定时调用过零控制函数
25.3.2 程序流程图
图25.2.2.1 无刷电机基本控制流程图
25.3.3 程序解析
这里我们只讲解关于无感驱动的核心代码,首先是过零控制函数,在源文件zero_ctr.c中,内容如下:
/**
* @brief       实现定位并以一定速度旋转之后,切换至过零控制
* @param       无
* @retval      无
*/
void zero_ctr_loop(void)
{
    if(g_bldc_motor1.run_flag == RUN)
    {
      switch(g_zero_ctr_status)
      {
            case 0:                                                      /* 定位:固定一相*/
            {
                        /* 启动速度不可太快,否则容易过流 */
                vvvf_sp.Voilage_Ref = (uint16_t)(MAX_PWM_DUTY/20);
                g_bldc_motor1.pwm_duty = vvvf_sp.Voilage_Ref;
                m1_uhvl();                               /* U+V- */
                delay_temp = 0;
                vvvf_sp.Freq_T_Ref = 1100;            /* 初始延迟时间为:55*1100us */
                g_zero_ctr_status = 1;                /* 切换至延迟计数 */
                count_i = 0;
                switch_hallless = 0;
                vvvf_sp.Count = 0;
            }
            break;
            case 1:/*定时延迟*/
            {
                delay_temp++;
                if(delay_temp >= vvvf_sp.Freq_T_Ref)
                {
                  delay_temp = 0;
                  g_zero_ctr_status = 2;          /* 切换至换相操作 */
                }
#if (DRIVE_MODE)                              /* 过零闭环控制 为0开环控制 */
                switch_hallless = hallless_sw();/* 检测过零信号 稳定后切换至闭环 */
            
                if (switch_hallless == 1)
                {
                  g_zero_ctr_status = 3;
                }
#endif
            }
            break;
            case 2:                                     /* 加速换相(提高换向频率)*/
            {
                vvvf_sp.Freq_T_Ref -= vvvf_sp.Freq_T_Ref/15+1;/*改变换向频率 */
                vvvf_sp.Count++;
                change_voltage();                   /* 改变换向所需电压 */
                if(vvvf_sp.Freq_T_Ref < 180)
                {
                  vvvf_sp.Freq_T_Ref = 180;         /* 固定次频率(延迟时间) */
                  g_zero_ctr_status = 1;            /* 切换至延迟计数 */
                }
                else
                {
                  g_zero_ctr_status = 1;         /* 切换至延迟计数 */
                }
                vvvf_sp.VvvF_Count++;            /* 换向计数 */

                if(vvvf_sp.VvvF_Count == 6)
                {
                  vvvf_sp.VvvF_Count = 0;
                }
                anwerfen_sw();
            }
            break;
            case 3:
            {
                hallless_sw();                        /* 切换至闭环过零检测状态 */
            }
            break;
            default: break;
      }
    }
    else if(g_bldc_motor1.run_flag == STOP)
    {
      zero_ctr_init();
    }
}
      首先初始状态标志位g_zero_ctr_status为0,此时使能旋转的话会进入case 0,这时程序默认给UV相通电,实现转子定位,然后下一次进入时切换到case 1,经过延迟后切换到case 2,在这里将变量vvvf_sp.Freq_T_Ref递减,实现增频,通过函数change_voltage实现增压,即实现了升频升压法。之后逐渐加速,再回到状态1进行延迟,直至检测到稳定的过零信号,最后切换到状态3,调用函数hallless_sw实现过零控制。接着看下函数hallless_sw的内容:
uint8_t hallless_sw(void)
{
    count_j++;/* 运行过程时间计数 18K的中断频率为单位 */
    /* 过零信号滤波 */
    hallless_three.Queue_Status = hallless_three.Queue_Status << 1;
    hallless_three.Queue_Status = hallless_three.Queue_Status << 1;
    hallless_three.Queue_Status = hallless_three.Queue_Status << 1;
    /* 检测过零点 */
hallless_three.Queue_Status |= HAL_GPIO_ReadPin(HALL1_TIM_CH1_GPIO,
HALL1_TIM_CH1_PIN); /* U相过零点 */
hallless_three.Queue_Status |= HAL_GPIO_ReadPin(HALL1_TIM_CH2_GPIO,
HALL1_TIM_CH2_PIN); /* V相过零点 */
hallless_three.Queue_Status |= HAL_GPIO_ReadPin(HALL1_TIM_CH3_GPIO,
HALL1_TIM_CH3_PIN); /* W相过零点 */
    /* 过零信号U */
    hallless_three.Filter_Math = hallless_three.Queue_Status & FILTER_LONG;
    if (hallless_three.Filter_Math == FILTER_LONG)
    {
      hallless_three.QFilter_Status = 1;

    }
    else if (hallless_three.Filter_Math == 0x00)
    {
      hallless_three.QFilter_Status = 0;
    }
    else
    {
      hallless_three.Filter_Count++;
      return 0;
    }
    /* 过零信号V */
    hallless_three.Filter_Math = hallless_three.Queue_Status & FILTER_LONG;
    if (hallless_three.Filter_Math == FILTER_LONG)
    {
      hallless_three.QFilter_Status = 1;
    }
    else if (hallless_three.Filter_Math == 0x00)
    {
      hallless_three.QFilter_Status = 0;
    }
    else
    {
      hallless_three.Filter_Count++;
      return 0;
    }
    /* 过零信号W */
    hallless_three.Filter_Math = hallless_three.Queue_Status & FILTER_LONG;
    if (hallless_three.Filter_Math == FILTER_LONG)
    {
      hallless_three.QFilter_Status = 1;
    }
    else if (hallless_three.Filter_Math == 0x00)
    {
      hallless_three.QFilter_Status = 0;
    }
    else
    {
      hallless_three.Filter_Count++;
      return 0;
    }
    /******************* 速度计算 ********************/
    hallless_three.Filter_Edge = uemf_edge(hallless_three.QFilter_Status);

    if (hallless_three.Filter_Edge == 0) /* 统计过零信号的高电平时间 */
    {
      /* 延迟30°换相,因为硬件上低通滤波器和软件延迟的原因,实际延迟角度需小于30°
      最优解可以通过示波器确定。通过PE1查看实际延迟角度 */
      if (count_i >= 4)/* 稳定检测到过零信号才对速度进行测量 */
      {
            if (g_bldc_motor1.dir == CCW)
                hallless_three.Speed_RPM = ((uint32_t)SPEED_COEFF / count_j);
            else
                hallless_three.Speed_RPM = -((uint32_t)SPEED_COEFF / count_j);

            FirstOrderRC_LPF(g_bldc_motor1.speed, hallless_three.Speed_RPM, 0.2379);
      }

      hallless_three.Filter_Delay = count_j / 6;          /* 30°所需时间 */
      hallless_three.Filter_Count = 0;
      count_j = 0;
      count_i++;                                                          /* 捕捉过零点,累计次数 */
    }

    if (hallless_three.Filter_Edge == 1)
    {
      hallless_three.Filter_Count = 0;
      count_j = 0;
    }

    if (hallless_three.Filter_Edge == 2)    /* 过零信号没变化 */
    {
      hallless_three.Filter_Count++;            /* 不换相时间累计 超时则判定速度为0 */

      if (hallless_three.Filter_Count > 15000)
      {
            hallless_three.Filter_Count = 0;
            hallless_three.Speed_RPMF = 0;          /* 超时换向 判定为停止 速度为0 */
      }
    }
    /********************* 过零控制 ***********************/
    if (count_i >= 4)                                                   /* 稳定检测到过零信号并旋转2圈之后进入*/
    {
      count_i = 4;
      edge_flag++;                                    
      if (edge_flag >= 2)
      {
            edge_flag = 2;
            hallless_three.Hallless_State = hallless_three.QFilter_Status |
                        (hallless_three.QFilter_Status << 1) |
                        (hallless_three.QFilter_Status << 2);         /* 获取过零信号组合 */
                  /* 检测到过零信号发生改变,但不立即换向 开始过零计时*/
            if (hallless_three.Hallless_State !=                                                                                       hallless_three.OldHallless_State)      
            {
                hallless_three.Filter_Count_All++;
            }
            /*********** 调试延迟30°的时间之后,执行换相 **************/
            if (hallless_three.Filter_Count_All >=
                        (hallless_three.Filter_Delay))       /* 等延迟30°时间之后 在进行换相 */
            {               
                hallless_three.Filter_Count_All = 0;
                   /* 在次确认是否检测到过零信号发生改变,是的话立即换相 */
                if (hallless_three.Hallless_State !=                                 
                              hallless_three.OldHallless_State)
                {
                  if (g_bldc_motor1.dir == CCW)
                  {
                        g_bldc_motor1.pos--;            /* 电机位置计数 */
                                        /* 根据过零信号组合值,导通对应相的上下桥臂 */
                        pfunclist_m1();            
                  }
                  else
                  {
                        g_bldc_motor1.pos++;    /* 电机位置计数 */
                                        /* 根据过零信号组合值,导通对应相的上下桥臂 */
                        pfunclist_m2();            
                  }
                }
                hallless_three.OldHallless_State =
                        hallless_three.Hallless_State ;
            }
      }
      return 1;
    }
    else
      return 0;
}
      该函数实现了过零信号控制,首先将采集到的过零信号进行滤波,防止换向产生的尖峰电压带来的干扰,接着通过读取过零信号组合值进行换向控制,注意读取到过零信号组合值时不是立即换相,而是需要延迟30°电角度的时间在进行换相。这样就可以实现电机的无感过零控制了。
      在中断回调函数里只需定时调用过零控制函数即可,中断回调函数如下:
/**
* @brief       定时器中断回调
* @param       无
* @retval      无
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == ATIM_TIMX_PWM)/* 55us */
    {
#ifdef H_PWM_L_ON
      zero_ctr_loop();
#endif
    }
}
      主函数内容同六步换相类似,通过按键控制无刷电机的正反转及停止,具体函数内容如下:
int main(void)
{
    uint8_t key,t;
    char buf;

    HAL_Init();                                    /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7);            /* 设置时钟,168Mhz */
    delay_init(168);                                 /* 延时初始化 */
    usart_init(115200);                              /* 串口初始化为115200 */
    led_init();                                    /* 初始化LED */
    key_init();                                    /* 初始化按键 */
    lcd_init();                                    /* 初始化LCD */
    bldc_init(168000/18-1,0);
    bldc_ctrl(MOTOR_1,CW,1000);                            /* 初始无刷电机接口1速度 */

    g_point_color = WHITE;
    g_back_color= BLACK;
    lcd_show_string(10,10,200,16,16,"BLDC Motor Test",g_point_color);
    lcd_show_string(10,30,200,16,16,"KEY0:Step++",g_point_color);
    lcd_show_string(10,50,200,16,16,"KEY1:Step--",g_point_color);
    lcd_show_string(10,70,200,16,16,"KEY2:Stop",g_point_color);

    while (1)
    {
      t++;
      if(t % 20 == 0)
      {
            sprintf(buf,"PWM_Duty:%.1f%%",(float)((g_bldc_motor1.pwm_duty/
MAX_PWM_DUTY)*100));      /* 显示控制PWM占空比 */
            lcd_show_string(10,110,200,16,16,buf,g_point_color);
            LED0_TOGGLE();                         /* LED0(红灯) 翻转 */
      }

      key = key_scan(0);
      if(key == KEY0_PRES)                            /* 按下KEY0开启电机 */
      {
            g_bldc_motor1.dir=CCW;
            g_bldc_motor1.run_flag=RUN;      /* 开启运行 */
            start_motor1();                              /* 开启运行 */
      }
      if(key == KEY1_PRES)                            /* 按下KEY1开启电机 */
      {
            g_bldc_motor1.dir=CW;
            g_bldc_motor1.run_flag=RUN;      /* 开启运行 */
            start_motor1();                              /* 运行电机 */
      }
      if(key == KEY2_PRES)                            /* 按下KEY2关闭电机 */
      {
            stop_motor1();                                 /* 停机 */
            g_bldc_motor1.run_flag=STOP;      /* 标记停机 */
            g_zero_ctr_status=0;
            g_bldc_motor1.pwm_duty=0;
      }
      delay_ms(10);
    }
}
25.4 下载验证
      硬件连接好之后下载程序到开发板,点击按键KEY0可以看到电机开始正向旋转,点击一次按键KEY1则可以看到电机开始反向旋转,点击按键KEY2则可以随时停止无刷电机。大家可以自己下载程序并点击按键测试效果。

页: [1]
查看完整版本: 《DMF407电机控制专题教程_V1.0》第25章 直流无刷电机无感控制