久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 10574|回復(fù): 10
收起左側(cè)

STM32步進(jìn)電機(jī)PID速度環(huán)控速源碼

  [復(fù)制鏈接]
ID:364498 發(fā)表于 2018-11-9 15:21 | 顯示全部樓層 |閱讀模式
【1】例程簡(jiǎn)介
  使用定時(shí)器功能輸出PWM信號(hào)到步進(jìn)電機(jī)驅(qū)動(dòng)器,使其驅(qū)動(dòng)步進(jìn)電機(jī)轉(zhuǎn)動(dòng)。
  編碼器用于電機(jī)測(cè)速。在電機(jī)轉(zhuǎn)動(dòng)一圈時(shí)編碼器可以輸出固定的脈沖數(shù),通過讀取編碼器
脈沖可以獲取當(dāng)前電機(jī)轉(zhuǎn)動(dòng)狀態(tài)。
一般處理編碼器脈沖有兩種方法:
1. T法:計(jì)算一定量的脈沖數(shù)所用的時(shí)間
2. M法:計(jì)算一段固定時(shí)間內(nèi)所捕獲的脈沖數(shù)。
  根據(jù)當(dāng)前速度和目標(biāo)速度之間的誤差,使用PID計(jì)算定時(shí)器輸出的脈沖頻率,使得滑臺(tái)能夠以目標(biāo)速度
運(yùn)動(dòng)

【2】跳線帽情況
編碼器              A相  --> PC6
                B相  --> PC7
               
步進(jìn)電機(jī)驅(qū)動(dòng)器    DIR- --> PB13
                ENA- --> PB14
                PUL- --> PA8
                DIR+ --> +5V
                ENA+ --> +5V
                PUL+ --> +5V
  
【3】操作及現(xiàn)象
  根據(jù)引腳定義方法連接開發(fā)板和步進(jìn)電機(jī)驅(qū)動(dòng)器和編碼器,另外步進(jìn)電機(jī)
連接自行根據(jù)電機(jī)和驅(qū)動(dòng)器標(biāo)識(shí)連接,驅(qū)動(dòng)器需要一個(gè)24V的直流電源供電。
接線時(shí)注意開發(fā)板與驅(qū)動(dòng)器“共地”連接。編碼器的AB相輸出都是開漏輸出,
所以需要使用加上拉電阻才能連接,使用開發(fā)板配套的MINI USB線連接到開發(fā)
板標(biāo)示“調(diào)試串口”字樣的MIMI USB接口為開發(fā)板提供電源。下載完程序之后
,開發(fā)板持續(xù)PWM脈沖給步進(jìn)電機(jī)驅(qū)動(dòng)器,電機(jī)以目標(biāo)速度持續(xù)轉(zhuǎn)動(dòng),同時(shí)在
串口助手上每秒顯示一次當(dāng)前位置,速度,捕獲值等信息.

