你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

驱动BLDC电机发出蜂鸣声

[复制链接]
CM_STM32 发布时间:2026-7-17 13:44

1.蜂鸣原理

在消费级无人机解锁、手持电动工具自检或工业协作机器人启动时,操作者往往需要一种直观的听觉反馈来确认设备状态。许多设计选择利用电机线圈本身来发出蜂鸣声,节省了额外的蜂鸣器硬件空间,还能直接利用现有的驱动控制算法。 电机发声的机理与动圈式扬声器很相似,在BLDC电机中,定子绕组就相当于“音圈”,转子永磁体提供了磁场。当向绕组注入高频的交变电流时,定子产生的交变磁场会与转子的永磁场相互作用,产生高频波动的电磁转矩。这种高频波会引起定子齿、绕组线圈以及电机外壳的高频振动,发出声音。 在FOC框架下,我们将三相坐标系下的电流通过Clarke变换映射到α-β平面。为了让电机只发声而不旋转,最理想的方法是在α轴上注入信号:在α轴上施加一个高频的正弦波或方波电压信号,保持β轴电压为0。这种单轴向的高频脉冲产生的平均力矩为零,转子只会在原位发生小幅度的往复微振,不会产生连续旋转。 通过SVPWM调制,系统可以利用功率管的快速开关模拟出这一高频电压向量。FOC矢量注入可以将参考电压矢量精确地映射为三相PWM,占空比受控,使得声学效果更稳定。 改变电压的频率可以改变声音音调;改变幅值则可以改变响度。

2.技术实现

本工程依然在MCSDK生成的代码框架下进行修改和开发,关于MCSDK的使用、开发板硬件说明等等,可以参考前面几篇文章:为了验证可行性,尝试编写代码,在2208电机启动前加入两声蜂鸣声。IDLE 状态下按下按钮 → 蜂鸣1开始 → 蜂鸣1(250ms) → 间隔(90ms) → 蜂鸣2开始 → 蜂鸣2(250ms) → 启动电机

关键参数设置

在 mc_tasks.c 中,定义了几个可调节的宏定义:

参数 含义
PRESTART_BEEP_ON_MS 250ms 每段蜂鸣持续时间
PRESTART_BEEP_GAP1_MS 90ms 两段蜂鸣间隔
PRESTART_BEEP1_HALF_MS 1ms 半周期
PRESTART_BEEP1_AMP 28000 第一段蜂鸣振幅
PRESTART_BEEP2_AMP 22000 第二段蜂鸣振幅

半周期用于调节PWM的频率;最后两个幅值参数的范围是 [-32767, 32767],用于调节响度。28000和22000两个不同的振幅可以验证电压幅值对响度的影响。

声明了用于状态机的几个全局变量:

static volatile bool g_prestart_beep_pending = false; 
static PrestartBeepState_t g_prestart_beep_state = PRESTART_BEEP_IDLE; //状态机
static uint32_t g_prestart_beep_tick = 0U; 
static uint32_t g_prestart_beep_mod_tick = 0U;
static bool g_prestart_beep_wave_positive = true; //标志位,用于反转波形

用于状态机的结构体,标志蜂鸣执行的状态:

typedef enum
{
  PRESTART_BEEP_IDLE = 0,
  PRESTART_BEEP_1_ON,
  PRESTART_BEEP_1_GAP,
  PRESTART_BEEP_2_ON,
  PRESTART_BEEP_2_GAP
} PrestartBeepState_t;

波形生成方式

每个蜂鸣段内部以1ms的半周期快速翻转α轴的电压极性,等效为产生500Hz的双极性方波信号,比如幅值为28000的方波,就是在28000和-28000之间翻转。在电机的机械特性和绕圈电感作用下,这个方波会转化为相对平滑的周期性激励,驱动结构振动发声。

我们的函数都在mc_tasks.c中定义和调用: UI_ApplyPrestartBeepVector():每个半周期翻转一次 g_prestart_beep_wave_positive 标志位,产生双极性的方波信号。PWMC_SetPhaseVoltage() 函数的调用可以自动计算对应的PWM波形并驱动MOS管。 关于PWMC_SetPhaseVoltage()接口的介绍可以在用户文档里的Component/PWM & Current Feedback里面找到:f47f5059-327a-42d2-bd55-9a5597552805.png

文档文本大意:作用是将α和β的电压转换成PWM占空比并将其馈送到逆变器。该函数计算每个相位的晶体管在PWM周期内被接通的时间,以达到由Valfa_beta设定的参考相位电压。然后,该函数对相关定时器通道中的占空比进行编程。它还相应地设置下一个PWM周期的相电流采样点。

static inline void UI_ApplyPrestartBeepVector(PrestartBeepState_t state)
{
  alphabeta_t v;
  int16_t amp = UI_GetPrestartBeepAmp(state);

  v.alpha = g_prestart_beep_wave_positive ? amp : (-amp);  // +-交替
  v.beta = 0;
  (void)PWMC_SetPhaseVoltage(pwmcHandle[M1], v);  // 施加到电机
}

状态机

蜂鸣过程由状态机统一调度,我们利用 HAL_GetTick() 获取系统运行时间,并依据预设参数控制两段蜂鸣的时序。在蜂鸣持续期间,通过翻转g_prestart_beep_wave_positive标志位,生成方波信号,并调用前面实现的UI_ApplyPrestartBeepVector()函数将电压施加到电机上,使其振动发声。 在蜂鸣完毕后,自动调用MC_StartMotor1()启动电机。

