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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10484|回復: 10
打印 上一主題 下一主題
收起左側

STM32步進伺服電機梯形加速源程序 單軸簡易運動控制器

  [復制鏈接]
跳轉到指定樓層
樓主
ID:82014 發表于 2018-4-26 12:32 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
步進電機梯形加速程序

單片機源程序如下:
  1. /*基于STM32的單軸簡易運動控制器/脈沖發生器*/
  2. /*脈沖+方向控制步進伺服電機*/
  3. /*
  4. 優化記錄:
  5. 增加急停GPIOC.0、正向極限GPIOC.1、負向極限GPIOC.2等輸入IO接點

  6. 中斷修改TIMx_PSC一個寄存器的值,而不是修改TIMx_ARR預加載寄存器+TIMx_CCRx比較值寄存器兩個值,縮短中斷處理時間

  7. 定位指令DRVI/DRVA中,目標頻率設定過高、而實際輸出脈沖數過少時,則不必加速到目標頻率即進入減速區
  8. */

  9. /*
  10. DRVI(A);相對定位,輸出A(A取絕對值)個脈沖
  11. A不能為0
  12. 若A為正數,則方向為正、GPIOB.0為高電平
  13. 若A為負數,則方向為負、GPIOB.0為低電平

  14. DRVA(A)  絕對定位,輸出脈沖,運行至A個脈沖的位置
  15. 若目標位置A等于當前位置D,則不執行脈沖輸出
  16. 若A大于D 則方向為正GPIOB.5為高電平
  17. 若A小于D 則方向為負GPIOB.5為低電平

  18. GPIOB.1為脈沖輸出
  19. GPIOB.0為方向輸出
  20. 占空比為50%
  21. GPIOC.0急停
  22. GPIOC.1正向極限
  23. GPIOC.2反向極限
  24. GPIOC.3
  25. GPIOC.4
  26. GPIOC.5
  27. GPIOC.6
  28. GPIOC.7啟動
  29. 階梯曲線形式加減速
  30. 加減速時間以10毫秒為基本單位
  31. 加減速以每10毫秒為一級
  32. 例如
  33. 加減速時間為50毫秒,則加減速級數為50/10=5
  34. 加減速時間為100毫秒,則加減速級數為100/10=10
  35. 加減速時間為150毫秒,則加減速級數為150/10=15
  36. */

  37. #include "sys.h"  
  38. #include "delay.h"

  39. #define  MasterFrequency  0x100000//最高頻率限制100K

  40. long Current;                        //當前位置脈沖數
  41. long Target;                        //目標位置脈沖數
  42. long StartSave;                        //定位指令剛開始啟動時的當前值
  43. long DownStartSave;                //開始進入減速時的當前值


  44. typedef enum
  45. {
  46.         OFF = 0,
  47.         ON = 1,
  48. }STATUS_Type;


  49. typedef enum
  50. {
  51.         us=1,
  52.         ms=1000,
  53.         sce=1000000,
  54. }DELAY_Type;


  55. STATUS_Type RunFlag;        //定位指令脈沖輸出執行標志
  56. STATUS_Type StopCommand;//定位指令脈沖輸出停止命令標志
  57. STATUS_Type PlusMinus;        //正負方向標志


  58. u32 StartFreq;                        //啟動頻率
  59. u32 TargetFreq;                        //目標頻率
  60. u32 UDTimer=1000;                        //加減速時間

  61. u32 LadderFreq[102];
  62. u16 LadderPSC[202];                //加減速0至9級速度/頻率預分頻值
  63. u16 LadderNum;                        //加減速速度級數
  64. u16 LadderOrderNum;                //加減速速度編號
  65. long LadderTarget[202];        //各速度等級目標值
  66. int m;

  67. void MyTimer3_Init()//定時器3初始化
  68. {
  69.                 RCC->APB2ENR|=(1<<3)|(1<<0);   //使能AFIO、GPIOB時鐘
  70.                 GPIOB->CRL&=0xffffff00;  //PB5
  71.                 GPIOB->CRL|=0x000000a2;        //配置PORTB.1為復用推挽輸出、配置PORTB.0為推挽輸出,輸出最大頻率2MHz   00B000a2
  72.                 GPIOB->BRR=1<<0;
  73.                
  74.                 RCC->APB1ENR|=1<<1;           //使能定時器TIMER3時鐘
  75.                 TIM3->CR1|=1<<2;                                   //設置只有計數溢出作為T3更新中斷
  76.                 TIM3->DIER|=1<<0;                           //允許定時器3計數溢出中斷

  77.                 MY_NVIC_Init(1,3,TIM3_IRQn,2);
  78.                 TIM3->CCMR2&=~(3<<8);               //T3_CH4通道配置為輸出模式
  79.                 TIM3->CCMR2|=7<<12;                 //T3_CH4為PWM模式2
  80.                 TIM3->CCER|=1<<12;                  //T3_CH4通道輸出使能               
  81.                 TIM3->PSC=71;                  
  82. }


  83. void Pluse_start()
  84. {
  85.           
  86.                 RunFlag=ON;                             //脈沖輸出定位指令執行標志置ON
  87.                 StartSave=Current;
  88.                 LadderOrderNum=0;//加減速級數序號為0       
  89.                 TIM3->ARR=LadderPSC[0];
  90.     TIM3->CCR4=TIM3->ARR>>1;   //匹配值1等于重裝值一半,是以占空比為50%
  91.            //delay_ms(2);                       //脈沖信號比方向信號滯后,以提高可靠性
  92.        
  93.                 TIM3->CR1|=1<<0;              //啟動定時器TIMER2計數
  94. }

  95. /*********************************************************************************
  96. 函數名稱:DRVI
  97. 函數功能:相對定位
  98. 入口參數:long offset相對偏移脈沖,u32 frequency最高頻率
  99. 返回值:無
  100. *********************************************************************************/
  101. void DRVI(long offset,u32 frequency)
  102. {
  103.         u16 h;
  104.         u16 i;
  105.         u32 j;
  106.         if((offset!=0)&&(RunFlag==OFF)&&((GPIOC->IDR&0x01)==0))//相對偏移值為0則不接受命令,脈沖輸出已執行,不接受命令
  107.         {       
  108.                 Target=Current+offset;     //目標值等于當前值加上相對偏移值
  109.                
  110.                 if(frequency<StartFreq)    //如果設定目標頻率小于啟動頻率
  111.                 {
  112.                         frequency=StartFreq;
  113.                 }
  114.                 else if(frequency>MasterFrequency)//否則如果設定目標頻率高于最高限制頻率
  115.                 {
  116.                         frequency=MasterFrequency;
  117.                 }
  118.                
  119.                 LadderNum=UDTimer/10;//加減速級數
  120.                 j=(frequency-StartFreq)/LadderNum;//等差
  121.                 for(i=0;i<LadderNum;i++)
  122.                 {
  123.                         LadderFreq[i]=i*j+StartFreq;//加減速各階梯頻率
  124.                         LadderPSC[i]=(6000000/LadderFreq[i])-1;//加減速各階梯頻率對應定時器預分頻值
  125.                 }
  126.                 LadderFreq[LadderNum]=frequency;//目標頻率,最高頻率
  127.                 LadderPSC[LadderNum]=6000000/frequency-1;//目標頻率(最高頻率)對應定時器預分頻值
  128.                                
  129.                 if(offset>0)//相對偏移值為正數
  130.                 {
  131.                         GPIOB->BSRR=1<<0;//相對偏移值為正數,方向為正,方向信號高電平
  132.                         PlusMinus=ON;//正負方向標志置ON
  133.                        
  134.                         LadderTarget[0]=Current+StartFreq/100;//加速第一段目標脈沖值
  135.                         for(i=1;i<LadderNum;i++)
  136.                         {
  137.                                 LadderTarget[i]=LadderTarget[i-1]+LadderFreq[i]/100;//加速各段目標脈沖值
  138.                         }       
  139.                        
  140.                         while(offset<=((LadderTarget[LadderNum-1]-Current)<<1))//如果偏移量小于二倍加速增量
  141.                         {
  142.                                 LadderNum--;//加速等級數減一  頻率設定過高、實際輸出脈沖數過少的情況下不必加速至設定頻率,避免過沖
  143.                         }
  144.                        
  145.                         for(i=0,h=LadderNum<<1;  i<LadderNum;  i++,h--)
  146.                         {
  147.                                 LadderPSC[h]=LadderPSC[i];//減速各段定時器重裝值
  148.                         }
  149.                        
  150.                         LadderTarget[LadderNum<<1]=Target;//減速最后一段目標脈沖值
  151.                         for(i=(LadderNum<<1)-1,h=0;i>LadderNum;i--,h++)
  152.                         {
  153.                                 LadderTarget[i]=LadderTarget[i+1]-LadderFreq[h]/100;//減速各段目標脈沖值
  154.                         }
  155.                 }
  156.                 else//否則相對偏移值為負數                                             
  157.                 {
  158.                         GPIOB->BRR=1<<0;//相對偏移值為負數,方向為負,方向信號低電平
  159.                         PlusMinus=OFF;//正負方向標志OFF
  160.                        
  161.                         LadderTarget[0]=Current-StartFreq/100;//加速第一段目標脈沖值
  162.                         for(i=1;i<LadderNum;i++)
  163.                         {
  164.                                 LadderTarget[i]=LadderTarget[i-1]-LadderFreq[i]/100;//加速各段目標脈沖值
  165.                         }
  166.                        
  167.                         while(offset>=((LadderTarget[LadderNum-1]-Current)<<1))//如果偏移量小于二倍加速增量
  168.                         {
  169.                                 LadderNum--;//加速等級數減一  頻率設定過高、實際輸出脈沖數過少的情況下不必加速至設定頻率,避免過沖
  170.                         }
  171.                        
  172.                         for(i=0,h=LadderNum<<1;  i<LadderNum;  i++,h--)
  173.                         {
  174.                                 LadderPSC[h]=LadderPSC[i];
  175.                         }
  176.                        
  177.                         LadderTarget[LadderNum<<1]=Target;//減速最后一段目標脈沖值
  178.                         for(i=(LadderNum<<1)-1,h=0;i>LadderNum;i--,h++)
  179.                         {
  180.                                 LadderTarget[i]=LadderTarget[i+1]+LadderFreq[h]/100;//減速各段目標脈沖值
  181.                         }
  182.                 }
  183.                 LadderTarget[LadderNum]=Target + Current - LadderTarget[LadderNum-1];
  184.                 Pluse_start();//脈沖輸出正式啟動
  185.         }
  186. }

  187. /*********************************************************************************
  188. 函數名稱:DRVA
  189. 函數功能:絕對定位
  190. 入口參數:long target目標位置脈沖,u32 frequency最高頻率
  191. 返回值:無
  192. *********************************************************************************/
  193. void DRVA(long target,u32 frequency)//3200  2khz
  194. {
  195.         u16 h;
  196.         u16 i;
  197.         u32 j;
  198.         long offset=target-Current;//
  199.         if((offset!=0)&&(RunFlag==OFF)&&((GPIOC->IDR&0x01)==0))    //目標位置等于當前位置,則不接受命令  
  200.         {                       
  201. ///////////////////////////////////////////////////////////////////////////////////////////////////////               
  202.                 Target=target;                 //目標位置設定(等于參數)
  203.                
  204.                 if(frequency<StartFreq)        //如果設定目標頻率小于啟動頻率
  205.                 {
  206.                         frequency=StartFreq;
  207.                 }
  208.                 else if(frequency>MasterFrequency)//否則如果設定目標頻率高于最高限制頻率
  209.                 {
  210.                         frequency=MasterFrequency;
  211.                 }
  212.                 LadderNum=UDTimer/10;//加減速級數 分成100級
  213.                 j=(frequency-StartFreq)/LadderNum;//等差 每個階段所加的頻率數
  214.        
  215.                 for(i=0;i<LadderNum;i++)         //獲取每個階段的速度值
  216.                 {
  217.                         LadderFreq[i]=i*j+StartFreq;//加減速各階梯頻率 每個階段的速度 等級到J
  218.                         LadderPSC[i]=(1000000/LadderFreq[i])-1;//加減速各階梯頻率對應定時器初值
  219.                 }
  220.                
  221.                 LadderFreq[LadderNum]=frequency;
  222.                 LadderPSC[LadderNum]=1000000/frequency-1;//  
  223. /////////////////////////////////////////////////////////////////////////////////////////////////////       
  224.            if(offset>0)//目標位置值大于當前位置值  
  225.                  {
  226.                         GPIOB->BSRR=1<<0;//則方向為正,方向信號高電平
  227.                         PlusMinus=ON;//正負方向標志置ON
  228.                        
  229.                         LadderTarget[0]=Current+StartFreq/100;
  230.                         for(i=1;i<LadderNum;i++)
  231.                         {
  232.                                 LadderTarget[i]=LadderTarget[i-1]+LadderFreq[i]/100;
  233.                         }       
  234.                        
  235.                         while(offset<=((LadderTarget[LadderNum-1]-Current)<<1))//如果偏移量小于二倍加速增量
  236.                         {
  237.                                 LadderNum--;//加速等級數減一  頻率設定過高、實際輸出脈沖數過少的情況下不必加速至設定頻率,避免過沖
  238.                         }
  239.                        
  240.                         for(i=0,h=LadderNum<<1;  i<LadderNum;  i++,h--)
  241.                         {
  242.                                 LadderPSC[h]=LadderPSC[i];
  243.                         }
  244.                        
  245.                         LadderTarget[LadderNum<<1]=Target;//減速最后一段目標脈沖值
  246.                         for(i=(LadderNum<<1)-1,h=0;i>LadderNum;i--,h++)
  247.                         {
  248.                                 LadderTarget[i]=LadderTarget[i+1]-LadderFreq[h]/100;//減速各段目標脈沖值
  249.                         }
  250.      }
  251.                 else//否則目標位置值小于當前位置值,                                                          
  252.                 {
  253.                         GPIOB->BRR=1<<0;//則方向為負,方向信號低電平       
  254.                         PlusMinus=OFF;//正負方向標志OFF
  255.                        
  256.                         LadderTarget[0]=Current-StartFreq/100;
  257.                         for(i=1;i<LadderNum;i++)
  258.                         {
  259.                                 LadderTarget[i]=LadderTarget[i-1]-LadderFreq[i]/100;
  260.                         }
  261.                        
  262.                         while(offset>=((LadderTarget[LadderNum-1]-Current)<<1))//如果偏移量小于二倍加速增量
  263.                         {
  264.                                 LadderNum--;//加速等級數減一  頻率設定過高、實際輸出脈沖數過少的情況下不必加速至設定頻率,避免過沖
  265.                         }               
  266.                         for(i=0,h=LadderNum<<1;  i<LadderNum;  i++,h--)
  267.                         {
  268.                                 LadderPSC[h]=LadderPSC[i];
  269.                         }               
  270.                         LadderTarget[LadderNum<<1]=Target;//減速最后一段目標脈沖值
  271.                         for(i=(LadderNum<<1)-1,h=0;          i>LadderNum;   i--,h++)
  272.                         {
  273.                                 LadderTarget[i]=LadderTarget[i+1]+LadderFreq[h]/100;//減速各段目標脈沖值
  274.                         }
  275.                 }
  276.                 LadderTarget[LadderNum]=Target + Current - LadderTarget[LadderNum-1];//勻速段目標位置/進入減速時位置        數組元素60
  277.                 Pluse_start();//脈沖輸出正式啟動
  278.         }
  279. }

  280. /*********************************************************************************
  281. 函數名稱:SLOPE
  282. 函數功能:斜坡設置(坡度斜率設置)  限定啟動頻率在100---1000之間 限制時間在50---1000
  283. 入口參數:u32 frequency啟動頻率,u32 timer加減速時間
  284. 返回值:無
  285. *********************************************************************************/
  286. void SLOPE(u32 frequency,u32 timer)//200hz 600
  287. {
  288.         if(frequency<100)               
  289.         {
  290.                 StartFreq=100;
  291.         }
  292.         else if(frequency>1000)
  293.                                 {
  294.                                         StartFreq=1000;
  295.                                 }
  296.                                 else                                       
  297.                                 {
  298.                                         StartFreq=frequency;
  299.                                 }//啟動頻率設置大于等于100小于等于1000
  300.        
  301.         if(timer<50)               
  302.         {
  303.                 UDTimer=50;
  304.         }
  305.         else if(timer>1000)       
  306.                         {
  307.                                 UDTimer=1000;
  308.                         }
  309.                         else                               
  310.                         {               
  311.                                 UDTimer=(timer/10)*10; //取整數
  312.                         }//加減速時間設置 大于等于50小于等于1000,且為整十數
  313. }

  314. void TIM3_IRQHandler()      //定時器3全局中斷函數
  315. {
  316.         long temp;
  317.         if(TIM3->SR&0x0001)
  318.         {
  319.                 if(PlusMinus==ON)  
  320.                 {
  321.                         temp=Current;
  322.                //如果方向為正,當前值加一  
  323.                         temp++;
  324.                         Current=temp;
  325.                 }
  326.                 else   
  327.                 {
  328.                         temp=Current;
  329.                         temp--;       //否則方向為負,當前值減一
  330.                         Current=temp;
  331.                 }
  332.                

  333.                 if(Current==LadderTarget[LadderOrderNum])
  334.                 {
  335.                         if(LadderOrderNum< (LadderNum<<1))
  336.                         {
  337.                                 LadderOrderNum++;
  338.                                 TIM3->PSC=LadderPSC[LadderOrderNum];
  339.                         }
  340.                         else
  341.                         {
  342.                                 TIM3->CR1&=~(1<<0);          
  343.                                 TIM3->CNT=0x0000;
  344.                                
  345.                                 RunFlag=OFF;         
  346.                         }
  347.                 }                               
  348.                
  349.                 TIM3->SR=0x0000;
  350.         }
  351. }
  352. void Variable_Init()
  353. {
  354.         Target=0;//目標位置脈沖值
  355.         Current=0;//當前位置脈沖值
  356.         RunFlag=OFF;//脈沖定位指令執行標志
  357.         StopCommand=OFF;//定位指令脈沖輸出停止命令標志
  358. }
  359. void PAUSE()
  360. {
  361.         while(RunFlag==ON);       
  362. }


  363. int main(void)
  364. {
  365. //        Stm32_Clock_Init(9);
  366.         //delay_init(72);
  367.         MyTimer3_Init();        //定時器2初始化
  368.         Variable_Init();        //變量初始化
  369.         SLOPE(200,600);                //啟動頻率200Hz,加減速時間600毫秒 斜率設置
  370.         DRVA(1200,4000);       
  371.         while(1)
  372.         {
  373.                             //以2KHz頻率前進3200脈沖當量距離
  374. //                                //PAUSE();                                //等待脈沖輸出執行完畢
  375. //                                delay_ms(500);                                                                       
  376. //                          DRVA(0,20000);                //以2KHz頻率前進3200脈沖當量距離
  377. //                          PAUSE();                                //等待脈沖輸出執行完畢
  378. //                          delay_ms(500);       
  379.   }
  380. }