單片機(jī)源程序如下:
  1. /**
  2.   ******************************************************************************
  3.   * 文件名程: main.c
  4.   * 作    者: 硬石嵌入式開發(fā)團(tuán)隊(duì)
  5.   * 版    本: V1.1
  6.   * 功    能: 基于PID速度環(huán)的步進(jìn)電機(jī)速度調(diào)節(jié)
  7.   ******************************************************************************
  8.   * 說明:
  9.   * 本例程配套硬石stm32開發(fā)板YS-F1Pro使用。
  10.   *

  11.   ******************************************************************************
  12.   */
  13. /* 包含頭文件 ----------------------------------------------------------------*/
  14. #include "stm32f1xx_hal.h"
  15. #include "StepMotor/bsp_STEPMOTOR.h"
  16. #include "usart/bsp_debug_usart.h"
  17. #include "EncoderTIM/bsp_EncoderTIM.h"
  18. #include  <stdlib.h>
  19. #include  <string.h>
  20. /* 私有類型定義 --------------------------------------------------------------*/
  21. typedef struct
  22. {
  23.   __IO float SetPoint;    // 目標(biāo)值  單位:mm/s
  24.   __IO int LastError;     // 前一次誤差   
  25.   __IO int PrevError;     // 前兩次誤差
  26.   __IO long SumError;     // 累計(jì)誤差
  27.   __IO double Proportion; // Kp系數(shù)
  28.   __IO double Integral;   // Ki系數(shù)
  29.   __IO double Derivative; // Kd系數(shù)
  30. }PID;
  31. /* 私有宏定義 ----------------------------------------------------------------*/
  32. #define TXDCYCLE                  1000    // 數(shù)據(jù)發(fā)送周期;單位:ms
  33. #define SAMPLING                  0x01    // 采樣標(biāo)記
  34. #define TXD                       0x02    // 發(fā)送數(shù)據(jù)標(biāo)記

  35. #define abs(x)    ((x)<0?(-x):(x))
  36. #define SENDBUFF_SIZE              100    // 串口DMA發(fā)送緩沖區(qū)大小

  37. /* 私有變量 ------------------------------------------------------------------*/
  38. __IO static PID vPID;

  39. __IO uint16_t time_count = 0;              // 時(shí)間計(jì)數(shù),每1ms增加一(與滴答定時(shí)器頻率有關(guān))
  40. __IO uint8_t Time_Flag   = 0;              // 任務(wù)時(shí)間標(biāo)記

  41. /* 擴(kuò)展變量 ------------------------------------------------------------------*/
  42. extern int16_t OverflowCount;              //編碼器計(jì)數(shù)溢出 計(jì)數(shù)器
  43. /* 私有函數(shù)原形 --------------------------------------------------------------*/

  44. /* 函數(shù)體 --------------------------------------------------------------------*/
  45. /**
  46.   * 函數(shù)功能:增量式PID速度環(huán)計(jì)算
  47.   * 輸入?yún)?shù):NextPoint     由編碼器得到的速度值
  48.   *           TargetVal    目標(biāo)值
  49.   * 返 回 值:經(jīng)過PID運(yùn)算得到的增量值
  50.   * 說    明:增量式 PID 速度環(huán)控制設(shè)計(jì),計(jì)算得到的結(jié)果仍然是速度值
  51.   */
  52. float IncPIDCalc(int NextPoint,float TargetVal)       //臨時(shí)變量,期望值
  53. {
  54.   float iError = 0,iIncpid = 0;                       //當(dāng)前誤差
  55.   iError = TargetVal - NextPoint;                     // 增量計(jì)算
  56.   if((iError<0.5)&&(iError>-0.5))
  57.     iError = 0;                                       // |e| < 0.5,不做調(diào)整
  58.   iIncpid=(vPID.Proportion * iError)                  // E[k]項(xiàng)
  59.               -(vPID.Integral * vPID.LastError)       // E[k-1]項(xiàng)
  60.               +(vPID.Derivative * vPID.PrevError);    // E[k-2]項(xiàng)
  61.   
  62.   vPID.PrevError=vPID.LastError;                      // 存儲(chǔ)誤差,用于下次計(jì)算
  63.   vPID.LastError = iError;
  64.   return(iIncpid);                                    // 返回增量值
  65. }

  66. /**
  67.   * 函數(shù)功能: 系統(tǒng)時(shí)鐘配置
  68.   * 輸入?yún)?shù): 無
  69.   * 返 回 值: 無
  70.   * 說    明: 無
  71.   */
  72. void SystemClock_Config(void)
  73. {
  74.   RCC_OscInitTypeDef RCC_OscInitStruct;
  75.   RCC_ClkInitTypeDef RCC_ClkInitStruct;

  76.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;  // 外部晶振,8MHz
  77.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  78.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  79.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  80.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  81.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;  // 9倍頻,得到72MHz主時(shí)鐘
  82.   HAL_RCC_OscConfig(&RCC_OscInitStruct);

  83.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  84.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  85.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;       // 系統(tǒng)時(shí)鐘:72MHz
  86.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;              // AHB時(shí)鐘:72MHz
  87.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;               // APB1時(shí)鐘:36MHz
  88.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;               // APB2時(shí)鐘:72MHz
  89.   HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);

  90.          // HAL_RCC_GetHCLKFreq()/1000    1ms中斷一次
  91.         // HAL_RCC_GetHCLKFreq()/100000         10us中斷一次
  92.         // HAL_RCC_GetHCLKFreq()/1000000 1us中斷一次
  93.   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);  // 配置并啟動(dòng)系統(tǒng)滴答定時(shí)器
  94.   /* 系統(tǒng)滴答定時(shí)器時(shí)鐘源 */
  95.   HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  96.   /* 系統(tǒng)滴答定時(shí)器中斷優(yōu)先級(jí)配置 */
  97.   HAL_NVIC_SetPriority(SysTick_IRQn, 1, 0);
  98. }

  99. /**
  100.   * 函數(shù)功能: PID結(jié)構(gòu)體初始化
  101.   * 輸入?yún)?shù): 無
  102.   * 返 回 值: 無
  103.   * 說    明: 初始化PID參數(shù)
  104.   */
  105. void Init_PID()
  106. {
  107.   vPID.SetPoint   = 5;       // 目標(biāo)值  單位:mm/s
  108.   vPID.Proportion = 0.11;    // Kp系數(shù)
  109.   vPID.Derivative = 0.03;    // Ki系數(shù)
  110.   vPID.Integral   = 0.12;    // Kd系數(shù)
  111.   vPID.LastError  = 0;
  112.   vPID.PrevError  = 0;
  113.   vPID.SumError   = 0;
  114. }
  115. /**
  116.   * 函數(shù)功能: 主函數(shù).
  117.   * 輸入?yún)?shù): 無
  118.   * 返 回 值: 無
  119.   * 說    明: 無
  120.   */
  121. int main(void)
  122. {
  123.   static float Exp_Val = 0;           // PID計(jì)算出來的期望值
  124.   float Vel_Target;                   // 速度目標(biāo)值
  125.   uint16_t SUM_Pulse = 0;             // 1秒內(nèi)的總脈沖
  126.   int16_t MSF = 0;                    // 電機(jī)反饋速度
  127.   __IO int32_t CaptureNumber=0;       // 輸入捕獲數(shù)
  128.   __IO int32_t Last_CaptureNumber=0;  // 上一次捕獲值
  129.   uint8_t aTxBuffer[SENDBUFF_SIZE];   // 串口DMA發(fā)送緩沖區(qū)
  130.   /* 復(fù)位所有外設(shè),初始化Flash接口和系統(tǒng)滴答定時(shí)器 */
  131.   HAL_Init();
  132.   /* 配置系統(tǒng)時(shí)鐘 */
  133.   SystemClock_Config();
  134.   Init_PID();
  135.   /* 調(diào)試串口初始化 */
  136.   MX_DEBUG_USART_Init();

  137.   /* 編碼器定時(shí)器初始化并配置輸入捕獲功能 */
  138.   ENCODER_TIMx_Init();
  139.   /* 啟動(dòng)編碼器接口 */
  140.   HAL_TIM_Encoder_Start(&htimx_Encoder, TIM_CHANNEL_ALL);
  141.   
  142.   HAL_Delay(10);
  143.   /* 步進(jìn)電機(jī)定時(shí)器初始化*/
  144.   STEPMOTOR_TIMx_Init();
  145.   /* 首先禁止步進(jìn)電機(jī)動(dòng)作*/
  146.   STEPMOTOR_OUTPUT_DISABLE();
  147.   /* 啟動(dòng)定時(shí)器 */
  148.   HAL_TIM_Base_Start(&htimx_STEPMOTOR);
  149.   /* 啟動(dòng)比較輸出并使能中斷 */
  150.   HAL_TIM_OC_Start_IT(&htimx_STEPMOTOR,TIM_CHANNEL_1);
  151.   
  152.   /* 目標(biāo)值單位為:mm/s,這里需要轉(zhuǎn)換為頻率
  153.      f = v*PPM;
  154.      PPM是每mm的編碼器脈沖數(shù),得到的F就是每秒的脈沖數(shù) (Pulse/s,也就是頻率:Hz)
  155.      Vel_Target = f/(1000/20);得到每個(gè)采樣周期(20ms)的脈沖數(shù)(Pulse/ms)
  156.    */
  157.   Vel_Target = (vPID.SetPoint*P_PERIOD);//每單位采樣周期內(nèi)的脈沖數(shù)(頻率)
  158.   
  159.   /* 無限循環(huán) */
  160.   while (1)
  161.   {
  162.    
  163.     //采樣和控制周期為20ms
  164.     if(Time_Flag & SAMPLING)
  165.     {
  166.       //獲得編碼器的脈沖值
  167.       CaptureNumber = OverflowCount*65535 + __HAL_TIM_GET_COUNTER(&htimx_Encoder);

  168.       //M法 測(cè)速度
  169.       MSF = CaptureNumber  - Last_CaptureNumber;
  170.       Last_CaptureNumber = CaptureNumber;
  171.       MSF = abs(MSF);
  172.       //對(duì)速度進(jìn)行累計(jì),得到1s內(nèi)的脈沖數(shù)
  173.       SUM_Pulse += MSF;
  174.       Exp_Val += IncPIDCalc(MSF,Vel_Target);
  175.       Exp_Val = abs(Exp_Val);
  176.       /* 經(jīng)過PID計(jì)算得到的結(jié)果是編碼器的輸出期望值的增量,
  177.          需要轉(zhuǎn)換為步進(jìn)電機(jī)的控制量(頻率值),這里乘上一個(gè)系數(shù)6400/2400
  178.       */
  179.       STEPMOTOR_Motion_Ctrl(CW,Exp_Val*FEEDBACK_CONST);//乘上一個(gè)系數(shù),6400/2400,將PID計(jì)算結(jié)果轉(zhuǎn)換為步進(jìn)電機(jī)的頻率(速度)
  180.       Time_Flag &= ~SAMPLING;
  181.     }
  182.     //數(shù)據(jù)發(fā)送周期為1s
  183.     if(Time_Flag & TXD)
  184.     {
  185.       sprintf(aTxBuffer,"捕獲值:%d--速度:%.1f mm/s\n",CaptureNumber,(float)SUM_Pulse*MPP);
  186.       sprintf(aTxBuffer+strlen((const char*)aTxBuffer),"1s內(nèi)編碼器計(jì)數(shù)值:%d\n",SUM_Pulse);
  187.       HAL_UART_Transmit_DMA(&husart_debug, aTxBuffer, strlen((const char*)aTxBuffer));
  188.       SUM_Pulse = 0;
  189.       Time_Flag &= ~TXD;
  190.     }
  191.   }
  192. }

  193. /**
  194.   * 函數(shù)功能: 系統(tǒng)滴答定時(shí)器中斷回調(diào)函數(shù)
  195.   * 輸入?yún)?shù): 無
  196.   * 返 回 值: 無
  197.   * 說    明: 每發(fā)生一次滴答定時(shí)器中斷進(jìn)入該回調(diào)函數(shù)一次
  198.   */
  199. void HAL_SYSTICK_Callback(void)
  200. {
  201.   // 每1ms自動(dòng)增一
  202.   time_count++;         
  203.   if(time_count%(SAMPLING_PERIOD) == 0) // 20ms
  204.   {
  205.     Time_Flag |= SAMPLING;
  206.   }
  207.   if(time_count >= TXDCYCLE)            // 1s
  208.   {
  209.     Time_Flag |= TXD;
  210.     time_count = 0;
  211.   }
  212. }


  213. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式開發(fā)團(tuán)隊(duì) *****END OF FILE****/
