无刷电机强拖程序解析

基于 TMS320F2812 的直流无刷电机(BLDCM)的开环控制系统 基于 TMS320F2812 的直流无刷电机(BLDCM)的开环控制系统,通过调节电位器调节给定电压,ADC模块采集电压,改变PWM占空比实现调速,事件管理器的CAP模块来捕获转速大小。 阅读详情
AI摘要

本文主要解析无刷电机的强拖程序,强拖是无刷电机无传感器启动或测试方法,包括 V/F 和 I/F 启动方式。还介绍了三种不同的强拖程序代码,如较简单的量产过的程序、简易电机驱动带预定位的程序以及南京凌欧官方代码框架程序,并对各代码的参数、逻辑等进行说明。

一、强拖概述​

强拖​(也称为开环拖动)是一种无刷电机(BLDC/PMSM)的无传感器启动方法或电机测试方法,主要用于电机启动或低速运行阶段,在没有位置传感器(如编码器、霍尔)的情况下,通过固定电压/频率比 (V/F) ​或者计算一个模拟角度,同时进行电流闭环 (I/F) 强制驱动电机旋转。

1.1 V/F 启动简介

V/F 启动,是保持电压 (V) 与频率 (F) 的比值恒定。并不需要控制器采集包括电机自身任何的外部信息,它仅需要设置目标电频率 (可以去我之前文章搜搜电频率是啥,目前可粗浅的将电频率看作为转速) 以生成虚拟的电机位置角度,和目标调制的电压即可运行,这里所谓的调制电压可以看作母线电压的百分比。

  • 优点:无需采集电流。
  • 缺点:负载突变时易失步,恢复速度慢,转速会随负载波动。

1.2 I/F 启动简介

I/F 启动,保持电流(I)与频率(F)的比值恒定。通过调节电流实现转矩控制,简单来说就是根据配置生成虚拟的电机位置角度,和 FOC 的电流闭环同时控制。

  • 优点:负载突变稳定,恒速。
  • 缺点:需实时电流检测。

1.3 区别

简单来说,V/F和I/F最大的区别是,I/F 增加了电流闭环,根据电流闭环生成调制 PWM 输出。而 V/F 的调制比是固定的开环控制。

二、代码介绍

2.1 较简单的强拖与切换无感程序 (量产过)

2.1.1 参数和变量

#define FORCE_START             0           // 强拖启动 切换时会有噪音
#define FORCE_ACC               (200)       // 强拖加速度//todo:转成物理单位量
#define FORCE_RPM_MAX           (500*23)    // 强拖最大速度(电速度)
#define FORCE_SPEED_MIN         (1000)      // 强拖介入速度(x/32768*100%)
#define FORCE_SWITCH            (50*23)     // 强拖切换速度(电速度) 周期的角度增量(dpp)

stru_force_start force_start = {
     // 加速步进的周期数
    .acc_plus_periods = FORCE_ACC,

     // 最大角速度(通过rpm2dpp宏将RPM转换为角度/周期)也就是每次调用自增的角度
    .thetadpp_max = rpm2dpp(FORCE_RPM_MAX)   
};

其中: 

#define rpm2dpp(rpm)       (((s32)rpm << 16) / (s16)PWM_FREQ / 60 )  // 将 RPM 转换为每 PWM 周期的角度增量(dpp)

1 rpm 为一转,也就是360°。对于这个代码框架来说 0~360° 映射到 0~65535,所以首先将 rpm 乘 65535,然后除 pwm 周期和 60。因为 rpm 是每分钟转速,我们需要算出每秒的转速。

最终得出 thetadpp_max 的值。

2.1.2 强拖主要程序

在以上的强拖逻辑中, force_start.thetadpp < force_start.thetadpp_max 时,需要先缓慢增加 force_start.thetadpp 的值,以模拟电机启动时转速放缓的情况。之后每个周期就按照 thetadpp_max 的值进行累加,以在强拖阶段达到我们的目标转速。

