找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9731|回复: 7
打印 上一主题 下一主题
收起左侧

STM32大功率直流有刷电机电流位置式PID闭环控制源程序与资料

  [复制链接]
跳转到指定楼层
楼主
能不能帮忙看下这个程序


单片机源程序如下:
  1. /**
  2.   ******************************************************************************
  3.   * 文件名程: main.c
  4.   * 作    者: 硬石嵌入式开发团队
  5.   * 版    本: V1.0
  6.   * 功    能: 有刷直流电机位置闭环控制_位置式PID
  7.   ******************************************************************************
  8.   * 说明:
  9.   * 本例程配套硬石stm32开发板YS-F1Pro使用。
  10.   * 版权归硬石嵌入式开发团队所有,请勿商用。
  11.   ******************************************************************************
  12.   */
  13. /* 包含头文件 ----------------------------------------------------------------*/
  14. #include "stm32f4xx_hal.h"
  15. #include "key/bsp_key.h"
  16. #include "encoder/bsp_encoder.h"
  17. #include "usart/bsp_usartx.h"
  18. #include "DCMotor/bsp_BDCMotor.h"
  19. #include "led/bsp_led.h"
  20. /* 私有类型定义 --------------------------------------------------------------*/
  21. typedef struct
  22. {
  23.   __IO int32_t  SetPoint;                                 //设定目标 Desired Value
  24.   __IO float    SumError;                                //误差累计
  25.   __IO float    Proportion;                               //比例常数 Proportional Const
  26.   __IO float    Integral;                                 //积分常数 Integral Const
  27.   __IO float    Derivative;                               //微分常数 Derivative Const
  28.   __IO int      LastError;                                //Error[-1]
  29.   __IO int      PrevError;                                //Error[-2]
  30. }PID_TypeDef;

  31. /* 私有宏定义 ----------------------------------------------------------------*/

  32. /*************************************/
  33. // 定义PID相关宏
  34. // 这三个参数设定对电机运行影响非常大
  35. // PID参数跟采样时间息息相关
  36. /*************************************/
  37. #define  SPD_P_DATA      1.025f        // P参数
  38. #define  SPD_I_DATA      0.215f        // I参数
  39. #define  SPD_D_DATA      0.1f         // D参数
  40. #define  TARGET_LOC    11880        // 目标速度    1 r

  41. /* 私有变量 ------------------------------------------------------------------*/
  42. __IO uint8_t  Start_flag = 0;       // PID 开始标志
  43. __IO uint32_t Motor_Dir = CW;             // 电机方向
  44. __IO int32_t Loc_Pulse;              // 编码器捕获值 Pulse

  45. /* 扩展变量 ------------------------------------------------------------------ */
  46. extern __IO uint32_t uwTick;

  47. /* PID结构体 */
  48. PID_TypeDef  sPID;               // PID参数结构体

  49. /* 扩展变量 ------------------------------------------------------------------*/
  50. /* 私有函数原形 --------------------------------------------------------------*/
  51. void PID_ParamInit(void) ;
  52. int32_t LocPIDCalc(int32_t NextPoint);
  53. /* 函数体 --------------------------------------------------------------------*/
  54. /**
  55.   * 函数功能: 系统时钟配置
  56.   * 输入参数: 无
  57.   * 返 回 值: 无
  58.   * 说    明: 无
  59.   */
  60. void SystemClock_Config(void)
  61. {
  62.   RCC_OscInitTypeDef RCC_OscInitStruct;
  63.   RCC_ClkInitTypeDef RCC_ClkInitStruct;

  64.   __HAL_RCC_PWR_CLK_ENABLE();                                     // 使能PWR时钟

  65.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);  // 设置调压器输出电压级别1

  66.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;      // 外部晶振,8MHz
  67.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;                        // 打开HSE
  68.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;                    // 打开PLL
  69.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;            // PLL时钟源选择HSE
  70.   RCC_OscInitStruct.PLL.PLLM = 8;                                 // 8分频MHz
  71.   RCC_OscInitStruct.PLL.PLLN = 336;                               // 336倍频
  72.   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;                     // 2分频,得到168MHz主时钟
  73.   RCC_OscInitStruct.PLL.PLLQ = 7;                                 // USB/SDIO/随机数产生器等的主PLL分频系数
  74.   HAL_RCC_OscConfig(&RCC_OscInitStruct);

  75.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  76.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  77.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;       // 系统时钟:168MHz
  78.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;              // AHB时钟: 168MHz
  79.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;               // APB1时钟:42MHz
  80.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;               // APB2时钟:84MHz
  81.   HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);

  82.   HAL_RCC_EnableCSS();                                            // 使能CSS功能,优先使用外部晶振,内部时钟源为备用

  83.          // HAL_RCC_GetHCLKFreq()/1000    1ms中断一次
  84.         // HAL_RCC_GetHCLKFreq()/100000         10us中断一次
  85.         // HAL_RCC_GetHCLKFreq()/1000000 1us中断一次
  86.   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);                 // 配置并启动系统滴答定时器
  87.   /* 系统滴答定时器时钟源 */
  88.   HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  89.   /* 系统滴答定时器中断优先级配置 */
  90.   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
  91. }

  92. /**
  93.   * 函数功能: 主函数.
  94.   * 输入参数: 无
  95.   * 返 回 值: 无
  96.   * 说    明: 无
  97.   */
  98. int main(void)
  99. {
  100.   /* 复位所有外设,初始化Flash接口和系统滴答定时器 */
  101.   HAL_Init();
  102.   /* 配置系统时钟 */
  103.   SystemClock_Config();
  104.   /* 串口初始化 */
  105.   MX_USARTx_Init();
  106.   /* LED初始化 */
  107.   LED_GPIO_Init();
  108.   /* 按键初始化 */
  109.   KEY_GPIO_Init();
  110.   /* 编码器初始化及使能编码器模式 */
  111.   ENCODER_TIMx_Init();
  112.         /* 高级控制定时器初始化并配置PWM输出功能 */
  113.   BDCMOTOR_TIMx_Init();
  114.   /* 设定占空比 */
  115.   PWM_Duty = 0;
  116.   SetMotorSpeed(PWM_Duty);  // 0%
  117.   /* PID 参数初始化 */
  118.   PID_ParamInit();
  119.   /* 无限循环 */
  120.   while (1)
  121.   {
  122.     /* 停止按钮 */
  123.     if(KEY1_StateRead()==KEY_DOWN)
  124.     {
  125.       if(sPID.SetPoint > 0)
  126.       {
  127.         Motor_Dir = CCW;
  128.         BDDCMOTOR_DIR_CCW();
  129.       }
  130.       else
  131.       {
  132.         Motor_Dir = CW;
  133.         BDDCMOTOR_DIR_CW();
  134.       }
  135.       Start_flag = 1;
  136.     }
  137.     if(KEY2_StateRead()==KEY_DOWN)
  138.     {
  139.       SHUTDOWN_MOTOR();
  140.       HAL_TIM_PWM_Stop(&htimx_BDCMOTOR,TIM_CHANNEL_1);
  141.       HAL_TIMEx_PWMN_Stop(&htimx_BDCMOTOR,TIM_CHANNEL_1);         // 停止输出
  142.     }
  143.     if(KEY3_StateRead()==KEY_DOWN)//加速
  144.     {
  145.       sPID.SetPoint += 11880; // +1 r
  146.     }
  147.     if(KEY4_StateRead()==KEY_DOWN)//减速
  148.     {
  149.       sPID.SetPoint -= 11880; // -1 r
  150.     }
  151.   }
  152. }

  153. /**
  154.   * 函数功能: 系统滴答定时器中断回调函数
  155.   * 输入参数: 无
  156.   * 返 回 值: 无
  157.   * 说    明: 每发生一次滴答定时器中断进入该回调函数一次
  158.   */
  159. void HAL_SYSTICK_Callback(void)
  160. {
  161.   int32_t tmpPWM_Duty = 0;
  162.   /* 速度环周期100ms */
  163.   if(uwTick % 100 == 0)
  164.   {
  165.     Loc_Pulse = (OverflowCount*CNT_MAX) + (int32_t)__HAL_TIM_GET_COUNTER(&htimx_Encoder);

  166.     /* 计算PID结果 */
  167.     if(Start_flag == 1)
  168.     {
  169.       /* 限定速度 */
  170.       PWM_Duty = LocPIDCalc(Loc_Pulse);
  171.       if(PWM_Duty >= BDCMOTOR_DUTY_FULL/2)
  172.         PWM_Duty = BDCMOTOR_DUTY_FULL/2;
  173.       if(PWM_Duty <= -BDCMOTOR_DUTY_FULL/2)
  174.         PWM_Duty = -BDCMOTOR_DUTY_FULL/2;

  175.       /* 判断当前运动方向 */
  176.       if(PWM_Duty < 0)
  177.       {
  178.         Motor_Dir = CW;
  179.         BDDCMOTOR_DIR_CW();
  180.         tmpPWM_Duty = -PWM_Duty;
  181.       }
  182.       else
  183.       {
  184.         Motor_Dir = CCW;
  185.         BDDCMOTOR_DIR_CCW();
  186.         tmpPWM_Duty = PWM_Duty;
  187.       }
  188.       /* 输出PWM */
  189.       SetMotorSpeed( tmpPWM_Duty );
  190.     }
  191.     printf(" Loc: %d (Pulse) = %.3f (r) \n",Loc_Pulse, (float)Loc_Pulse/11880.0f);
  192.   }
  193. }
  194. /******************** PID 控制设计 ***************************/
  195. /**
  196.   * 函数功能: PID参数初始化
  197.   * 输入参数: 无
  198.   * 返 回 值: 无
  199.   * 说    明: 无
  200.   */
  201. void PID_ParamInit()
  202. {
  203.     sPID.LastError = 0;               // Error[-1]
  204.     sPID.PrevError = 0;               // Error[-2]
  205.     sPID.Proportion = SPD_P_DATA; // 比例常数 Proportional Const
  206.     sPID.Integral = SPD_I_DATA;   // 积分常数  Integral Const
  207.     sPID.Derivative = SPD_D_DATA; // 微分常数 Derivative Const
  208.     sPID.SetPoint = TARGET_LOC;     // 设定目标Desired Value
  209. }
  210. /**
  211.   * 函数名称:位置闭环PID控制设计
  212.   * 输入参数:当前控制量
  213.   * 返 回 值:目标控制量
  214.   * 说    明:无
  215.   */
  216. int32_t LocPIDCalc(int32_t NextPoint)
  217. {
  218.   int32_t iError,dError;
  219.   iError = sPID.SetPoint - NextPoint; //偏差

  220.   if( (iError<50) && (iError>-50) )
  221.     iError = 0;

  222.   /* 限定积分区域 */
  223.   if((iError<400 )&& (iError>-400))
  224.   {
  225.     sPID.SumError += iError; //积分
  226.     /* 设定积分上限 */
  227.     if(sPID.SumError >= (TARGET_LOC*10))
  228.        sPID.SumError  = (TARGET_LOC*10);
  229.     if(sPID.SumError <= -(TARGET_LOC*10))
  230.       sPID.SumError = -(TARGET_LOC*10);
  231.   }

  232.   dError = iError - sPID.LastError; //微分
  233.   sPID.LastError = iError;
  234.   return (int32_t)( (sPID.Proportion * (float)iError) //比例项
  235.                     + (sPID.Integral * (float)sPID.SumError) //积分项
  236.                     + (sPID.Derivative * (float)dError) ); //微分项
  237. }

  238. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码


所有资料51hei提供下载:
YSF4_HAL_MOTOR-011. 直流有刷电机_位置闭环控制_位置式PID.7z (3.83 MB, 下载次数: 265)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏10 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:309613 发表于 2019-4-11 10:42 | 只看该作者
谢谢楼主分享!
回复

使用道具 举报

板凳
ID:483754 发表于 2019-6-3 11:06 | 只看该作者
讲的很好
回复

使用道具 举报

地板
ID:59224 发表于 2019-7-26 21:47 | 只看该作者
感谢楼主的贡献
回复

使用道具 举报

5#
ID:631267 发表于 2019-10-28 10:46 | 只看该作者
找了好久,谢谢。。。
回复

使用道具 举报

6#
ID:785535 发表于 2020-6-21 08:18 | 只看该作者
the brush DC motor is nice
回复

使用道具 举报

7#
ID:258522 发表于 2021-7-27 10:27 | 只看该作者
学习一下,有没有库函数的例程
回复

使用道具 举报

8#
ID:228452 发表于 2022-4-2 20:24 | 只看该作者
Do you have schematic diagram for DC motor driver board ?
It is not possible to  check the software
thank you
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表