|
步進(jìn)電機(jī)梯形加速程序
單片機(jī)源程序如下:
- /*基于STM32的單軸簡(jiǎn)易運(yùn)動(dòng)控制器/脈沖發(fā)生器*/
- /*脈沖+方向控制步進(jìn)伺服電機(jī)*/
- /*
- 優(yōu)化記錄:
- 增加急停GPIOC.0、正向極限GPIOC.1、負(fù)向極限GPIOC.2等輸入IO接點(diǎn)
- 中斷修改TIMx_PSC一個(gè)寄存器的值,而不是修改TIMx_ARR預(yù)加載寄存器+TIMx_CCRx比較值寄存器兩個(gè)值,縮短中斷處理時(shí)間
- 定位指令DRVI/DRVA中,目標(biāo)頻率設(shè)定過高、而實(shí)際輸出脈沖數(shù)過少時(shí),則不必加速到目標(biāo)頻率即進(jìn)入減速區(qū)
- */
- /*
- DRVI(A);相對(duì)定位,輸出A(A取絕對(duì)值)個(gè)脈沖
- A不能為0
- 若A為正數(shù),則方向?yàn)檎PIOB.0為高電平
- 若A為負(fù)數(shù),則方向?yàn)樨?fù)、GPIOB.0為低電平
- DRVA(A) 絕對(duì)定位,輸出脈沖,運(yùn)行至A個(gè)脈沖的位置
- 若目標(biāo)位置A等于當(dāng)前位置D,則不執(zhí)行脈沖輸出
- 若A大于D 則方向?yàn)檎GGPIOB.5為高電平
- 若A小于D 則方向?yàn)樨?fù)GPIOB.5為低電平
- GPIOB.1為脈沖輸出
- GPIOB.0為方向輸出
- 占空比為50%
- GPIOC.0急停
- GPIOC.1正向極限
- GPIOC.2反向極限
- GPIOC.3
- GPIOC.4
- GPIOC.5
- GPIOC.6
- GPIOC.7啟動(dòng)
- 階梯曲線形式加減速
- 加減速時(shí)間以10毫秒為基本單位
- 加減速以每10毫秒為一級(jí)
- 例如
- 加減速時(shí)間為50毫秒,則加減速級(jí)數(shù)為50/10=5
- 加減速時(shí)間為100毫秒,則加減速級(jí)數(shù)為100/10=10
- 加減速時(shí)間為150毫秒,則加減速級(jí)數(shù)為150/10=15
- */
- #include "sys.h"
- #include "delay.h"
- #define MasterFrequency 0x100000//最高頻率限制100K
- long Current; //當(dāng)前位置脈沖數(shù)
- long Target; //目標(biāo)位置脈沖數(shù)
- long StartSave; //定位指令剛開始啟動(dòng)時(shí)的當(dāng)前值
- long DownStartSave; //開始進(jìn)入減速時(shí)的當(dāng)前值
- typedef enum
- {
- OFF = 0,
- ON = 1,
- }STATUS_Type;
- typedef enum
- {
- us=1,
- ms=1000,
- sce=1000000,
- }DELAY_Type;
- STATUS_Type RunFlag; //定位指令脈沖輸出執(zhí)行標(biāo)志
- STATUS_Type StopCommand;//定位指令脈沖輸出停止命令標(biāo)志
- STATUS_Type PlusMinus; //正負(fù)方向標(biāo)志
- u32 StartFreq; //啟動(dòng)頻率
- u32 TargetFreq; //目標(biāo)頻率
- u32 UDTimer=1000; //加減速時(shí)間
- u32 LadderFreq[102];
- u16 LadderPSC[202]; //加減速0至9級(jí)速度/頻率預(yù)分頻值
- u16 LadderNum; //加減速速度級(jí)數(shù)
- u16 LadderOrderNum; //加減速速度編號(hào)
- long LadderTarget[202]; //各速度等級(jí)目標(biāo)值
- int m;
- void MyTimer3_Init()//定時(shí)器3初始化
- {
- RCC->APB2ENR|=(1<<3)|(1<<0); //使能AFIO、GPIOB時(shí)鐘
- GPIOB->CRL&=0xffffff00; //PB5
- GPIOB->CRL|=0x000000a2; //配置PORTB.1為復(fù)用推挽輸出、配置PORTB.0為推挽輸出,輸出最大頻率2MHz 00B000a2
- GPIOB->BRR=1<<0;
-
- RCC->APB1ENR|=1<<1; //使能定時(shí)器TIMER3時(shí)鐘
- TIM3->CR1|=1<<2; //設(shè)置只有計(jì)數(shù)溢出作為T3更新中斷
- TIM3->DIER|=1<<0; //允許定時(shí)器3計(jì)數(shù)溢出中斷
- MY_NVIC_Init(1,3,TIM3_IRQn,2);
- TIM3->CCMR2&=~(3<<8); //T3_CH4通道配置為輸出模式
- TIM3->CCMR2|=7<<12; //T3_CH4為PWM模式2
- TIM3->CCER|=1<<12; //T3_CH4通道輸出使能
- TIM3->PSC=71;
- }
- void Pluse_start()
- {
-
- RunFlag=ON; //脈沖輸出定位指令執(zhí)行標(biāo)志置ON
- StartSave=Current;
- LadderOrderNum=0;//加減速級(jí)數(shù)序號(hào)為0
- TIM3->ARR=LadderPSC[0];
- TIM3->CCR4=TIM3->ARR>>1; //匹配值1等于重裝值一半,是以占空比為50%
- //delay_ms(2); //脈沖信號(hào)比方向信號(hào)滯后,以提高可靠性
-
- TIM3->CR1|=1<<0; //啟動(dòng)定時(shí)器TIMER2計(jì)數(shù)
- }
- /*********************************************************************************
- 函數(shù)名稱:DRVI
- 函數(shù)功能:相對(duì)定位
- 入口參數(shù):long offset相對(duì)偏移脈沖,u32 frequency最高頻率
- 返回值:無
- *********************************************************************************/
- void DRVI(long offset,u32 frequency)
- {
- u16 h;
- u16 i;
- u32 j;
- if((offset!=0)&&(RunFlag==OFF)&&((GPIOC->IDR&0x01)==0))//相對(duì)偏移值為0則不接受命令,脈沖輸出已執(zhí)行,不接受命令
- {
- Target=Current+offset; //目標(biāo)值等于當(dāng)前值加上相對(duì)偏移值
-
- if(frequency<StartFreq) //如果設(shè)定目標(biāo)頻率小于啟動(dòng)頻率
- {
- frequency=StartFreq;
- }
- else if(frequency>MasterFrequency)//否則如果設(shè)定目標(biāo)頻率高于最高限制頻率
- {
- frequency=MasterFrequency;
- }
-
- LadderNum=UDTimer/10;//加減速級(jí)數(shù)
- j=(frequency-StartFreq)/LadderNum;//等差
- for(i=0;i<LadderNum;i++)
- {
- LadderFreq[i]=i*j+StartFreq;//加減速各階梯頻率
- LadderPSC[i]=(6000000/LadderFreq[i])-1;//加減速各階梯頻率對(duì)應(yīng)定時(shí)器預(yù)分頻值
- }
- LadderFreq[LadderNum]=frequency;//目標(biāo)頻率,最高頻率
- LadderPSC[LadderNum]=6000000/frequency-1;//目標(biāo)頻率(最高頻率)對(duì)應(yīng)定時(shí)器預(yù)分頻值
-
- if(offset>0)//相對(duì)偏移值為正數(shù)
- {
- GPIOB->BSRR=1<<0;//相對(duì)偏移值為正數(shù),方向?yàn)檎较蛐盘?hào)高電平
- PlusMinus=ON;//正負(fù)方向標(biāo)志置ON
-
- LadderTarget[0]=Current+StartFreq/100;//加速第一段目標(biāo)脈沖值
- for(i=1;i<LadderNum;i++)
- {
- LadderTarget[i]=LadderTarget[i-1]+LadderFreq[i]/100;//加速各段目標(biāo)脈沖值
- }
-
- while(offset<=((LadderTarget[LadderNum-1]-Current)<<1))//如果偏移量小于二倍加速增量
- {
- LadderNum--;//加速等級(jí)數(shù)減一 頻率設(shè)定過高、實(shí)際輸出脈沖數(shù)過少的情況下不必加速至設(shè)定頻率,避免過沖
- }
-
- for(i=0,h=LadderNum<<1; i<LadderNum; i++,h--)
- {
- LadderPSC[h]=LadderPSC[i];//減速各段定時(shí)器重裝值
- }
-
- LadderTarget[LadderNum<<1]=Target;//減速最后一段目標(biāo)脈沖值
- for(i=(LadderNum<<1)-1,h=0;i>LadderNum;i--,h++)
- {
- LadderTarget[i]=LadderTarget[i+1]-LadderFreq[h]/100;//減速各段目標(biāo)脈沖值
- }
- }
- else//否則相對(duì)偏移值為負(fù)數(shù)
- {
- GPIOB->BRR=1<<0;//相對(duì)偏移值為負(fù)數(shù),方向?yàn)樨?fù),方向信號(hào)低電平
- PlusMinus=OFF;//正負(fù)方向標(biāo)志OFF
-
- LadderTarget[0]=Current-StartFreq/100;//加速第一段目標(biāo)脈沖值
- for(i=1;i<LadderNum;i++)
- {
- LadderTarget[i]=LadderTarget[i-1]-LadderFreq[i]/100;//加速各段目標(biāo)脈沖值
- }
-
- while(offset>=((LadderTarget[LadderNum-1]-Current)<<1))//如果偏移量小于二倍加速增量
- {
- LadderNum--;//加速等級(jí)數(shù)減一 頻率設(shè)定過高、實(shí)際輸出脈沖數(shù)過少的情況下不必加速至設(shè)定頻率,避免過沖
- }
-
- for(i=0,h=LadderNum<<1; i<LadderNum; i++,h--)
- {
- LadderPSC[h]=LadderPSC[i];
- }
-
- LadderTarget[LadderNum<<1]=Target;//減速最后一段目標(biāo)脈沖值
- for(i=(LadderNum<<1)-1,h=0;i>LadderNum;i--,h++)
- {
- LadderTarget[i]=LadderTarget[i+1]+LadderFreq[h]/100;//減速各段目標(biāo)脈沖值
- }
- }
- LadderTarget[LadderNum]=Target + Current - LadderTarget[LadderNum-1];
- Pluse_start();//脈沖輸出正式啟動(dòng)
- }
- }
- /*********************************************************************************
- 函數(shù)名稱:DRVA
- 函數(shù)功能:絕對(duì)定位
- 入口參數(shù):long target目標(biāo)位置脈沖,u32 frequency最高頻率
- 返回值:無
- *********************************************************************************/
- void DRVA(long target,u32 frequency)//3200 2khz
- {
- u16 h;
- u16 i;
- u32 j;
- long offset=target-Current;//
- if((offset!=0)&&(RunFlag==OFF)&&((GPIOC->IDR&0x01)==0)) //目標(biāo)位置等于當(dāng)前位置,則不接受命令
- {
- ///////////////////////////////////////////////////////////////////////////////////////////////////////
- Target=target; //目標(biāo)位置設(shè)定(等于參數(shù))
-
- if(frequency<StartFreq) //如果設(shè)定目標(biāo)頻率小于啟動(dòng)頻率
- {
- frequency=StartFreq;
- }
- else if(frequency>MasterFrequency)//否則如果設(shè)定目標(biāo)頻率高于最高限制頻率
- {
- frequency=MasterFrequency;
- }
- LadderNum=UDTimer/10;//加減速級(jí)數(shù) 分成100級(jí)
- j=(frequency-StartFreq)/LadderNum;//等差 每個(gè)階段所加的頻率數(shù)
-
- for(i=0;i<LadderNum;i++) //獲取每個(gè)階段的速度值
- {
- LadderFreq[i]=i*j+StartFreq;//加減速各階梯頻率 每個(gè)階段的速度 等級(jí)到J
- LadderPSC[i]=(1000000/LadderFreq[i])-1;//加減速各階梯頻率對(duì)應(yīng)定時(shí)器初值
- }
-
- LadderFreq[LadderNum]=frequency;
- LadderPSC[LadderNum]=1000000/frequency-1;//
- /////////////////////////////////////////////////////////////////////////////////////////////////////
- if(offset>0)//目標(biāo)位置值大于當(dāng)前位置值
- {
- GPIOB->BSRR=1<<0;//則方向?yàn)檎较蛐盘?hào)高電平
- PlusMinus=ON;//正負(fù)方向標(biāo)志置ON
-
- LadderTarget[0]=Current+StartFreq/100;
- for(i=1;i<LadderNum;i++)
- {
- LadderTarget[i]=LadderTarget[i-1]+LadderFreq[i]/100;
- }
-
- while(offset<=((LadderTarget[LadderNum-1]-Current)<<1))//如果偏移量小于二倍加速增量
- {
- LadderNum--;//加速等級(jí)數(shù)減一 頻率設(shè)定過高、實(shí)際輸出脈沖數(shù)過少的情況下不必加速至設(shè)定頻率,避免過沖
- }
-
- for(i=0,h=LadderNum<<1; i<LadderNum; i++,h--)
- {
- LadderPSC[h]=LadderPSC[i];
- }
-
- LadderTarget[LadderNum<<1]=Target;//減速最后一段目標(biāo)脈沖值
- for(i=(LadderNum<<1)-1,h=0;i>LadderNum;i--,h++)
- {
- LadderTarget[i]=LadderTarget[i+1]-LadderFreq[h]/100;//減速各段目標(biāo)脈沖值
- }
- }
- else//否則目標(biāo)位置值小于當(dāng)前位置值,
- {
- GPIOB->BRR=1<<0;//則方向?yàn)樨?fù),方向信號(hào)低電平
- PlusMinus=OFF;//正負(fù)方向標(biāo)志OFF
-
- LadderTarget[0]=Current-StartFreq/100;
- for(i=1;i<LadderNum;i++)
- {
- LadderTarget[i]=LadderTarget[i-1]-LadderFreq[i]/100;
- }
-
- while(offset>=((LadderTarget[LadderNum-1]-Current)<<1))//如果偏移量小于二倍加速增量
- {
- LadderNum--;//加速等級(jí)數(shù)減一 頻率設(shè)定過高、實(shí)際輸出脈沖數(shù)過少的情況下不必加速至設(shè)定頻率,避免過沖
- }
- for(i=0,h=LadderNum<<1; i<LadderNum; i++,h--)
- {
- LadderPSC[h]=LadderPSC[i];
- }
- LadderTarget[LadderNum<<1]=Target;//減速最后一段目標(biāo)脈沖值
- for(i=(LadderNum<<1)-1,h=0; i>LadderNum; i--,h++)
- {
- LadderTarget[i]=LadderTarget[i+1]+LadderFreq[h]/100;//減速各段目標(biāo)脈沖值
- }
- }
- LadderTarget[LadderNum]=Target + Current - LadderTarget[LadderNum-1];//勻速段目標(biāo)位置/進(jìn)入減速時(shí)位置 數(shù)組元素60
- Pluse_start();//脈沖輸出正式啟動(dòng)
- }
- }
- /*********************************************************************************
- 函數(shù)名稱:SLOPE
- 函數(shù)功能:斜坡設(shè)置(坡度斜率設(shè)置) 限定啟動(dòng)頻率在100---1000之間 限制時(shí)間在50---1000
- 入口參數(shù):u32 frequency啟動(dòng)頻率,u32 timer加減速時(shí)間
- 返回值:無
- *********************************************************************************/
- void SLOPE(u32 frequency,u32 timer)//200hz 600
- {
- if(frequency<100)
- {
- StartFreq=100;
- }
- else if(frequency>1000)
- {
- StartFreq=1000;
- }
- else
- {
- StartFreq=frequency;
- }//啟動(dòng)頻率設(shè)置大于等于100小于等于1000
-
- if(timer<50)
- {
- UDTimer=50;
- }
- else if(timer>1000)
- {
- UDTimer=1000;
- }
- else
- {
- UDTimer=(timer/10)*10; //取整數(shù)
- }//加減速時(shí)間設(shè)置 大于等于50小于等于1000,且為整十?dāng)?shù)
- }
- void TIM3_IRQHandler() //定時(shí)器3全局中斷函數(shù)
- {
- long temp;
- if(TIM3->SR&0x0001)
- {
- if(PlusMinus==ON)
- {
- temp=Current;
- //如果方向?yàn)檎?dāng)前值加一
- temp++;
- Current=temp;
- }
- else
- {
- temp=Current;
- temp--; //否則方向?yàn)樨?fù),當(dāng)前值減一
- Current=temp;
- }
-
- if(Current==LadderTarget[LadderOrderNum])
- {
- if(LadderOrderNum< (LadderNum<<1))
- {
- LadderOrderNum++;
- TIM3->PSC=LadderPSC[LadderOrderNum];
- }
- else
- {
- TIM3->CR1&=~(1<<0);
- TIM3->CNT=0x0000;
-
- RunFlag=OFF;
- }
- }
-
- TIM3->SR=0x0000;
- }
- }
- void Variable_Init()
- {
- Target=0;//目標(biāo)位置脈沖值
- Current=0;//當(dāng)前位置脈沖值
- RunFlag=OFF;//脈沖定位指令執(zhí)行標(biāo)志
- StopCommand=OFF;//定位指令脈沖輸出停止命令標(biāo)志
- }
- void PAUSE()
- {
- while(RunFlag==ON);
- }
- int main(void)
- {
- // Stm32_Clock_Init(9);
- //delay_init(72);
- MyTimer3_Init(); //定時(shí)器2初始化
- Variable_Init(); //變量初始化
- SLOPE(200,600); //啟動(dòng)頻率200Hz,加減速時(shí)間600毫秒 斜率設(shè)置
- DRVA(1200,4000);
- while(1)
- {
- //以2KHz頻率前進(jìn)3200脈沖當(dāng)量距離
- // //PAUSE(); //等待脈沖輸出執(zhí)行完畢
- // delay_ms(500);
- // DRVA(0,20000); //以2KHz頻率前進(jìn)3200脈沖當(dāng)量距離
- // PAUSE(); //等待脈沖輸出執(zhí)行完畢
- // delay_ms(500);
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
步進(jìn)電機(jī)寄存器版本.zip
(698.35 KB, 下載次數(shù): 187)
2018-4-26 12:32 上傳
點(diǎn)擊文件名下載附件
梯形加速 下載積分: 黑幣 -5
|
|