復(fù)制代碼

所有資料51hei提供下載:
YSF1_HAL_MOTOR-018. 步進(jìn)電機(jī)速度環(huán)控速.rar (3.23 MB, 下載次數(shù): 304)


回復(fù)

使用道具 舉報(bào)

ID:1 發(fā)表于 2018-11-11 01:47 | 顯示全部樓層
好資料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報(bào)

ID:307544 發(fā)表于 2018-11-11 10:14 | 顯示全部樓層
資料不錯(cuò),程序注釋也比較詳細(xì),看起來就不那么累了
回復(fù)

使用道具 舉報(bào)

ID:521835 發(fā)表于 2019-4-25 22:36 | 顯示全部樓層
感謝樓主分享
回復(fù)

使用道具 舉報(bào)

ID:782879 發(fā)表于 2020-6-18 10:16 | 顯示全部樓層
好資料,感謝分享
回復(fù)

使用道具 舉報(bào)

ID:469171 發(fā)表于 2020-6-23 12:00 | 顯示全部樓層
感謝樓主分享
回復(fù)

使用道具 舉報(bào)

ID:774108 發(fā)表于 2020-7-3 10:01 來自觸屏版 | 顯示全部樓層
有原理圖嗎
回復(fù)

使用道具 舉報(bào)