// 函数功能:处理强制启动阶段的电机控制
// 参数:s32_Angle - 霍尔传感器或编码器反馈的当前电机角度(单位:定点数或度)
void force_start_handle(m_s32 s32_Angle) 
{
    static u16 cnt = 0;  // 静态计数器,用于控制加速周期

    // 1. 检查MOS管状态(是否关闭)
    if (MOS_CLOSED()) 
    {
        force_start.theta = 0;      // 重置目标角度为0
        cnt = 0;                    // 重置计数器为0
        force_start.thetadpp = 0;   // 重置角速度为0
    }

    // 2. 加速控制逻辑
    if (++cnt >= force_start.acc_plus_periods) // 计数器递增并检查是否达到加速周期
    {
        cnt = 0;  // 重置计数器
        if (force_start.thetadpp < force_start.thetadpp_max) 
        {
            force_start.thetadpp++;  // 逐步增加角速度(直到达到最大值)
        }
    }

    // 3. 更新目标角度
    force_start.theta += force_start.thetadpp; // 累加角度值(模拟电机转动)

    // 4. 计算角度偏差
    force_start.angle_delta_flex = force_start.theta - flex.theta; // 目标角度与柔性启动角度的偏差
    force_start.angle_delta_hall = force_start.theta - s32_Angle;  // 目标角度与传感器反馈角度的偏差
}

这段代码中所生成的角度波形是这样的。在刚刚启动的时候,force_start.thetadpp 逐步自增,也就是下图中左侧部分一样,三角波形周期从长变短,模拟电机真实启动的过程。

因为使用的是 uint16_t 类型储存变量,所以生成的三角波会在 0-65535 区间。但是我们是按照有符号数读取的,那么就是 -32768 至 32767 了。

2.1.3 强拖角度补偿和强拖切换观测器

当 MOS 管处于关管状态时使 force_start.flag = 2,代表当前是强拖启动状态。

等 force_start.thetadpp > rpm2dpp(FORCE_SWITCH) 也就是强拖的转速达到指定值时对 force_start.iq_sub++ 也就是在此刻强加目标电流,以防止强拖失败。

if ((flex.theta - force_start.theta < 500) && (force_start.theta - flex.theta < 500)) 这个判断是强拖给出的角度和观测角度误差小于 500 就切换为观测角度。

void force_check_handle()
{
    // 检测反电动势电压是否低于最低速度阈值
    if (bemf.vol_pu < FORCE_SPEED_MIN)
    {
        // 检查MOS管是否关闭(电机未通电)
        if (MOS_CLOSED())
        {
            force_start.flag = 2;   // 进入强制启动状态2
            force_start.iq_sub = 0; // 重置Q轴电流补偿值为0
        }
    }
    // 检查当前是否处于强制启动状态2
    if (2 == force_start.flag)
    {
        // 检查当前角速度是否超过切换阈值(FORCE_SWITCH转换为dpp单位)
        if (force_start.thetadpp > rpm2dpp(FORCE_SWITCH))
        {
            // 计数器递增,每2次循环执行一次
            if (++cnt > 1)
            {
                cnt = 0; // 重置计数器
                // 增加Q轴电流补偿值(上限30000)
                if (++force_start.iq_sub > 30000)
                {
                    force_start.iq_sub = 30000; // 限制最大值
                }
            }
            // 检查虚拟角度与实际角度偏差是否小于500(单位可能是Q16)
            if ((flex.theta - force_start.theta < 500) &&
                (force_start.theta - flex.theta < 500))
            {
                force_start.flag = 0; // 退出强制启动状态
            }
        }
    }
}

 2.1.4 强拖程序完整代码

#define rpm2dpp(rpm) (((s32)rpm << 16) / (s16)PWM_FREQ / 60) // 将 RPM 转换为每 PWM 周期的角度增量(dpp)

#define FORCE_START 0            // 强拖启动 切换时会有噪音
#define FORCE_ACC (200)          // 强拖加速度//todo:转成物理单位量
#define FORCE_RPM_MAX (500 * 23) // 强拖最大速度(电速度)
#define FORCE_SPEED_MIN (1000)   // 强拖介入速度(x/32768*100%)
#define FORCE_SWITCH (50 * 23)   // 强拖切换速度(电速度) 周期的角度增量(dpp)

stru_force_start force_start = {
    // 加速步进的周期数
    .acc_plus_periods = FORCE_ACC,

    // 最大角速度(通过rpm2dpp宏将RPM转换为角度/周期)也就是每次调用自增的角度
    .thetadpp_max = rpm2dpp(FORCE_RPM_MAX)};

