1.流程图
2,代码段
1.码盘
const UNBIT16 CarAccelerationList[CAR_ACCELERATION_STEP_MAX + 1] =
{
1897,786,603,508,448,405,372,347,326,308,
293,280,268,258,249,241,234,227,221,215,
210,205,200,196,192,188,184,181,178,175,
172,169,166,164,162,159,157,155,153,151,
149,147,146,144,142,141,139,138,136,135,
133,132,131,130,129,127,126,125,124,123,
122,121,120,119,118,117,116,115,115,114,
113,112,111,111,110,109,108,108,107,106,
106,105,104,104,103,103,102,101,101,100,
100,99,99,98,98,97,97,96,96,95,
95,94,94,93,93,92,92,91,91,91,
90,90,89,89,89,88,88,88,87,87,
86,86,86,85,85,85,84,84,84,83,83
};
2.速度改变段
void VerticalCarMotorSpeedCtr(UNBIT16 speed)
{
if(speed > CAR_ACCELERATION_STEP_MAX)
{
VerticalCarMotorSpeed = CAR_ACCELERATION_STEP_MAX;
}
else
{
VerticalCarMotorSpeed = speed;
}
TIM3->PSC = (CarAccelerationList[VerticalCarMotorSpeed]/10 *7); //±äƵ£¬³õʼÊÇ1001 }
3.速度控制段(包含距离计算,⽅向确定,速度控制)
//Òƶ¯´¹Ö±Ð¡³µµ½Ä¿±êµØÖ·
UNBIT8 MoveVerticalCarToTargetAddr(UNBIT8 MoveCarAddr)
{
static UNBIT16 DistanceTemp;
switch(MoveVerticalCarSta)
{
case MOVE_VerticalCAR_STA_INIT:
MoveVerticalCarSta = MOVE_VerticalCAR_STA_ACT;
VerticalCarPulseSta = 0;
VerticalCarPulseNum = 0;
DistanceTemp = 0;
MoveVerticalCarLeftFlag = 0;
MoveVerticalCarRightFlag = 0;
MoveVerticalCarStep = 0;
DeviceCfg.SUBDIVIDE = 0;
DeviceCfg.MoveStep = 0;
VerticalCarMotorSpeedCtr(0);
//¿ØÖÆÔ˶¯·½ÏòÒÔ¼°²éÕÒÐèÒªÔ˶¯¾àÀë¶Î
if(MoveCarAddr > DeviceCfg.sign) //ÕýÏòÒƶ¯
{
stepping_motor_reversal();
MoveVerticalCarLeftFlag = 1;
MoveVerticalCarStep = MoveCarAddr - DeviceCfg.sign;
}
else
{
stepping_motor_foreward();
MoveVerticalCarRightFlag = 1;
MoveVerticalCarStep = DeviceCfg.sign - MoveCarAddr;
}
//¼ÆËã×ܵÄÄ¿±ê²½Êý
DeviceCfg.MaxStep = (MoveVerticalCarStep * STEP_MOTOR);
break;
case MOVE_VerticalCAR_STA_ACT:
CatchVerticalCarPulseFunc( ); //²¶×½Ð¡³µÂö³åÊý£¨Ã¿Ò»¸öϽµÑؼÇÒ»¸öÂö³å£©
if(VerticalCarPulseNum != 0)
{
if(DeviceCfg.MoveStep < 20)
{
VerticalCarPulseNum = 0;
}
}
}
if(DistanceTemp != DeviceCfg.MoveStep )
{
DistanceTemp = DeviceCfg.MoveStep;
if(DeviceCfg.MoveStep < DeviceCfg.MaxStep/2) //²»µ½Ä¿±ê²½ÊýµÄÒ»°ã¶¼ÊǼÓËÙ
{
if(VerticalCarMotorSpeed < CAR_ACCELERATION_STEP_MAX){
VerticalCarMotorSpeed ++;
VerticalCarMotorSpeedCtr(VerticalCarMotorSpeed);
}
}
else if(DeviceCfg.MoveStep > (DeviceCfg.MaxStep - CAR_ACCELERATION_STEP_MAX - 20)) //ÌáÇ°¼õËÙ
{
if(VerticalCarMotorSpeed > 0)
{
VerticalCarMotorSpeed --;
VerticalCarMotorSpeedCtr(VerticalCarMotorSpeed);
maxstep}
}
}
if(VerticalCarPulseNum == MoveVerticalCarStep) //Èç¹û¾àÀë¶ÎºÍÂö³åÊýÏàµÈÁË
{
stepping_motor_stop();
if(MoveVerticalCarLeftFlag == 1) //¸üÐÂС³µµ±Ç°Î»ÖÃ
{
DeviceCfg.sign = (DeviceCfg.sign + VerticalCarPulseNum);
}
else
{
DeviceCfg.sign = (DeviceCfg.sign - VerticalCarPulseNum);
}
return 1;
}
else if(DeviceCfg.MoveStep > DeviceCfg.MaxStep + 100) //Èç¹ûС³µ²½Êý´óÓÚ×î´ó²½Êý¼Ó100£¬Ôò±¨´í²¢ÇÒֹͣǰ½ø {
stepping_motor_stop();
return 2;
}
return 0;
}
}
void CatchVerticalCarPulseFunc(void)
{
switch(VerticalCarPulseSta)
{
case 0:
if(GetVerticalCarPlaceSta( ) == SENSOR_COVER)
{
VerticalCarPulseSta = 1;
DeviceCfg.MoveVerticalCarLoseStep = 8;
}
break;
case 1:
if(GetVerticalCarPlaceSta( ) == SENSOR_DISCOVER)
{
VerticalCarPulseSta = 0;
}
else if(DeviceCfg.MoveVerticalCarLoseStep == 0)
{
VerticalCarPulseSta = 2;
}
break;
case 2:
if(GetVerticalCarPlaceSta( ) == SENSOR_DISCOVER)
{
VerticalCarPulseSta = 3;
DeviceCfg.MoveVerticalCarLoseStep = 8;
}
break;
case 3:
if(GetVerticalCarPlaceSta( ) == SENSOR_COVER)
{
VerticalCarPulseSta = 2;
}
else if(DeviceCfg.MoveVerticalCarLoseStep == 0)
{
VerticalCarPulseNum ++;
VerticalCarPulseSta = 0;
}
break;
}
}
5.中断部分
void TIM3_IRQHandler(void) //ϸ·ÖΪ2
{
if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET) { //¼ì²éTIM3¸üÐÂÖжϷ¢ÉúÓë·ñ TIM_ClearITPendingBit(TIM3, TIM_IT_CC1); //Çå³ýTIMx¸üÐÂÖжϱêÖ¾
DeviceCfg.SUBDIVIDE = (DeviceCfg.SUBDIVIDE++); //¿ØÖÆϸ·Ö
if(DeviceCfg.MoveVerticalCarLoseStep > 0)
{
DeviceCfg.MoveVerticalCarLoseStep--; //µÍµçƽÂö³åÊýÁ¿
}
if( DeviceCfg.SUBDIVIDE == 8){ //µ±×ßÁËÒ»²½µÄʱºò½øÈë¸ÄÌõ¼þ
DeviceCfg.SUBDIVIDE = 0; //ÖØмÆËãÂö³åÊýÁ¿
DeviceCfg.MoveStep = DeviceCfg.MoveStep + 1; //²½Êý¼Ñ¼Ñ
}
}
}
6.定时器初始化段
void TIM3_Configuration(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); //TIM3_CH1Òý½ÅÖØÓ³Éä
TIM_TimeBaseStructure.TIM_Period = 99;
TIM_TimeBaseStructure.TIM_Prescaler = 86; //ÉèÖÃÓÃÀ´×÷ΪTIMxʱÖÓƵÂʳýÊýµÄÔ¤·ÖƵֵ ²»·ÖƵ
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //ÉèÖÃʱÖÓ·Ö¸î:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIMÏòÉϼÆÊýģʽ
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //¸ù¾ÝTIM_TimeBaseInitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯TIMxµÄʱ¼ä»ùÊýµ¥Î»
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆģʽ2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±È½ÏÊä³öʹÄÜ
TIM_OCInitStructure.TIM_Pulse = 50; //ÉèÖôý×°È벶»ñ±È½Ï¼Ä´æÆ÷µÄÂö³åÖµ£¬³õʼµÄÕ¼¿Õ±È
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
TIM_OC1Init(TIM3, &TIM_OCInitStructure); //¸ù¾ÝTIM_OCInitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèTIMx
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //ʹÄÜTIMxÔÚCCR2ÉϵÄԤװÔؼĴæÆ÷
//ÉÏÃæÁ½¾äÖеÄOC2È·¶¨ÁËÊÇchannle¼¸£¬ÒªÊÇOC3ÔòÊÇchannel 3
TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE); //ʹÄÜÖ¸¶¨µÄTIM3ÖжÏ,ÔÊÐí¸üÐÂÖжÏ
TIM_ARRPreloadConfig(TIM3, ENABLE); //ʹÄÜTIMxÔÚARRÉϵÄԤװÔؼĴæÆ÷
TIM_Cmd(TIM3, DISABLE); //ʹÄÜTIMxÍâÉè
TIM_CtrlPWMOutputs(TIM3, ENABLE); // ´ò¿ªPWM
}
3.总结
1.步进电机加减速,⾸先要确定三要素,电机移动的⽅向,电机运动的距离步数,电机的速度控制。如果有传感器还需要传感器的⾼低电平计数。 2.同步:有带传感器的需要传感器和电机运动进⾏同步,变速和步数需要同步。不能使电机⼀下加速到最⼤值或者减速到最⼩值。⼀步⼀个速度进⾏控制。
3.最后退出加减速时,需要实时更新当前位置变化