//这两个可以在文件头用户自定义区加入,用于判断两声蜂鸣的频率和振幅
static inline uint32_t UI_GetPrestartBeepHalfMs(PrestartBeepState_t state)
{
  return (state == PRESTART_BEEP_1_GAP) ? PRESTART_BEEP1_HALF_MS : PRESTART_BEEP2_HALF_MS;
}

static inline int16_t UI_GetPrestartBeepAmp(PrestartBeepState_t state)
{
  return (state == PRESTART_BEEP_1_GAP) ? PRESTART_BEEP1_AMP : PRESTART_BEEP2_AMP;
}

在用户区实现状态机:

/* USER CODE BEGIN Private Functions */
static void UI_ProcessPrestartBeep(void)
{
  uint32_t now;

  if (!g_prestart_beep_pending)
  {
    return;
  }

  if (IDLE != MC_GetSTMStateMotor1())
  {
    g_prestart_beep_pending = false;
    g_prestart_beep_state = PRESTART_BEEP_IDLE;
    PWMC_SwitchOffPWM(pwmcHandle[M1]);
    return;
  }

  now = HAL_GetTick();

  switch (g_prestart_beep_state)
  {
    case PRESTART_BEEP_1_ON:
      g_prestart_beep_tick = now;
      g_prestart_beep_mod_tick = now;
      g_prestart_beep_wave_positive = true;
      PWMC_SwitchOnPWM(pwmcHandle[M1]);
      UI_ApplyPrestartBeepVector(PRESTART_BEEP_1_GAP);
      g_prestart_beep_state = PRESTART_BEEP_1_GAP;
      break;

    case PRESTART_BEEP_1_GAP:
      if ((now - g_prestart_beep_tick) >= PRESTART_BEEP_ON_MS)
      {
        PWMC_SwitchOffPWM(pwmcHandle[M1]);
        g_prestart_beep_tick = now;
        g_prestart_beep_state = PRESTART_BEEP_2_ON;
      }
      else if ((now - g_prestart_beep_mod_tick) >= UI_GetPrestartBeepHalfMs(g_prestart_beep_state))
      {
        g_prestart_beep_mod_tick = now;
        g_prestart_beep_wave_positive = !g_prestart_beep_wave_positive;
        UI_ApplyPrestartBeepVector(g_prestart_beep_state);
      }
      break;

    case PRESTART_BEEP_2_ON:
      if ((now - g_prestart_beep_tick) >= PRESTART_BEEP_GAP1_MS)
      {
        g_prestart_beep_mod_tick = now;
        g_prestart_beep_wave_positive = true;
        PWMC_SwitchOnPWM(pwmcHandle[M1]);
        UI_ApplyPrestartBeepVector(PRESTART_BEEP_2_GAP);
        g_prestart_beep_tick = now;
        g_prestart_beep_state = PRESTART_BEEP_2_GAP;
      }
      break;

    case PRESTART_BEEP_2_GAP:
      if ((now - g_prestart_beep_tick) >= PRESTART_BEEP_ON_MS)
      {
        PWMC_SwitchOffPWM(pwmcHandle[M1]);
        g_prestart_beep_tick = now;
        g_prestart_beep_state = PRESTART_BEEP_IDLE;
        g_prestart_beep_pending = false;
        g_as5600_gimbal_hold_active = false;
        (void)MC_StartMotor1();
      }
      else if ((now - g_prestart_beep_mod_tick) >= UI_GetPrestartBeepHalfMs(g_prestart_beep_state))
      {
        g_prestart_beep_mod_tick = now;
        g_prestart_beep_wave_positive = !g_prestart_beep_wave_positive;
        UI_ApplyPrestartBeepVector(g_prestart_beep_state);
      }
      break;

    case PRESTART_BEEP_IDLE:
    default:
      g_prestart_beep_pending = false;
      break;
  }

  if ((!g_prestart_beep_pending) && ((HAL_GetTick() - g_prestart_beep_tick) > PRESTART_BEEP_GAP2_MS))
  {
    /* Keep timing constants intentionally visible for future tuning. */
  }
}

MC_RunMotorControlTasks()中调用上面我们编写的状态机函数:

__weak void MC_RunMotorControlTasks(void)
{
  if (0U == bMCBootCompleted)
  {
    /* Nothing to do */
  }
  else
  {
    /* ** Medium Frequency Tasks ** */
/* USER CODE BEGIN MC_Scheduler 0 */
  UI_SyncUserControlMode();
    UI_ProcessPrestartBeep();

/* USER CODE END MC_Scheduler 0 */
//……后面省略

整个过程在中速FOC任务中处理,这个任务是在SysTick_Handler中运行的,靠中断进入,不阻塞主循环,确保系统实时性不受影响。调度链如下: SysTick → MC_RunMotorControlTasks → UI_ProcessPrestartBeep

实验结果可以清晰发出两声“哔哔”提示音。

4.小结

本文利用FOC控制框架,通过在α轴注入高频双极性电压信号,实现了无需额外硬件的电机蜂鸣功能。该方法利用电机结构的机械振动特性,将电磁激励转化为声波输出。

收藏 评论0 发布时间:2026-7-17 13:44

举报

0个回答

所属标签

ST 电机控制

意法半导体提供完整的电机控制解决方案,包括合适的电子器件,诸如集成式智能功率模块和系统级封装、单片式电机驱动器、快速高效的功率开关、具有电压暂态保护功能的可控硅、以及功能强大且安全的微控制器等。以及提供完整的生态系统(包括一系列评估板、参考设计、固件和开发工具),以简化和加速设计流程。


最新内容

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版