基于STM32步进电机加减速控制查表法

Sahar ·
更新时间:2024-09-21
· 647 次阅读

步进电机加减速查表法

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 (DeviceCfg.MaxStep - CAR_ACCELERATION_STEP_MAX - 20)) //ÌáÇ°¼õËÙ { if(VerticalCarMotorSpeed > 0) { VerticalCarMotorSpeed --; VerticalCarMotorSpeedCtr(VerticalCarMotorSpeed); } } } 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; } }

4.传感器监测

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.最后退出加减速时,需要实时更新当前位置变化


作者:st奔跑的小绵羊



stm32 电机 步进电机

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章