找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10715|回復: 7
收起左側

STM32大功率直流有刷電機電流位置式PID閉環(huán)控制源程序與資料

  [復制鏈接]
ID:444817 發(fā)表于 2018-12-25 20:51 | 顯示全部樓層 |閱讀模式
能不能幫忙看下這個程序
0.jpg

單片機源程序如下:
  1. /**
  2.   ******************************************************************************
  3.   * 文件名程: main.c
  4.   * 作    者: 硬石嵌入式開發(fā)團隊
  5.   * 版    本: V1.0
  6.   * 功    能: 有刷直流電機位置閉環(huán)控制_位置式PID
  7.   ******************************************************************************
  8.   * 說明:
  9.   * 本例程配套硬石stm32開發(fā)板YS-F1Pro使用。
  10.   * 版權歸硬石嵌入式開發(fā)團隊所有,請勿商用。
  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;                               //比例常數(shù) Proportional Const
  26.   __IO float    Integral;                                 //積分常數(shù) Integral Const
  27.   __IO float    Derivative;                               //微分常數(shù) Derivative Const
  28.   __IO int      LastError;                                //Error[-1]
  29.   __IO int      PrevError;                                //Error[-2]
  30. }PID_TypeDef;

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

  32. /*************************************/
  33. // 定義PID相關宏
  34. // 這三個參數(shù)設定對電機運行影響非常大
  35. // PID參數(shù)跟采樣時間息息相關
  36. /*************************************/
  37. #define  SPD_P_DATA      1.025f        // P參數(shù)
  38. #define  SPD_I_DATA      0.215f        // I參數(shù)
  39. #define  SPD_D_DATA      0.1f         // D參數(shù)
  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參數(shù)結構體

  49. /* 擴展變量 ------------------------------------------------------------------*/
  50. /* 私有函數(shù)原形 --------------------------------------------------------------*/
  51. void PID_ParamInit(void) ;
  52. int32_t LocPIDCalc(int32_t NextPoint);
  53. /* 函數(shù)體 --------------------------------------------------------------------*/
  54. /**
  55.   * 函數(shù)功能: 系統(tǒng)時鐘配置
  56.   * 輸入?yún)?shù): 無
  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/隨機數(shù)產生器等的主PLL分頻系數(shù)
  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;       // 系統(tǒng)時鐘: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功能,優(yōu)先使用外部晶振,內部時鐘源為備用

  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);                 // 配置并啟動系統(tǒng)滴答定時器
  87.   /* 系統(tǒng)滴答定時器時鐘源 */
  88.   HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  89.   /* 系統(tǒng)滴答定時器中斷優(yōu)先級配置 */
  90.   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
  91. }

  92. /**
  93.   * 函數(shù)功能: 主函數(shù).
  94.   * 輸入?yún)?shù): 無
  95.   * 返 回 值: 無
  96.   * 說    明: 無
  97.   */
  98. int main(void)
  99. {
  100.   /* 復位所有外設,初始化Flash接口和系統(tǒng)滴答定時器 */
  101.   HAL_Init();
  102.   /* 配置系統(tǒng)時鐘 */
  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 參數(shù)初始化 */
  118.   PID_ParamInit();
  119.   /* 無限循環(huán) */
  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.   * 函數(shù)功能: 系統(tǒng)滴答定時器中斷回調函數(shù)
  155.   * 輸入?yún)?shù): 無
  156.   * 返 回 值: 無
  157.   * 說    明: 每發(fā)生一次滴答定時器中斷進入該回調函數(shù)一次
  158.   */
  159. void HAL_SYSTICK_Callback(void)
  160. {
  161.   int32_t tmpPWM_Duty = 0;
  162.   /* 速度環(huán)周期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.   * 函數(shù)功能: PID參數(shù)初始化
  197.   * 輸入?yún)?shù): 無
  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; // 比例常數(shù) Proportional Const
  206.     sPID.Integral = SPD_I_DATA;   // 積分常數(shù)  Integral Const
  207.     sPID.Derivative = SPD_D_DATA; // 微分常數(shù) Derivative Const
  208.     sPID.SetPoint = TARGET_LOC;     // 設定目標Desired Value
  209. }
  210. /**
  211.   * 函數(shù)名稱:位置閉環(huán)PID控制設計
  212.   * 輸入?yún)?shù):當前控制量
  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.   /* 限定積分區(qū)域 */
  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 硬石嵌入式開發(fā)團隊 *****END OF FILE****/
復制代碼
0.png

所有資料51hei提供下載:
YSF4_HAL_MOTOR-011. 直流有刷電機_位置閉環(huán)控制_位置式PID.7z (3.83 MB, 下載次數(shù): 267)


評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:309613 發(fā)表于 2019-4-11 10:42 | 顯示全部樓層
謝謝樓主分享!
回復

使用道具 舉報

ID:483754 發(fā)表于 2019-6-3 11:06 | 顯示全部樓層
講的很好
回復

使用道具 舉報

ID:59224 發(fā)表于 2019-7-26 21:47 | 顯示全部樓層
感謝樓主的貢獻
回復

使用道具 舉報

ID:631267 發(fā)表于 2019-10-28 10:46 | 顯示全部樓層
找了好久,謝謝。。。
回復

使用道具 舉報

ID:785535 發(fā)表于 2020-6-21 08:18 | 顯示全部樓層
the brush DC motor is nice
回復

使用道具 舉報

ID:258522 發(fā)表于 2021-7-27 10:27 | 顯示全部樓層
學習一下,有沒有庫函數(shù)的例程
回復

使用道具 舉報

ID:228452 發(fā)表于 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
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表