// 函数功能:处理强制启动阶段的电机控制
// 参数:s32_Angle - 霍尔传感器或编码器反馈的当前电机角度(单位:定点数或度)
void force_start_handle(m_s32 s32_Angle)
{
    static u16 cnt = 0; // 静态计数器,用于控制加速周期

    // 1. 检查MOS管状态(是否关闭)
    if (MOS_CLOSED())
    {
        force_start.theta = 0;    // 重置目标角度为0
        cnt = 0;                  // 重置计数器为0
        force_start.thetadpp = 0; // 重置角速度为0
    }

    // 2. 加速控制逻辑
    if (++cnt >= force_start.acc_plus_periods) // 计数器递增并检查是否达到加速周期
    {
        cnt = 0; // 重置计数器
        if (force_start.thetadpp < force_start.thetadpp_max)
        {
            force_start.thetadpp++; // 逐步增加角速度(直到达到最大值)
        }
    }

    // 3. 更新目标角度
    force_start.theta += force_start.thetadpp; // 累加角度值(模拟电机转动)

    // 4. 计算角度偏差
    force_start.angle_delta_flex = force_start.theta - flex.theta; // 目标角度与柔性启动角度的偏差
    force_start.angle_delta_hall = force_start.theta - s32_Angle;  // 目标角度与霍尔传感器反馈角度的偏差
}

void force_check_handle()
{
    // 检测反电动势电压是否低于最低速度阈值
    if (bemf.vol_pu < FORCE_SPEED_MIN)
    {
        // 检查MOS管是否关闭(电机未通电)
        if (MOS_CLOSED())
        {
            force_start.flag = 2;   // 进入强制启动状态2
            force_start.iq_sub = 0; // 重置Q轴电流补偿值为0
        }
    }
    // 检查当前是否处于强制启动状态2
    if (2 == force_start.flag)
    {
        // 检查当前角速度是否超过切换阈值(FORCE_SWITCH转换为dpp单位)
        if (force_start.thetadpp > rpm2dpp(FORCE_SWITCH))
        {
            // 计数器递增,每2次循环执行一次
            if (++cnt > 1)
            {
                cnt = 0; // 重置计数器
                // 增加Q轴电流补偿值(上限30000)
                if (++force_start.iq_sub > 30000)
                {
                    force_start.iq_sub = 30000; // 限制最大值
                }
            }
            // 检查虚拟角度与实际角度偏差是否小于500(单位可能是Q16)
            if ((flex.theta - force_start.theta < 500) &&
                (force_start.theta - flex.theta < 500))
            {
                force_start.flag = 0; // 退出强制启动状态
            }
        }
    }
}

2.2 某简易电机驱动的强拖程序(带预定位)

2.1.1 预定位

这段代码预定位的逻辑非常简单,仅靠延迟做实现。简单来说转子预定为就是给一个固定的角度输出给 FOC 控制一段时间,使转子拖动到这个角度。

对于控制逻辑相当于是:

  1. 施加一个固定的D轴电流(Id),产生定向磁场(如指向0°电角度)。
  2. 保持Q轴电流(Iq)为零(不产生转矩)。
  3. 持续 LOCK_COUNTER 个控制周期,确保转子被拉至目标位置。

LOCK_COUNTER 取值:
通常为几十到几百个PWM周期(例如20ms,若PWM频率=10kHz,则 LOCK_COUNTER=200)。

/* 初始锁定序列(用于磁场对齐) */
if (pmsm_mc_param.startup_lock_count < LOCK_COUNTER)
{
    pmsm_mc_param.startup_lock_count++; // 锁定计数器递增
}

2.1.2 加速度和切无感条件

同样,这段代码也有启动的加速度:

pmsm_mc_param.startup_ramp += OPENLOOP_RAMPSPEED_INCREASERATE; // 增加开环转速

这段代码的切换判断条件也很有意思:

​开环生成的角度 pmsm_foc_param.angle < π(180°)​实际转子角度 smc1.theta < π(180°)

这两个条件同时满足才会切换:

if ((pmsm_foc_param.angle < M_PI) && (smc1.theta < M_PI))

