首页 > 其他分享 >STM32驱动无刷电机用PID实现速度环控制 保姆级教程

STM32驱动无刷电机用PID实现速度环控制 保姆级教程

时间:2024-10-13 19:20:13浏览次数:9  
标签:sum 环控制 PID VM 无刷电机 M1 pHandle Output

各位,9月份,我花了差不多1个月时间,实现了STM32用六步换相法驱动无刷电机的程序编制和调试。那么,既然电机都转起来了,怎么也得搞个PID实现速度环控制嘛。于是,我就开始学习无刷电机的速度环PID控制,抱歉我是对PID一无所知的小白。

结果,花了我3天时间,居然实现了速度环PID控制,本着传播优秀知识,造福中华民族和全人类的宗旨,我现在来写个保姆级教程,来教大家怎么实现这个速度环PID。

首先,还是要感谢下列人员,在我开发PID中对我的帮助。

1. 参考了下列文章:

使用stm32实现电机的PID控制_stm32pid控制电机-CSDN博客

使用STM32实现对电机的PID控制_stm32 pid控制算法代码-CSDN博客 

UM2124_基于STM32F单片机的six-step固件库的入门指南 | STMCU中文官网 

感谢安富利的Cavin, 感谢QQ群的 GuanGuan和Medivh。

2. 这个没有什么好配置的,直接上代码吧

pid.h

#define KP_GAIN_VM                         4000     /*!< Kp parameter for PI regulator */
#define KI_GAIN_VM                           30     /*!< Ki parameter for PI regulator */   
#define KP_DIV_VM                          8192     /*!< Kp parameter divider for PI regulator */
#define KI_DIV_VM                          8192     /*!< Ki parameter divider for PI regulator */   
#define LOWER_OUT_LIMIT_VM                  400     /*!< Low Out value of PI regulator */      
#define UPPER_OUT_LIMIT_VM     (int16_t)(period*0.8)     /*!< High Out value of PI regulator */   

typedef struct
{
    int16_t Kp_Gain;                      /*!< Kp value for PI regulator */ 
    int16_t Ki_Gain;                      /*!< Ki value for PI regulator */  
    int16_t Lower_Limit_Output;           /*!< Min output value for PI regulator */ 
    int16_t Upper_Limit_Output;           /*!< Max output value for PI regulator */ 
    int8_t Max_PID_Output;                /*!< Max Saturation indicator flag */ 
    int8_t Min_PID_Output;                /*!< Min Saturation indicator flag */
    int32_t Integral_sum;
}PID_Handle_t;

pih.c

void PID_HandleInit(PID_Handle_t *pHandle)
{
    pHandle->Kp_Gain = KP_GAIN_VM;
    pHandle->Ki_Gain = KI_GAIN_VM;
    pHandle->Lower_Limit_Output = LOWER_OUT_LIMIT_VM;
    pHandle->Upper_Limit_Output = UPPER_OUT_LIMIT_VM;
    pHandle->Max_PID_Output = RESET;
    pHandle->Min_PID_Output = RESET;
    pHandle->Integral_sum = 0;
}

uint16_t PI_Controller(PID_Handle_t *pHandle, int32_t hError)
{
    int32_t wProportional_Term=0, wIntegral_Term=0, wOutput_32=0,wIntegral_sum_temp=0;

    wProportional_Term = pHandle->Kp_Gain * hError;

    if(pHandle->Ki_Gain == 0)
    {
        pHandle->Integral_sum=0;
    }
    else
    {
        wIntegral_Term=pHandle->Ki_Gain * hError;
        wIntegral_sum_temp = pHandle->Integral_sum + wIntegral_Term;
        pHandle->Integral_sum = wIntegral_sum_temp;
    }

    if(pHandle->Integral_sum > KI_DIV_VM*pHandle->Upper_Limit_Output)
    {
        pHandle->Integral_sum = KI_DIV_VM*pHandle->Upper_Limit_Output;
    }

    if(pHandle->Integral_sum < -KI_DIV_VM*pHandle->Upper_Limit_Output)
    {
        pHandle->Integral_sum = -KI_DIV_VM*pHandle->Upper_Limit_Output;
    }

    wOutput_32 = (wProportional_Term/KP_DIV_VM) + (pHandle->Integral_sum/KI_DIV_VM);

    if(wOutput_32 > pHandle->Upper_Limit_Output)
    {
        wOutput_32 = pHandle->Upper_Limit_Output;
    }
    else if(wOutput_32 < pHandle->Lower_Limit_Output)
    {
        wOutput_32 = pHandle->Lower_Limit_Output;
    }

    
    return (uint16_t)wOutput_32;
    
}

uint16_t Speed_Controller(PID_Handle_t *PISpeed, int32_t targetSpeed, int32_t realSpeed)
{
    uint16_t hDutyCycleReference=0;

    int32_t hError;

    hError = targetSpeed - realSpeed;

    hDutyCycleReference = PI_Controller(PISpeed, hError);

  //  usb_printf("pulse is %d\r\n", hDutyCycleReference);

    return hDutyCycleReference;

}

