一、步進(jìn)電機閉環(huán)驅(qū)動器
該篇文章中用到的步進(jìn)電機閉環(huán)驅(qū)動器為Emm42_V4.0步進(jìn)電機閉環(huán)驅(qū)動器。該閉環(huán)驅(qū)動器自帶FOC矢量閉環(huán)控制算法,能實現(xiàn)力矩、速度、位置三環(huán)控制。
如下圖所示,該42步進(jìn)閉環(huán)電機驅(qū)動器的A+、A-、B+、B-連接步進(jìn)電機,通過右側(cè)的使能、脈沖、方向端對步進(jìn)電機進(jìn)行驅(qū)動控制。
二、CubeMx配置
首先要進(jìn)行時鐘配置。
1、Clock Configuration
配置時鐘前要先打開Pinout & Configuration中的RCC,選擇Crystal/Ceramic Resonator開啟外部晶振。
再根據(jù)自己單片機的外部晶振頻率設(shè)定參數(shù),如下圖所示。
2、脈沖端 定時器配置
再次回到Pinout & Configuration,在Timers中選擇一個你想要的定時器,這里我選擇的是定時器2,然后打開內(nèi)部時鐘(Clock Source:Intermal Clock)。
在配置通道功能為PWM輸出(PWM Generation)。這里我使用了4個步進(jìn)電機,因此選擇了4個通道。(下文視頻只演示了一個步進(jìn)電機,其他步進(jìn)電機也是一樣的道理,接線再補充程序就ok了)
再打開NVIC Settings使能定時器中斷。如下圖所示。
接著,要根據(jù)你上一步設(shè)置的時鐘和你的驅(qū)動器所能承載的頻率,來設(shè)置該定時器的頻率。
如我使用的驅(qū)動器最大脈沖頻率是120KHZ,最高轉(zhuǎn)速是2200+轉(zhuǎn),即我想要達(dá)到最高轉(zhuǎn)速,可以配置1.8°步距角的步進(jìn)電機為16細(xì)分,也就是(360 ÷ 1.8) × 16 = 3200個脈沖轉(zhuǎn)一圈(這個下文控制脈沖數(shù)會提到),再用120K ÷ 3200 = 37.5轉(zhuǎn)/s,即每分鐘2250轉(zhuǎn)。而如下圖所示,我的tim2屬于APB1,時鐘設(shè)置是84MHZ。
我使用的單片機為STM32F407,因此此處APB1總線對應(yīng)了通用定時器tim2 ~ 5,基本定時器tim6、tim7,通用定時器tim12~14。APB2總線對應(yīng)了高級定時器tim1、tim8,通用定時器tim9 ~ 11。
所以這里千萬千萬要小心不要把APB1的定時器時鐘頻率錯當(dāng)用成APB2的時鐘頻率了。
因此,以我的配置為例,使用84M ÷ 120K = 700,再用這個700對預(yù)分頻系數(shù)和計數(shù)周期進(jìn)行分配,如下圖所示。這里為了后面設(shè)置PWM占空比的方便,把計數(shù)周期定為100,那么PSC則為7。
公式:PWM輸出頻率 = 定時器時鐘頻率 ÷ ((psc+1) × (arr + 1))。
來用示波器檢查一下頻率和波形有沒有問題,這里用到的程序在下面會詳細(xì)講到,占空比50%,頻率120KHZ。
3、使能、方向端 引腳配置
如下圖所示,左鍵你想要使用的引腳配置為輸出即可,非常簡單。這里我使用了PC0-4作為使能端,PG0-4作為方向端,可根據(jù)需求選擇不會占用你所需功能的引腳作為單純的高低電平輸出引腳。
然后再進(jìn)入Project Manager配置工程名字和編譯環(huán)境、生成.c、.h文件等就ok了。
三、STM32F407定時器中斷控制步進(jìn)電機程序
先上張引腳配置圖,程序看起來更清晰一點。
0、引腳配置圖
引腳配置如下所示。
1、使用到的HAL庫函數(shù)
這兩個函數(shù)的功能下文會有解釋。
HAL_TIM_PWM_Stop(&htimx,TIM_CHANNEL_x);
HAL_TIM_PWM_Start(&htimx,TIM_CHANNEL_x);
2、脈沖觸發(fā)定時器初始化配置
在CubeMx生成的工程中,只需根據(jù)之前設(shè)置的定時器找到初始化程序,然后在程序最后加入以下程序即可,但是要根據(jù)自己配置的定時器和通道進(jìn)行參數(shù)配置。如設(shè)置的為定時器2,則Ctrl F搜索MX_TIM2_Init即可。
// 添加程序
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_4);
HAL_TIM_PWM_Start函數(shù)是啟動PWM輸出的函數(shù),如上所示對應(yīng)定時器2的4個通道。如下所示是我根據(jù)HAL庫生成的初始修改后的初始化函數(shù),把sConfigOC提出來是為了方便下面編寫PWM設(shè)置函數(shù),這兩步都是必要的。
/* ============================== 步進(jìn)電機脈沖觸發(fā)定時器初始化 ============================== */
TIM_HandleTypeDef htim2;
TIM_OC_InitTypeDef Motor_PWM_sConfigOC = {0};
/* TIM2 init function */
void Motor_PWM_MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 7-1;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 100-1;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
Motor_PWM_sConfigOC.OCMode = TIM_OCMODE_PWM1;
Motor_PWM_sConfigOC.Pulse = 0;
Motor_PWM_sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
Motor_PWM_sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_3) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_MspPostInit(&htim2);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_4);
}
3、步進(jìn)電機脈沖設(shè)置
如下所示,拿步進(jìn)電機1舉例,先停止定時器2通道1的PWM輸出,然后設(shè)置占空比,配置通道后再次開啟PWM即可。HAL_TIM_PWM_Stop為停止定時器x通道x的PWM輸出的函數(shù)。
void Motor1_pwm_Set(int motor1_n)
{
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
Motor_PWM_sConfigOC.Pulse = motor1_n;
HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
}
4、步進(jìn)電機使能、失能、改變方向
如下所示,配置高低電平即可。
void Motor1_enable(void) // 電機1使能
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET);
}
void Motor1_disable(void) // 電機1失能
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);
}
void Motor1_course(char course_mod) // 電機1改變方向
{
if(course_mod == 1){HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0, GPIO_PIN_SET);} // 正轉(zhuǎn)
else if(course_mod == 0){HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0, GPIO_PIN_RESET);} // 反轉(zhuǎn)
}
5、步進(jìn)電機正轉(zhuǎn)main.c程序
啟動步進(jìn)電機1,設(shè)置占空比為50%,正轉(zhuǎn)。
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
Motor_PWM_MX_TIM2_Init();
Motor_PWM_MX_TIM2_Init(); // 定時器初始化
Motor1_pwm_Set(50); // 設(shè)置占空比為50%(50/100)
Motor1_course(1); // 正轉(zhuǎn)
Motor1_enable(); // 使能
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
6、視頻效果演示
步進(jìn)電機控制
四、閉環(huán)步進(jìn)電機 精準(zhǔn)控制脈沖數(shù)
1、使用到的HAL庫函數(shù)
同樣的,這三個函數(shù)的功能下文也會有解釋。
HAL_TIM_PWM_Start_IT(&htimx, TIM_CHANNEL_x);
HAL_TIM_PWM_Stop_IT(&htimx, TIM_CHANNEL_x);
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim);
2、更改步進(jìn)電機驅(qū)動脈沖頻率
首先設(shè)置步進(jìn)電機細(xì)分步數(shù)為16,如下圖所示,此處使用的是步距角為1.8°的步進(jìn)電機。在這種參數(shù)配置的情況下,發(fā)送16個脈沖可轉(zhuǎn)動1.8°,因此轉(zhuǎn)動一圈所需的脈沖為(360° ÷ 1.8°) × 16 = 3200個脈沖。
基于上文的步進(jìn)電機驅(qū)動程序,我想把轉(zhuǎn)速改為大概5轉(zhuǎn)/s這樣子,所以我們應(yīng)當(dāng)更改一下脈沖頻率120KHZ。利用上述的一轉(zhuǎn)3200脈沖,那么5轉(zhuǎn)就需要16000個脈沖,因此將120KHZ改為16KHZ即可。那再計算一次PSC就是(84M ÷ 16K) ÷100 = 52.5。
將上文步進(jìn)電機脈沖觸發(fā)定時器初始化Motor_PWM_MX_TIM2_Init中的PSC改為53:
htim2.Instance = TIM2;
htim2.Init.Prescaler = 53-1;
同時也要刪去之前的HAL_TIM_PWM_Start()函數(shù),即刪去以下程序:
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_4);
3、更改步進(jìn)電機脈沖設(shè)置程序
因為我們不再使用HAL_TIM_PWM_Start和HAL_TIM_PWM_Stop,因此改程序也要刪去這兩個函數(shù)。以步進(jìn)電機1為例,改為以下程序:
void Motor1_pwm_Set(int motor1_n)
{
Motor_PWM_sConfigOC.Pulse = motor1_n;
HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_1);
}
當(dāng)然值得注意的一點是,我們定義的這個函數(shù)現(xiàn)在沒有了停止PWM的程序,所以我們一定要記得在更改PWM前要調(diào)用 HAL_TIM_PWM_Stop_IT 關(guān)閉定時器輸出PWM。
4、定時器PWM中斷回調(diào)函數(shù)
在使用定時器中斷之前,要記得在你的程序里重定義定時器的回調(diào)函數(shù)。
可選擇把以下程序添加到你的stm32f4xx_it.c里:
/* USER CODE BEGIN 1 */
int PWM_num = 0; // 脈沖數(shù)
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == htim2.Instance) // 確認(rèn)是否為步進(jìn)電機脈沖中斷的回調(diào)
{
PWM_num ++;
if(PWM_num >= 3200) // 第3200次(一圈)
{
PWM_num = 0;
HAL_TIM_PWM_Stop_IT(&htim2, TIM_CHANNEL_1); // 停止輸出PWM
//HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10); // 翻轉(zhuǎn)led燈電平
}
}
}
/* USER CODE END 1 */
上述程序中可以看到PWM_num正在累加,每調(diào)用一次回調(diào)函數(shù)就會累加一次,我們會在main函數(shù)中調(diào)用一次 HAL_TIM_PWM_Start_IT 函數(shù),大概猜一猜就能知道,該函數(shù)的用途就是開啟定時器輸出PWM,并且每發(fā)送一個脈沖就調(diào)用一次回調(diào)函數(shù)。
如下圖所示,箭頭所指的函數(shù)HAL庫已經(jīng)幫我們寫好了,會調(diào)用我們上述的中斷回調(diào)函數(shù)。
5、步進(jìn)電機正轉(zhuǎn)一圈閉環(huán)main.c程序
以下為main函數(shù)程序:
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
Motor_PWM_MX_TIM2_Init();
Motor1_pwm_Set(50);
HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_1);
Motor1_course(1);
Motor1_enable();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
6、視頻效果演示
閉環(huán)步進(jìn)電機——精準(zhǔn)控制脈沖數(shù)
五、程序鏈接
程序已經(jīng)打包好上傳到csdn的資源里了。
CSDN:HAL庫STM32F407定時器中斷控制步進(jìn)電機程序
CSDN:HAL庫STM32F407定時器中斷控制閉環(huán)步進(jìn)電機精準(zhǔn)控制脈沖數(shù)
也可以通過以下鏈接下載:
STM32F407定時器中斷控制步進(jìn)電機程序:
鏈接:https://pan.baidu.com/s/1svRzVW_7elkHg7wwQ4AN5A
提取碼:hpzq
STM32F407定時器中斷控制閉環(huán)步進(jìn)電機精準(zhǔn)控制脈沖數(shù):
鏈接:https://pan.baidu.com/s/1QIyusKAbusqyMl_VTkjKxg
提取碼:4rml文章來源:http://www.zghlxwxcb.cn/news/detail-791133.html
本人是一名學(xué)生,目前正在學(xué)習(xí)中,本篇文章也算是我的學(xué)習(xí)筆記,如有錯誤的話還請指正。文章來源地址http://www.zghlxwxcb.cn/news/detail-791133.html
到了這里,關(guān)于STM32控制步進(jìn)電機:基于HAL庫定時器中斷的閉環(huán)步進(jìn)電機驅(qū)動+精準(zhǔn)控制脈沖數(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!