文章目錄
- 一、定時器基礎頻率
- 二、驅動原理
- 三、關鍵代碼
對于stm32芯片來說,步進電機的驅動由于要在中斷中不斷計算下一次脈沖的時間而極其消耗算力,使用計算的方法對于芯片的算法消耗更高,特別是在f1這種算力比較低的芯片上,這時候使用查表法是一種比較靠譜的方式,這里只給出部分代碼思路。當然使用查表法的缺點就是在算力夠用的情況下相比計算會沒有那么平滑,但是在使用更多電機的時候查表法表現更好,計算會由于算力不足出現卡頓的情況。
一、定時器基礎頻率
首先就是定時器基礎頻率的選擇,stm32f1定時器的基礎頻率設置是36M,在這個基礎上肯定還是要分頻的,為了移植方便,選擇分頻后的頻率為100k,所以分頻系數為360-1;
htim1.Init.Prescaler = 360-1;
至于period這個參數就無所謂了,反正在電機運動的時候這個會改變。
下面是定時器的參考配置:
/* TIM1 init function */
void MX_TIM1_Init(void)
{/* USER CODE BEGIN TIM1_Init 0 *//* USER CODE END TIM1_Init 0 */TIM_ClockConfigTypeDef sClockSourceConfig = {0};TIM_MasterConfigTypeDef sMasterConfig = {0};TIM_OC_InitTypeDef sConfigOC = {0};TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};/* USER CODE BEGIN TIM1_Init 1 *///200khz/* USER CODE END TIM1_Init 1 */htim1.Instance = TIM1;htim1.Init.Prescaler = 360-1;htim1.Init.CounterMode = TIM_COUNTERMODE_UP;htim1.Init.Period = 400-1;htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htim1.Init.RepetitionCounter = 0;htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;if (HAL_TIM_Base_Init(&htim1) != HAL_OK){Error_Handler();}sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK){Error_Handler();}if (HAL_TIM_PWM_Init(&htim1) != HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK){Error_Handler();}sConfigOC.OCMode = TIM_OCMODE_PWM1;sConfigOC.Pulse = 0;sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK){Error_Handler();}sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;sBreakDeadTimeConfig.DeadTime = 0;sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK){Error_Handler();}/* USER CODE BEGIN TIM1_Init 2 *//* USER CODE END TIM1_Init 2 */HAL_TIM_MspPostInit(&htim1);
}
二、驅動原理
使用查表法驅動步進電機使用了兩個表,一個是加速表,即速度由慢到快S型曲線加速的過程,一個是速度表,通過這個表可以計算出下個定時器周期的自動重裝載值。
加速度表就是一個S型曲線,通過MATLAB就能直接生成,速度表是根據計算得到的,我這里直接用EXCEL表做了,
因為在定時器處理中CCR的值為ARR的一半,所以計算的時候是200k,部分表格如下:
轉速就代表每分鐘多少轉。
三、關鍵代碼
加速段ARR:
TIM4->ARR = Motor[0].Speed / s_curve_table[Motor[0].count_step/Motor[0].Accdelay];
這里有個Accdelay,這個是指加速度延遲的倍數,因為加速度表只有那么長,在高速的時候加速就會顯得很快,使用這個可以顯著的把加速表進行延長。
勻速段ARR:
TIM4->ARR = Motor[0].Speed / s_curve_table[Motor[0].Acc_Len/Motor[0].Accdelay - 1];
減速段ARR:
else{TIM4->ARR = Motor[0].Speed / s_curve_table[(Motor[0].Dec_Len - X_cnt-1)/Motor[0].Accdelay ];TIM4->CCR2 = TIM4->ARR / 2;X_cnt++;}