电机控制程序重要片段

 if(htim->Instance==TIM2)
  {

    if(M1_motor_status==2) // motor is running
    {
      M1_hall_pos = M1_get_hall_pos();
      if(M1_pre_hall_pos!=M1_hall_pos)
      {
        M1_pre_hall_pos=M1_hall_pos;
        //__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, (uint32_t)(period/1.2));  //1.2
        //__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, (uint32_t)(period/1.8));  //1.8
        //__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, (uint32_t)(period/2.5));  //2.5

       __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, (uint32_t)Speed_Controller(&speedPID, M1_target_speed, M1_motor_speed));
       __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, (uint32_t)Speed_Controller(&speedPID, M1_target_speed, M1_motor_speed));
       __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, (uint32_t)Speed_Controller(&speedPID, M1_target_speed, M1_motor_speed));

        M1_motor_change(M1_hall_pos, motor_direction);
      }
    }
  }

3.运行结果确认

将target_speed设定为800rpm, 下面是实际PID调速的结果。

 

基本实现了800rpm的调速。

至此,STM32 无刷电机的PID速度环控制,大功告成,亲个嘴儿。

标签:sum,环控制,PID,VM,无刷电机,M1,pHandle,Output
From: https://blog.csdn.net/dqsh06/article/details/142885287

相关文章

  • [Paper Reading] TouchInsight: Uncertainty-aware Rapid Touch and Text Input for M
    目录TouchInsight:Uncertainty-awareRapidTouchandTextInputforMixedRealityfromEgocentricVisionTL;DRMethod模型中的数据流touchlocalizationLossProbabilisticcommandpredictExperimentAblation打字速度模型部署效果可视化总结与发散资料查询TouchInsight:Unc......
  • 【应急响应+Linux】常见的rootkit隐藏手段:通过挂载/proc/pid实现pid隐藏
    原理ps、netstat是遍历/proc来显示pid的原理,通过隐藏相关/proc/pid文件夹来实现pid隐藏实现运行如下命令,将pid对应文件夹挂载到隐藏目录上面mount-obind/home/.hidden/proc/9212现象:如下图,使用root权限调用netstat发现PID和Programname都是空:排查方法1、ca......
  • PID学习
    直立环PD,速度环PI,转向环PDPID的实例对小球进行速度控制pid目标值:需要小球达到的速度pid反馈值:小球的实时速度pid输出值:施加在小球上的力对电机的转速进行控制pid目标值:需要电机达到的转速pid反馈值:电机的实时转速pid输出值:电机中流过电流的大小毕竟微积分都是......
  • 'FK_StudentEducation_Student_StudentTrackSignupId' 不是约束。 未能删除约束。请参
    Student主表StudentEducation从表建表的时候外键约束名写错了,不能数据库直接改通过映射文件想要删掉外键重新生成protectedoverridevoidUp(MigrationBuildermigrationBuilder){migrationBuilder.DropForeignKey("FK_StudentEducation_Student_StudentTrackSignupId",......
  • 支付宝公匙 私匙 APPID 配置方法
    相信很多站长都给自己的网站开通了网上支付功能,而网上支付最方便的要属支付宝与微信了,我们抛开微信支付不谈,说一说支付宝支付的公匙,私匙以及APPID的获取方法!使用支付宝支付需要创建应用后进行签约,比如当付面(不强制使用营业执照),手机支付,网站支付,转账等,这里的签约自己根据支付宝......
  • pwm模拟遥控器驱动电调控制无刷电机
    目录1.前言2.操作全程2.1输出pwm信号2.2硬件部分2.3电调校准3.启动4.总结1.前言我们小伙伴是不是都遇到到过我们的无刷电机买回来,上电,并且给了正确的pwm超,但是电机就是不转动。我也遇到了这个问题,不过最后还是让我蒙对了,哈哈。下面开始我们的操作。本人学识尚浅,如果......
  • spider
    目录PrefaceArchitectureComponentsScrapyEngineSchedulerDownloaderSpidersItemPipelineExampleDemandStepSpecifythecontentwearedesiredtocrawlPrefaceScrapyisanapplicationframeworkforcrawlingwebsitesandextractingstructureddatawhichcanbeu......
  • SimForPlc仿真设备联合西门子PLC1500进行液位PID控制
    SimForPlc仿真设备联合西门子PLC1500进行液位PID控制准备PLC编程软件 博途V15  TIAPortalV15.1仿真PLC    S7-PLCSIMAdvancedV4.0SP1PLC仿真设备SimForPlc仿真设备项目的具体要求通过SimForPlc仿真设备联合西门子PLC1500进行液位PID控制的练习,我们可以掌......
  • POL8901升级POL8903 2 PORT LVDS转MIPIDSI点屏+旋转,大批量出货物料
    LVDS输入:支持1或者2通道LVDS输入;支持最大1920x1080@60Hz输入;兼容VESA和JEIDA格式:通道内5条差分信号对,支持1clock/4data独立任意映射和极性翻转;MIPI输出:兼容DCS1.02,D-PHY1.2.DSI1.2andCSl-21.00;支持最大输出分辨率1080x1920@60Hz;5条差分信号对,支......
  • 科普向:USB设备的PID、VID和GUID分别代表什么
    USB设备的PID、VID和GUID分别代表什么在USB设备中,PID、VID和GUID是用于标识和管理设备的重要标识符。以下是它们的具体含义:1.VID(VendorID)VID代表供应商ID,它是由USB实现者论坛(USB-IF)分配给每个USB设备制造商的唯一标识符。每个制造商在制造USB设备时都......