全部代码如下: 

    /* 加速阶段 */
    else if (pmsm_mc_param.startup_ramp < END_SPEED_RADS_ELEC_COUNTER) 
    {
        pmsm_mc_param.startup_ramp += OPENLOOP_RAMPSPEED_INCREASERATE; // 增加开环转速
    }
    /* 准备切换到闭环 */
    else 
    {
        theta_error = pmsm_foc_param.angle - smc1.theta;  // 计算角度误差
#ifndef OPEN_LOOP_MODE
        // 检查角度是否在合理范围内(避免突变)
        if ((pmsm_foc_param.angle < M_PI) && (smc1.theta < M_PI)) 
        {
            pmsm_mc_param.change_mode = 1;  // 标记模式切换
            pmsm_mc_param.openloop = 0;     // 退出开环模式
        }
#endif

2.1.3 完整代码

static void calculate_park_angle(void)
{
if (pmsm_mc_param.openloop) 
{
    /* 初始锁定序列(用于磁场对齐) */
    if (pmsm_mc_param.startup_lock_count < LOCK_COUNTER) 
    {
        pmsm_mc_param.startup_lock_count++;  // 锁定计数器递增
    }
    /* 加速阶段 */
    else if (pmsm_mc_param.startup_ramp < END_SPEED_RADS_ELEC_COUNTER) 
    {
        pmsm_mc_param.startup_ramp += OPENLOOP_RAMPSPEED_INCREASERATE; // 增加开环转速
    }
    /* 准备切换到闭环 */
    else 
    {
        theta_error = pmsm_foc_param.angle - smc1.theta;  // 计算角度误差
#ifndef OPEN_LOOP_MODE
        // 检查角度是否在合理范围内(避免突变)
        if ((pmsm_foc_param.angle < M_PI) && (smc1.theta < M_PI)) 
        {
            pmsm_mc_param.change_mode = 1;  // 标记模式切换
            pmsm_mc_param.openloop = 0;     // 退出开环模式
        }
#endif
    }
    // 更新Park角度(累加开环转速)
    pmsm_foc_param.angle += pmsm_mc_param.startup_ramp;
    // 角度归一化(0~2π)
    if (pmsm_foc_param.angle > ANGLE_2PI)
        pmsm_foc_param.angle = pmsm_foc_param.angle - ANGLE_2PI;
}

2.3 南京凌欧官方代码框架强拖程序

2.3.1 强拖角度生成

预先设置目标转速和每周期增加的步长 (角度)

// 根据电机运行方向设置强拖频率方向
if (struFOC_CtrProc.bMotorDirtionCtrl == CW) // 顺时针方向
{
    // 设置正向强拖目标频率(最小服务频率)
    mOpenForceRun.wOpen2CloseFreq = struAppCommData.wSvcMinFreq;
}
else // 逆时针方向
{
    // 设置负向强拖目标频率
    mOpenForceRun.wOpen2CloseFreq = -struAppCommData.wSvcMinFreq;
}

// 设置强拖频率的加速步长(将用户单位转换为应用单位)
mOpenForceRun.nFreqAccStep = User2AppFreqTrans(FREQ_ACC);

// 设置强拖频率的减速步长(将用户单位转换为应用单位)
mOpenForceRun.nFreqDecStep = User2AppFreqTrans(FREQ_DEC);

// 执行频率爬坡生成(生成线性变化的频率参考值)
SpeedReferenceGen(&mOpenForceRun);

 其中 SpeedReferenceGen() 函数实现如下:

只做了简单的累加,并没有设置强拖刚开始的缓启动。

/*****************************************************************************
 * 函数名   : void SpeedReferenceGen(stru_OpenForceRunDef *this)
 * 说明     : 速度爬坡 
 * 设计思路 :1.速度爬坡
 * 参数     :无
 * 返回值   :无
 * 修改时间 :2020.08.17
 *****************************************************************************/
void SpeedReferenceGen(stru_OpenForceRunDef *this)
{
    s32 ax;
    ax = this->wOpen2CloseFreq << 7;
    if(this->wRampFreqRef < (ax))
    {
        this->wRampFreqRef += this->nFreqAccStep;
        if(this->wRampFreqRef >= ax)
        {
            this->wRampFreqRef = ax;
        }                                             
    }
    if(this->wRampFreqRef > ax)
    {
        this->wRampFreqRef -= this->nFreqDecStep;
        if(this->wRampFreqRef <= ax)
        {
            this->wRampFreqRef = ax;  
        }
    }
}

2.3.1 强拖切无感逻辑

根据强拖角度和和观测角度误差在指定范围内累加切换。

// 计算观测器估算角度与开环强拖角度的误差
struAppCommData.wThetaErr = struFluxOB_Param.wElectAngleEst - struFluxOB_Param.wElectAngleOpen;

// 取误差绝对值并右移16位(Q16格式转换为实际值)
struAppCommData.wThetaErr = ABS(struAppCommData.wThetaErr) >> 16;

// 检查角度误差是否在合理范围内(2000~18000对应10.98°~98.87°)
if ((struAppCommData.wThetaErr > 2000) && (struAppCommData.wThetaErr < 18000))
{
    // 误差在范围内,增加匹配计数器
    struAppCommData.nMatchCnt++;
}
else
{
    // 误差超出范围,重置匹配计数器
    struAppCommData.nMatchCnt = 0;
}

2.3.2 完整代码

南京的凌欧的代码框架在强拖前有预定位的配置,但是并没有在改函数内实现。

/*****************************************************************************
 * 函数名   : void StateOpen(void)
 * 说明     : 电机强拖程序
 * 设计思路 :1.给定电机强拖频率、强拖电流、强拖加速度,使电机从静止开始拖动到设定的强拖频率。           \
              2.当电机达到设定频率,且估算角度和强拖角度误差在(10.98°~ 98.87°)之内则判断为估算         \
                已经跟随到强拖角度,连续5次则从开环切换到闭环。                                          \
              3.由于强拖给定的是Id,所以在程序留了从Id-->Iq电流的切换时间,切换时间的长短依照实际电机负载\
                来调整。(总的原则,负载轻则切换时间短;负载重则切换时间长,对于灯扇类应用则可以适当延长,\
                等扇叶完全展开后再切入速度闭环。                                                         \
              4.开环状态用来测试电机极对数,计算公式:极对数N = 60f/Speed ,其中f为电机电频率,Speed为电机\
                机械转速。
 * 参数     :无
 * 返回值   :无
 * 修改时间 :2020.08.17
 *****************************************************************************/
void StateOpen(void)
{
    // 检查是否处于开环强拖状态(bOpenRunFlag=0表示未启动强拖)
    if (struAppCommData.bOpenRunFlag == 0)
    {
        // 根据电机运行方向设置强拖频率方向
        if (struFOC_CtrProc.bMotorDirtionCtrl == CW) // 顺时针方向
        {
            // 设置正向强拖目标频率(最小服务频率)
            mOpenForceRun.wOpen2CloseFreq = struAppCommData.wSvcMinFreq;
        }
        else // 逆时针方向
        {
            // 设置负向强拖目标频率
            mOpenForceRun.wOpen2CloseFreq = -struAppCommData.wSvcMinFreq;
        }

        // 设置强拖频率的加速步长(将用户单位转换为应用单位)
        mOpenForceRun.nFreqAccStep = User2AppFreqTrans(FREQ_ACC);
        // 设置强拖频率的减速步长(将用户单位转换为应用单位)
        mOpenForceRun.nFreqDecStep = User2AppFreqTrans(FREQ_DEC);

        // 执行频率爬坡生成(生成线性变化的频率参考值)
        SpeedReferenceGen(&mOpenForceRun);
        // 获取当前频率设定值(右移7位进行缩放)
        struMotorSpeed.wSpeedSet = mOpenForceRun.wRampFreqRef >> 7;
        // 将频率参考值转换为核心控制层单位
        struMotorSpeed.wSpeedRef = App2CoreFreqTrans(struMotorSpeed.wSpeedSet);

        // 检查是否达到设定的强拖目标频率
        if (struMotorSpeed.wSpeedSet == mOpenForceRun.wOpen2CloseFreq)
        {
            // 计算观测器估算角度与开环强拖角度的误差
            struAppCommData.wThetaErr = struFluxOB_Param.wElectAngleEst - struFluxOB_Param.wElectAngleOpen;
            // 取误差绝对值并右移16位(Q16格式转换为实际值)
            struAppCommData.wThetaErr = ABS(struAppCommData.wThetaErr) >> 16;

            // 检查角度误差是否在合理范围内(2000~18000对应10.98°~98.87°)
            if ((struAppCommData.wThetaErr > 2000) && (struAppCommData.wThetaErr < 18000))
            {
                // 误差在范围内,增加匹配计数器
                struAppCommData.nMatchCnt++;
            }
            else
            {
                // 误差超出范围,重置匹配计数器
                struAppCommData.nMatchCnt = 0;
            }

            // 检查是否连续匹配次数超过阈值(默认5次)
            if (struAppCommData.nMatchCnt > MATCH_TIME)
            {
                // 根据系统配置决定是否切换到闭环
#if (OPEN_RUN_STATUS == TRUE)
                {
                    // 配置为仅开环运行,不执行任何操作
                }
#elif (OPEN_RUN_STATUS == FALSE)
                {
                    // 切换到闭环运行模式
                    struFOC_CtrProc.eSysState = RUN;  // 设置系统状态为运行模式
                    struAppCommData.bOpenRunFlag = 1; // 标记开环强拖已完成

                    // 根据电机方向设置Q轴电流(转矩电流)
                    if (struFOC_CtrProc.bMotorDirtionCtrl == CW) // 顺时针方向
                    {
                        // 设置正向Q轴电流(经过两级单位转换)
                        struFOC_CurrLoop.nQCurrentSet = App2CoreCurTrans(User2AppCurTrans(U_START_CUR_SET_S));
                    }
                    else if (struFOC_CtrProc.bMotorDirtionCtrl == CCW) // 逆时针方向
                    {
                        // 设置负向Q轴电流(经过两级单位转换)
                        struFOC_CurrLoop.nQCurrentSet = -App2CoreCurTrans(User2AppCurTrans(U_START_CUR_SET_S));
                    }

                    // 设置D轴电流(励磁电流)
                    // 注:开环阶段使用Id强拖,闭环后Id逐渐降为0,Iq逐渐增加
                    struFOC_CurrLoop.nDCurrentSet = App2CoreCurTrans(User2AppCurTrans(U_START_CUR_SET_F));

                    // 设置电流环的加速斜率(经过两级单位转换)
                    struAppCommData.nCurrentACC = App2CoreCurTrans(User2AppCurTrans(OPEN2CLOSE_RUN_CURRENT_RAMP));
                    // 设置电流环的减速斜率(经过两级单位转换)
                    struAppCommData.nCurrentDEC = App2CoreCurTrans(User2AppCurTrans(OPEN2CLOSE_RUN_CURRENT_RAMP));

                    // 更新D轴电流环参数
                    CurrentLoopAxisD_Set();
                    // 更新Q轴电流环参数
                    CurrentLoopAxisQ_Set();
                }
#endif
            }
        }
    }
}

[FOC-Simulink]使用Simulink对永磁同步电机进行无传感矢量控制(增补IF强拖和开闭环切换) 为了在开环转闭环的过渡阶段,电流目标值改变,在前端加入了定时斜坡信号,前2.2s电流目标值保持不变,然后在2.2~2.5s中逐渐减小电流目标值,从而逐步减小强拖角,防止切换到闭环时电流波动过大,导致切换失败。之前文章介绍了Simulink官方给的模板,随着学习得不断加深,对程序框图每部分充分理解,发现这个模板中开环阶段采用的是VF强拖,这样启动阶段的动态响应不是很好,因此本人着手于改进代码将开环阶段升级为IF强拖+开闭环切换。:0.3s时刻,切入闭环程序,速度目标值增加到0.5,转速环启动运行。 阅读详情

相关推荐

项目实战|基于STM32的无刷电机开环控制

本博客记述了笔者提供STM32的HAL库(依赖STM32CubeMX),对直流无刷电机进行开环控制的代码。主要使用了TIM生成SPWM波。

过客朔越的博客 1万+

12、电机控制——IF强拖+无感运行(龙伯格观测器)

本文针对无感控制中低速观测器不准确导致的启动失败问题,提出IF强拖启动结合观测器闭环的控制方案。该方案分为三阶段:IF启动阶段通过斜波控制提升转速至观测器稳定阈值;切换阶段通过调节电流缩小自主电角度与估算值的偏差,在速度/角度误差满足条件时切换至无感双闭环;最终阶段采用观测器数据实现速度-电流双闭环控制。仿真测试验证了减小电流可增大转矩角,有效缩小自主与真实电角度差值,确保切换平滑性。该方案通过动态调节电流和严格切换条件,解决了电角度突变导致的顿挫问题。

weixin_59334478的博客 1241

无刷电机无感启动避坑指南:为什么你的强拖程序总在切换时‘抖一下’?

本文深入解析无刷电机(BLDC/PMSM)无传感器启动时强拖程序切换抖动问题,提供优化方案与实战调试技巧。从加速度曲线设计、切换条件判断到观测器收敛性保障,详细讲解如何避免切换时的抖动现象,特别针对水泵、风扇等应用场景给出负载适应性优化策略。

weixin_33737774的博客 489

无刷电机驱动入门(换相)C语言程序

无刷入门程序,无废话,快速学会。

A_Frost的博客 4423

无刷电机强拖程序实战:从V/F到I/F的代码实现与切换策略

本文深入探讨无刷电机强拖程序的实现与优化,重点对比V/F和I/F控制方式的优缺点及代码实现细节。通过BLDC/PMSM电机的无传感器启动案例,详细解析电流环设计、安全保护机制和平滑切换策略,提供可落地的工程实践参数配置建议,帮助开发者提升电机控制系统的启动可靠性和运行稳定性。

weixin_33717117的博客 359

无刷电机的工作原理

励磁无刷电机结构原理 不过显然模界中的无刷电机与这个励磁电机并不是同一个东西,那么我们常用的无刷电机里面究竟有些什么技术、如何解释那些专业名词、以及各种参数和设备之间究竟有什么区别和联系呢?今天就带大家全面了解一下模界常用的无刷电机。无刷电机的基本概念 根据电机的结构和工作原理,我们可以将电机分为有刷电机、内转子无刷电机和外转子无刷电机。 有刷电机:我们也称为直流电机或者碳刷电机,...

qgtx_424的博客 4397

BLDC控制算法

BLDC驱动算法

guoli_960322的博客 2392

无感启动利器:BLDC/PMSM强拖程序实战与优化

本文深入探讨了无刷电机(BLDC/PMSM)无感启动中的强拖程序实战与优化技巧。通过对比V/F与I/F控制方案,详细解析了各自的优缺点及适用场景,并分享了启动平滑度优化、切换时机判断等关键实现技巧。文章还提供了风机、泵类等典型负载的调参心得,帮助工程师解决无传感器启动中的常见问题。

weixin_42548829的博客 223

无刷电机工作原理介绍

一、有刷马达的原理 要讲清这一问题,那就应粗略地了解一下有刷马达的工作原理。接下来用一个三电极、二磁极内转子有刷马达作为演示。 二、无刷电机工作原理 首先,无刷电机不是直流电机,模型虽然是直流电池供电,但通过无刷电调之后就转变为了三相交变电流传输到了三个极性上。通过下图可以看出,无刷电机是没有碳刷的,和有刷相反,无刷电机的磁铁成了转子~ 三、无刷电机的命名 相对有刷电机,无刷电机的命名好理解很...

dayzo的博客 2万+

直流无刷电机驱动原理学习记录

直流无刷电机(BLDC)是指无电刷和换向器的电机,又称无换向器电机。

qq_44219883的博客 3483

三相直流无刷电机无感反电势控制TI源代码解析

三相直流无刷电机无感反电势控制TI源代码解析 时间:20200208 作者:LJL 参考文档:DMC MATH.pdf (文档路径:C:\ti\controlSUITE\libs\app_libs\motor_control\math_blocks\v4.1~Docs) 参考源代码:com_trig.h (代码路径:C:\ti\controlSUITE\libs\app_libs\motor_co...

lijialin_bit的博客 5221

无刷电机介绍

尺寸 大家选择无刷电机,会看到很多命名类似的型号,如2216、2814等,这个数字,前两位是定子外径(mm)、后两位的是定子高度(mm)。定子的外径和高度越多,定子的铁芯越大,线圈绕的匝数也越多,表现出来就是电机的功率越大。当然,尺寸越大功率越大,但重量也越大。 如某电机是2216,表示定子外径是22mm,定子高度是16mm。定子外径和定子高度与电机的功率成正比,2218的比2212的电机定子高度高,肯定是功率同样也大。这个尺寸的意义在于看型号就可以比较两个电机的功率大小,但这个一般只是比较定子外径相同而

qlexcel的专栏 4万+

【伺服电机控制】MIT无刷电机FOC驱动程序设计

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录系列文章目录前言一、FOC主程序分析1、主程序步骤2、主程序代码二、中断程序分析1.can接收中断主要的任务(1)驱动特殊指令(优先级最高)【用于非串口设置电机模式】(2)CAN接口指令(优先级最低)(3)把电机收到的信号返回到主设备,说明电机有响应代码2.串口接收中断主要的任务设置电机的模式(1)【27】电机复位状态+接收8位数据清零(2)【REST_MODE】:电机还在菜单栏上,在这里进行电机

qq_35635374的博客 9382

无刷电机驱动板原理图解析

OPA4171 作为一个高精度运算放大器,非常适合用于电机控制中的相电流采样电路。通过合理的设计,可以实现高精度的电流检测,为系统的闭环控制和保护提供可靠的信号。在设计过程中,需要注意采样电阻的选择、放大倍数的设置以及滤波器的设计,以确保电路的精度和稳定性。

weixin_66732375的博客 1万+

STM32F4 BLDC无感方波六步换向驱动:三段式启动与平稳过渡的技术详解

内容概要:本文详细介绍了基于STM32F4微控制器的BLDC(无刷直流电机)无感方波六步换向驱动技术。主要内容涵盖三段式启动方式、拉直、强拖、速度闭环和平稳过渡等关键技术。文中解释了如何通过逐步调整PWM信号的占空比实现三段式启动,确保电机启动平滑并减少冲击和噪音。此外,还讨论了拉直和强拖对电机性能的影响,以及速度闭环控制如何保证电机在不同工况下的稳定运行。最后,文章提到一键启动功能及其正反转闭环运行特性,极大地方便了用户的操作。为帮助读者更好地理解和应用这些技术,作者提供了完整的CubeMX配置文件、MDK工程、原理图和开发笔记,所有代码均用C语言编写,并附有详细的中文注释。 适合人群:从事电机控制系统开发的技术人员,尤其是对STM32F4和BLDC电机感兴趣的工程师。 使用场景及目标:适用于需要深入了解STM32F4在BLDC电机控制中具体应用的研发人员,旨在掌握无感方波六步换向驱动技术,优化电机启动和运行效率。 其他说明:提供的完整资源有助于快速上手实际项目开发,降低学习成本和技术门槛。

PyTorch深度学习实战(6)——神经网络性能优化技术

神经网络性能优化技术是指通过改进神经网络的结构、参数初始化、正则化和训练过程等方面来提高其性能和泛化能力的方法。优化技术的选择和调试需要根据具体问题进行,通过不断实验和调整,找到最适合网络的优化策略。本节首先训练了一个简单的全连接网络,然后在此基础上介绍了简单有效的神经网络性能提升技巧。

盼小辉丶的博客 1万+

无刷电机FOC控制笔记

序: 矢量控制的核心思想是为了简化无刷电机的控制模型,将一个需要换相的无刷电机通过各种算法变换,抽象为一个直流电机的控制模型,只需要控制简单的两个直流分量来控制无刷电机,其中Vq抽象为直流电机的两端电压,Vd可调节电机力矩,但这个模型需要一个实时的电机轴角度θ参与计算。 为了实现这个直流电机的控制模型,需要用到两个数学变换,即clarke变换和park变换。需要用到最原始的PID控制器等内容。...

xinglucao的专栏 3万+

【国密】基于SM2的协同签名与协同解密方案

两方协同签名指客户端与服务端协同完成签名、验签操作,具体实现方案参考了信工所专利[3]。在业务应用中,两方或多方的协同签名一般采用门限签名方案可以用来构造。门限密码算法在多方协作的相关场景中应用十分广泛,可以实现数据联合授权、认证、密钥安全恢复、密钥安全交换等需求,在诸多分布式多方计算协议中均可见其身影。在上述两方协同签名方案中,最巧妙的地方在于签名值s分量的构造,通过一些列数学变换,得以恢复。以下从两方协同签名方案介绍入手,介绍门限密码在协同签名中的应用。解决上述问题的关键在于门限密码算法的巧妙构造。

听雨草堂 8392

stm32无感无刷电机驱动

前言: 使用stm32如何去控制无刷电机? 首先我们先要知道无刷电机的工作原理是什么,这样我们才能针对实际需求,对stm32 进行点对点的内部资源的调用,从而进行程序编写。 我相信能搜到这个Blog的同学都对无刷电机有一个大概的了解,但是具体的使用细节和原理,可能不太清楚。 无刷电机的工作原理。 ...

richardgann的博客 4万+

【数据集总结】不透水面积ISA:GAIA、CLUD-Urban、GISA

【数据集总结】不透水面积ISA:GAIA、CLUD-Urban、GISA

WW、forever的博客 2159

14 硬件工程师笔面试高频考点真题解析——逻辑门

逻辑门是数字电路的基本单元,实现布尔运算(如与、或、非、异或等)。OC门(集电极开路)和OD门(漏极开路)需外接上拉电阻,支持“线与”逻辑,适用于I2C总线等场景,避免推挽输出并联导致的短路问题。三态门具有高、低、高阻三种状态,用于总线分时复用。推挽输出因内置上下管,禁止并联,否则会引发电源短路。三者区别在于:推挽驱动强但不可并联;OC/OD需上拉,支持线与;三态门通过使能控制实现高阻隔离,适用于共享总线设计。

XU157303764的博客 1904
上一篇: 位置式 PID、增量式 PID、PI、PD控制和前馈控制简谈
下一篇: 永磁同步电机 FOC 控制中 d、q 轴杂谈与角度偏移影响
崔佳宇_
崔佳宇_ 优质创作者: 嵌入式与硬件开发技术领域 优质创作者: 嵌入式与硬件开发技术领域
博客等级 码龄10年 1万+粉丝 173原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值