小弟是初次使用STM32 的MCU,希望有能力之士可以幫忙。
情況:
要用一塊STM32F103VET6 同時控制3個步進電機(要同步移動), 電機是二相,設定是分8細步,即1600步一圈.我就用了TIM2, TIM3, TIM4做PWM輸出, 當定時器中斷時就調整速度.
以下是定時器設定的功能
void TIM2_Configuration (uint32_t init_speed, FunctionalState state)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint16_t CCR1_Val;
uint16_t PrescalerValue = 333;
uint32_t new_period = 2400;
/* Compute the prescaler value */
PrescalerValue = (uint16_t) (SystemCoreClock / SystemCoreClock) - 1;
/* calculate the new period time*/
//new_period = ((SystemCoreClock / (init_speed * 1000)) - 1); //init speed is 10k
new_period = init_speed;
/* set the default duty is 50%*/
CCR1_Val = (new_period / 2);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = new_period; //init speed 10k
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel 2 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_ClearFlag(TIM2, TIM_FLAG_Update); //clean the IRQ flag
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //set the IRQ enable
TIM_ARRPreloadConfig(TIM2, ENABLE);
/* TIM3 enable counter */
if (state == ENABLE) {
TIM_Cmd(TIM2, ENABLE);
} else {
TIM_Cmd(TIM2, DISABLE);
}
}
當中斷產生時就進行速度調整,加或減速,以梯形圖的方法控制
TIM2->ARR = ((SystemCoreClock / tim2_freq) - 1);
TIM2->CCR1 = ((SystemCoreClock / tim2_freq) - 1) /2;
問題:
1. 由於沒有用編碼器,所以沒有回饋的步數,但當電機來回在軌道上行走數次就會明顯地失步(開始位置有1個位接近開關), 未能回到開始的位置. 有沒有其他人預到相同的問題?
是我的控制方法不好?
是我的軌道安裝不好?或是其他?
請教有能之士.
謝 |