復制代碼

所有資料51hei提供下載:
步進電機寄存器版本.zip (698.35 KB, 下載次數: 187)


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏12 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:445569 發表于 2019-2-2 11:08 | 只看該作者
學術型
回復

使用道具 舉報

板凳
ID:138247 發表于 2019-9-9 11:34 | 只看該作者

感謝分享,非常有幫助。。
回復

使用道具 舉報

地板
ID:245179 發表于 2019-10-21 16:56 | 只看該作者
寫的不錯,已分享使用
回復

使用道具 舉報

5#
ID:334838 發表于 2019-10-24 15:11 | 只看該作者
學習下,正好需要做電機控制
回復

使用道具 舉報

6#
ID:626923 發表于 2019-10-28 22:31 | 只看該作者
學習下
回復

使用道具 舉報

7#
ID:579837 發表于 2019-12-18 00:01 | 只看該作者
最近正在學習電機控制,謝謝分享
回復

使用道具 舉報

8#
ID:236035 發表于 2019-12-20 10:51 | 只看該作者
謝謝樓主分享,這是個弱項,還沒搞過項目。
回復

使用道具 舉報

9#
ID:353855 發表于 2020-2-9 18:19 | 只看該作者
感謝分享,非常有幫助。。
回復

使用道具 舉報