ID:856091 發(fā)表于 2020-12-7 16:05 | 顯示全部樓層
有集成加減速的嗎,加上加減速的PID閉環(huán)怎么做
回復(fù)

使用道具 舉報(bào)

ID:793041 發(fā)表于 2020-12-7 16:20 | 顯示全部樓層
好用。。。。。。
回復(fù)

使用道具 舉報(bào)

ID:620239 發(fā)表于 2021-1-20 13:43 | 顯示全部樓層
這編碼器和步進(jìn)電機(jī)是怎樣連的?
回復(fù)

使用道具 舉報(bào)

ID:879809 發(fā)表于 2021-1-22 20:22 | 顯示全部樓層
嘉哥呀 發(fā)表于 2021-1-20 13:43
這編碼器和步進(jìn)電機(jī)是怎樣連的?

安裝到同一根主軸即可。但是樓主思路有問題,步進(jìn)電機(jī)用于廉價(jià)低生產(chǎn)率場(chǎng)合,配編碼器太貴而且無法明顯提高性能,唯一優(yōu)點(diǎn)是丟步會(huì)馬上發(fā)現(xiàn)。真的不差錢的高效率生產(chǎn)場(chǎng)合,是要用伺服電機(jī)+編碼器的。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 黄色片在线| 男人影院在线观看 | 在线伊人| 福利片在线| 91精品国产综合久久久久久 | 日本精品视频 | 久久综合久 | 亚洲欧美日韩综合 | 丁香九月婷婷 | 亚洲免费婷婷 | 亚洲一区二区在线播放 | 国产九九精品 | 亚洲一区二区在线 | 亚洲免费av在线 | 成人爽a毛片一区二区免费 亚洲午夜在线观看 | www.毛片.com | 黄色高清网站 | 国产精品成人一区 | 日韩精品免费在线观看 | 精品亚洲国产成人av制服丝袜 | 成人三级小说 | 久久久久国产一区二区三区 | 日韩精品一区二区三区四区 | 色窝 | 欧美日韩一区二 | 欧美精品网 | 久久久天堂国产精品女人 | 国内精品一区二区三区 | 四虎影院在线 | av色| 91欧美激情一区二区三区成人 | 69久久久 | 亚洲视频一区二区三区 | 亚洲最新视频 | 国产一级片免费 | 免费欧美视频 | 久久久香蕉 | 永久免费看片在线播放 | 在线观看av网站 | 久草视频免费看 | 国产成人在线播放 |