赞
踩
软件开发环境:window11pro ,STM32CubeMX, Keil5_armv5
调试器: ST_LINK V2
硬件:
STM32F103C8T6最小开发板一块,
未知名两相四线步进电机一个,
TB6612驱动板一个,
杜邦线若干,
LED灯珠4个。(前期测试输出信号)
结果:已经调试出四拍单步驱动,运行结果正常,只是抖动比较大。
a.步距角:
控制系统发给电机一个脉冲,电机转动的角度。
b.步距角的计算:
步距角的计算方法主要取决于电机的类型和参数。对于步进电机,步距角可以通过以下公式计算:123
对于特定类型的电机,如五相步进电机,步距角可以通过以下公式计算:4
对于三相异步电动机,步距角可以通过以下公式计算:5
其中,每圈脉冲数、步进电机的步数和电机极数都是特定于电机的参数。此外,某些电机可能会直接在产品技术规格中提供步距角的大小,这样可以直接查阅而无需计算。
pos机打印机拆下来的步进电机。
对此了解不多,如下为电机剖解图:
两块线圈中间是两块铁,具体内部结构比较复杂,和塑胶交合在一起详情如下:
分上下两层,每一层有5个突出的铁块
转子是两块圆形磁铁
经测试,这块磁铁不是一体的,环周刚好有五对磁极,与上面的五个铁片对应。
判定为双极性整步驱动
步距角取决于电机上的磁极总数。
步距角的公式如下所示:
步距角=360度/N,其中N=(NPH×PH)
磁极齿数:线圈内嵌齿数5*2+外壳齿数5*2 = 20
在此我的理解齿数就是极数。根据步距角计算公式:步距角=360/(极数*运行拍数)计算该电机的步距角如下:
四拍整步的步距角:360/(20*4)=4.5
八拍半步的步距角:360/(20*8)=2.25
TB6612FNG的主要引脚功能:
(1)AINl/AIN2、BIN1/BIN2、PWMA/PWMB为控制信号输入端;
(2)AO1/A02、B01/B02为2路电机控制输出端;
(3)STBY为正常工作/待机状态控制引脚;
(4)VM(3~13.5 V)和VCC(2.7~5.5 V)分别为电机驱动电压输入和逻辑电平输入端
上图和部分文字引用了博友的:TB6612FNG模块使用说明-CSDN博客
四拍单步:
正转步序 | AIN1 | AIN2 | BIN1 | BIN2 |
1 | 1 | 0 | 0 | 0 |
2 | 0 | 1 | 0 | 0 |
3 | 0 | 0 | 1 | 0 |
4 | 0 | 0 | 0 | 1 |
MCU | TB6612 |
PA1 | AIN2 |
PA2 | AIN1 |
PA3 | BIN1 |
PA4 | BIN2 |
PA5 | STBY |
PA6 | PWMA |
PA7 | PWMB |
3.3 | VCC |
GND | GND |
- /* USER CODE BEGIN Header */
- /**
- ******************************************************************************
- * @file : main.c
- * @brief : Main program body
- ******************************************************************************
- * @attention
- *
- * Copyright (c) 2024 STMicroelectronics.
- * All rights reserved.
- *
- * This software is licensed under terms that can be found in the LICENSE file
- * in the root directory of this software component.
- * If no LICENSE file comes with this software, it is provided AS-IS.
- *
- ******************************************************************************
- */
- /* USER CODE END Header */
- /* Includes ------------------------------------------------------------------*/
- #include "main.h"
- #include "tb6612.h"
-
- #define LED_PIN GPIO_PIN_13
-
- void SystemClock_Config(void);
- static void LED_Init(void);
-
- /**
- * @brief The application entry point.
- * @retval int
- */
- int main(void)
- {
- /* MCU Configuration--------------------------------------------------------*/
-
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
- HAL_Init();
-
- /* Configure the system clock */
- SystemClock_Config();
-
- /* Initialize all configured peripherals */
- LED_Init();
- STEP_MOTOR_init();
-
- int delay_time = 1;
- //STEP_MOTOR_Run(500,20,MOTOR_MODE_FORWORD, delay_time);
- while (1)
- {
- /* USER CODE END WHILE */
-
- STEP_MOTOR_Run_Step4(10,10);
- delay_time+=2;
- //STEP_MOTOR_Run(100,50,MOTOR_MODE_FORWORD, delay_time++);
- //STEP_MOTOR_Run(1,50,MOTOR_MODE_FORWORD);
- HAL_GPIO_WritePin(GPIOC,LED_PIN,GPIO_PIN_SET); // close led
- HAL_Delay(500);
- HAL_GPIO_WritePin(GPIOC,LED_PIN,GPIO_PIN_RESET); //OPEN LED
- HAL_Delay(500);
- if(delay_time >100)
- break;
- }
- }
-
- /**
- * @brief System Clock Configuration
- * @retval None
- */
- void SystemClock_Config(void)
- {
- RCC_OscInitTypeDef RCC_OscInitStruct = {0};
- RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
-
- /** Initializes the RCC Oscillators according to the specified parameters
- * in the RCC_OscInitTypeDef structure.
- */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
- RCC_OscInitStruct.HSIState = RCC_HSI_ON;
- RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
- {
- Error_Handler();
- }
-
- /** Initializes the CPU, AHB and APB buses clocks
- */
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
- |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
-
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
- {
- Error_Handler();
- }
- }
-
- /* USER CODE BEGIN 4 */
- void LED_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
-
- /* GPIO Ports Clock Enable */
-
- __HAL_RCC_GPIOC_CLK_ENABLE();
- /*Configure GPIO pin Output Level */
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
- /*Configure GPIO pin : PC13 */
- GPIO_InitStruct.Pin = GPIO_PIN_13;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
- HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
- }
- /* USER CODE END 4 */
-
-
- #ifdef USE_FULL_ASSERT
- /**
- * @brief Reports the name of the source file and the source line number
- * where the assert_param error has occurred.
- * @param file: pointer to the source file name
- * @param line: assert_param error line source number
- * @retval None
- */
- void assert_failed(uint8_t *file, uint32_t line)
- {
- /* USER CODE BEGIN 6 */
- /* User can add his own implementation to report the file name and line number,
- ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
- /* USER CODE END 6 */
- }
- #endif /* USE_FULL_ASSERT */
- #ifndef __TB6612_H__
- #define __TB6612_H__
-
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- #include "stm32f1xx_hal.h"
-
- /*
- motor control pin
- */
-
- #define AIN1 GPIO_PIN_1
- #define AIN2 GPIO_PIN_2
- #define BIN1 GPIO_PIN_3
- #define BIN2 GPIO_PIN_4
- #define STBY GPIO_PIN_5
-
-
- #define MOTOR_MODE_FORWORD 0
- #define MOTOR_MODE_REVERSE 1
- #define MOTOR_MODE_BRAKE 2
-
-
- void STEP_MOTOR_init(void);
- void STEP_MOTOR_SetSpeed(int speed);
- void STEP_MOTOR_SetMode(int mode);
- void STEP_MOTOR_Step4(int step, int interval);
- void STEP_MOTOR_Run(int step, int speed, int mode, int arg);
- void STEP_MOTOR_Run_Step4(int steps,int interval);
- void STEP_MOTOR_Stop(void);
- void STEP_MOTOR_Brake(void);
-
-
- void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
- void Error_Handler(void);
-
-
- #ifdef __cplusplus
- }
- #endif
-
- #endif
-
-
-
-
-
- #include "tb6612.h"
-
-
- /* Private variables ---------------------------------------------------------*/
- static TIM_HandleTypeDef g_htim3;
- static int g_isBrake;
- /* USER CODE BEGIN PV */
-
- static TIM_OC_InitTypeDef gConfigOC = {0};
-
-
- void STEP_MOTOR_init(void)
- {
-
- /* USER CODE BEGIN TIM3_Init 0 */
- GPIO_InitTypeDef GPIO_InitStruct = {0};
-
- /* GPIO Ports Clock Enable */
- __HAL_RCC_GPIOA_CLK_ENABLE();
-
- /*Configure GPIO pin Output Level */
- HAL_GPIO_WritePin(GPIOA, AIN1|AIN2|BIN1|BIN2|STBY, GPIO_PIN_RESET);
-
- /*Configure GPIO pins : PA1 PA2 PA3 PA4 PA5 */
- GPIO_InitStruct.Pin = AIN1|AIN2|BIN1|BIN2|STBY;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
- /* USER CODE END TIM3_Init 0 */
-
- TIM_ClockConfigTypeDef sClockSourceConfig = {0};
- TIM_MasterConfigTypeDef sMasterConfig = {0};
- //TIM_OC_InitTypeDef sConfigOC = {0};
-
- /* USER CODE BEGIN TIM3_Init 1 */
-
- /* USER CODE END TIM3_Init 1 */
-
- g_htim3.Instance = TIM3;
- //g_htim3.Init.Prescaler = 16;
- g_htim3.Init.Prescaler = 8-1;
- g_htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
- //g_htim3.Init.Period = 65535;
- g_htim3.Init.Period = 10-1; //TIMx->ARR
- g_htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
- g_htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
- if (HAL_TIM_Base_Init(&g_htim3) != HAL_OK)
- {
- Error_Handler();
- }
- sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
- if (HAL_TIM_ConfigClockSource(&g_htim3, &sClockSourceConfig) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_TIM_PWM_Init(&g_htim3) != HAL_OK)
- {
- Error_Handler();
- }
- sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
- sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
- if (HAL_TIMEx_MasterConfigSynchronization(&g_htim3, &sMasterConfig) != HAL_OK)
- {
- Error_Handler();
- }
- gConfigOC.OCMode = TIM_OCMODE_PWM1;
- gConfigOC.Pulse = 0;
- gConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
- gConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
- if (HAL_TIM_PWM_ConfigChannel(&g_htim3, &gConfigOC, TIM_CHANNEL_1) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_TIM_PWM_ConfigChannel(&g_htim3, &gConfigOC, TIM_CHANNEL_2) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN TIM3_Init 2 */
- /* USER CODE END TIM3_Init 2 */
- HAL_TIM_MspPostInit(&g_htim3);
-
- HAL_GPIO_WritePin(GPIOA,STBY,GPIO_PIN_SET); // enable MOTOR
- g_isBrake = 0;
-
- HAL_TIM_PWM_Start(&g_htim3,TIM_CHANNEL_1);
- HAL_TIM_PWM_Start(&g_htim3,TIM_CHANNEL_2);
-
- }
- void STEP_MOTOR_SetSpeed(int speed)
- {
- gConfigOC.Pulse = speed;
- if (HAL_TIM_PWM_ConfigChannel(&g_htim3, &gConfigOC, TIM_CHANNEL_1) != HAL_OK)//TIMx->CCR1
- {
- Error_Handler();
- }
- if (HAL_TIM_PWM_ConfigChannel(&g_htim3, &gConfigOC, TIM_CHANNEL_2) != HAL_OK)//TIMx->CCR2
- {
- Error_Handler();
- }
- }
- void STEP_MOTOR_SetMode(int mode)
- {
- switch(mode)
- {
- case MOTOR_MODE_FORWORD:
- HAL_GPIO_WritePin(GPIOA, AIN1|BIN1, GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOA, AIN2|BIN2, GPIO_PIN_SET);
- break;
- case MOTOR_MODE_REVERSE:
- HAL_GPIO_WritePin(GPIOA, AIN1|BIN1, GPIO_PIN_SET);
- HAL_GPIO_WritePin(GPIOA, AIN2|BIN2, GPIO_PIN_RESET);
- break;
- case MOTOR_MODE_BRAKE:
- HAL_GPIO_WritePin(GPIOA, AIN1|AIN2|BIN1|BIN2, GPIO_PIN_SET);
-
- }
- }
- //四拍单步驱动
- void STEP_MOTOR_Step4(int step, int interval)
- {
- switch(step)
- {
- case 0:
- HAL_GPIO_WritePin(GPIOA, AIN2|BIN1|BIN2, GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOA, AIN1, GPIO_PIN_SET);
- break;
- case 1:
- HAL_GPIO_WritePin(GPIOA, AIN1|BIN1|BIN2, GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOA, AIN2, GPIO_PIN_SET);
- break;
- case 2:
- HAL_GPIO_WritePin(GPIOA, AIN1|AIN2|BIN2, GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOA, BIN1, GPIO_PIN_SET);
- break;
- case 3:
- HAL_GPIO_WritePin(GPIOA, AIN1|AIN2|BIN1, GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOA, BIN2, GPIO_PIN_SET);
- break;
- default:
- break;
- }
- HAL_Delay(interval);
- STEP_MOTOR_Stop();
- }
- void STEP_MOTOR_Run(int steps, int speed, int mode, int arg)
- {
- int i;
- if(0)
- {
- HAL_GPIO_WritePin(GPIOA,STBY,GPIO_PIN_SET); // enable MOTOR
- g_isBrake = 0;
- }
- for(i = 0; i<steps; i++)
- {
- STEP_MOTOR_SetMode(mode);
- STEP_MOTOR_SetSpeed(speed);
- HAL_Delay(arg);
- }
- STEP_MOTOR_SetSpeed(0);
- //STEP_MOTOR_Brake();
-
- }
- void STEP_MOTOR_Run_Step4(int steps,int interval)
- {
- int i;
- for(i = 0; i < steps; i++)
- {
- g_step++;
- if(g_step>3)g_step=0;
- STEP_MOTOR_Step4(g_step, interval);
- }
- }
- void STEP_MOTOR_Stop(void)
- {
- HAL_GPIO_WritePin(GPIOA, AIN1|AIN2|BIN1|BIN2, GPIO_PIN_RESET);
- }
-
- void STEP_MOTOR_Brake(void)
- {
- HAL_GPIO_WritePin(GPIOA,STBY,GPIO_PIN_RESET); // disable MOTOR
- g_isBrake = 1;
- }
-
-
-
- /**
- * @brief This function is executed in case of error occurrence.
- * @retval None
- */
- void Error_Handler(void)
- {
- /* USER CODE BEGIN Error_Handler_Debug */
- /* User can add his own implementation to report the HAL error return state */
- __disable_irq();
- while (1)
- {
- }
- /* USER CODE END Error_Handler_Debug */
- }
电机不转,只有抖动,为了防止电机过热,main函数里面没有把步进放进while循环。为了方便调试步进延时,我在
STEP_MOTOR_Run(500,20,MOTOR_MODE_FORWORD, delay_time);
添加了最后的那个参数。调试逻辑:把STEP_MOTOR_Run放进while里面调试,每循环一次增加一次延时,观察电机是否转动。
延时设到了最高100ms依然没有转动,电机只是发出电流震动声。
尝试过如下动作:
1.调换过一次电机线
2.电机驱动电源5V换到12V依然存在。
使用STEP_MOTOR_Run函数的方法是错误的,AB两组输出都是同时通电,并且PWM都是一样的,所以只能听见电流声,电机里面的电磁场还是平衡的,是无法转动的。在此记录一下这个坑。
步进电机 | 东芝半导体&存储产品中国官网 (toshiba-semicon-storage.com)
【资料分享】STM32配置TB6612驱动程序详解_stby引脚-CSDN博客
STM32驱动步进电机(原理、程序、解决电机只震动不转动问题)-CSDN博客
Stm32-使用TB6612驱动电机及编码器测速-CSDN博客
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。