10#
ID:353855 發表于 2020-2-18 16:21 | 只看該作者
寫的不錯,已分享使用
回復

使用道具 舉報

11#
ID:25103 發表于 2020-7-16 12:12 | 只看該作者
仿真好像不能用,請教樓主,謝謝!
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: www国产成人免费观看视频,深夜成人网 | 欧美大片一区二区 | 国产日韩欧美一区二区 | 午夜综合 | 欧美一级免费看 | 精品在线99| 亚洲欧美中文日韩在线v日本 | 日韩成人| 一区二区三区中文字幕 | 特黄色一级毛片 | 久久精品中文 | 搞av.com| 91精品国产综合久久久久久首页 | 国产精品免费观看 | 精品99爱视频在线观看 | 欧美日韩一区二区三区四区 | 午夜专区 | 亚洲精品久久久一区二区三区 | 日韩欧美二区 | 一区二区三区中文字幕 | 亚洲欧美中文日韩在线v日本 | 精品亚洲一区二区三区 | 亚洲一区二区精品视频 | 欧美一区二区免费 | 国产精品 欧美精品 | 9久9久 | 国内精品久久久久久影视8 最新黄色在线观看 | 中文字幕第一页在线 | www.天堂av.com | 成人在线播放 | 蜜桃日韩| 亚洲一区二区免费视频 | 国产成人精品午夜视频免费 | 国产一区二区三区在线 | 95国产精品 | 国产网站在线 | 国产精品久久国产愉拍 | 99精品久久久国产一区二区三 | 国产蜜臀97一区二区三区 | 成人免费视频在线观看 | 国产精品99久久久久久人 |