当前位置:   article > 正文

STM32F103C8T6+TB6612FNG驱动未知型号步进电机调试(已完)_tb6612 驱动步进电机

tb6612 驱动步进电机

简介:

软件开发环境:window11pro ,STM32CubeMX,  Keil5_armv5

调试器: ST_LINK V2 

硬件:

STM32F103C8T6最小开发板一块,

未知名两相四线步进电机一个,

TB6612驱动板一个,

杜邦线若干,

LED灯珠4个。(前期测试输出信号)

结果:已经调试出四拍单步驱动,运行结果正常,只是抖动比较大。

一。电机

1.电机的理论知识

a.步距角:

控制系统发给电机一个脉冲,电机转动的角度。

b.步距角的计算:

步距角的计算方法主要取决于电机的类型和参数。对于步进电机,步距角可以通过以下公式计算:123

  • 步距角=360°/每圈脉冲数。
  • 步距角=360°/步进电机的步数。(步数=拍数?)

对于特定类型的电机,如五相步进电机,步距角可以通过以下公式计算:4

  • 步距角=360°/步数。

对于三相异步电动机,步距角可以通过以下公式计算:5

  • 步距角=360°/(电机极数×3)。

其中,每圈脉冲数、步进电机的步数和电机极数都是特定于电机的参数。此外,某些电机可能会直接在产品技术规格中提供步距角的大小,这样可以直接查阅而无需计算。

2.未知电机拆解图

pos机打印机拆下来的步进电机。

对此了解不多,如下为电机剖解图:

两块线圈中间是两块铁,具体内部结构比较复杂,和塑胶交合在一起详情如下:

分上下两层,每一层有5个突出的铁块

转子是两块圆形磁铁

经测试,这块磁铁不是一体的,环周刚好有五对磁极,与上面的五个铁片对应。

判定为双极性整步驱动

3.未知电机参数

步距角取决于电机上的磁极总数。
步距角的公式如下所示:

步距角=360度/N,其中N=(NPH×PH)

  • NPH:每相的磁极数
  • PH:相数
  • N:各项的磁极总数

磁极齿数:线圈内嵌齿数5*2+外壳齿数5*2 = 20

在此我的理解齿数就是极数。根据步距角计算公式:步距角=360/(极数*运行拍数)计算该电机的步距角如下:

四拍整步的步距角:360/(20*4)=4.5

八拍半步的步距角:360/(20*8)=2.25

二。驱动板

1.电机引脚输出配置

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博客

2.驱动方式

四拍单步:

正转步序AIN1AIN2BIN1BIN2
11000
20100
30010
40001

三。电路引脚与接线

MCUTB6612
PA1

AIN2

PA2AIN1
PA3BIN1
PA4BIN2
PA5STBY
PA6PWMA
PA7PWMB
3.3VCC
GNDGND

1.TB6612引脚图

2. MCU与驱动板连线

四。STM32CubeMX工程配置

1.GPIO配置

2.sys配置

3.TIM配置

4.时钟配置

5.工程配置

五。KEIL工程代码

1.main.c

  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2024 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "main.h"
  21. #include "tb6612.h"
  22. #define LED_PIN GPIO_PIN_13
  23. void SystemClock_Config(void);
  24. static void LED_Init(void);
  25. /**
  26. * @brief The application entry point.
  27. * @retval int
  28. */
  29. int main(void)
  30. {
  31. /* MCU Configuration--------------------------------------------------------*/
  32. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  33. HAL_Init();
  34. /* Configure the system clock */
  35. SystemClock_Config();
  36. /* Initialize all configured peripherals */
  37. LED_Init();
  38. STEP_MOTOR_init();
  39. int delay_time = 1;
  40. //STEP_MOTOR_Run(500,20,MOTOR_MODE_FORWORD, delay_time);
  41. while (1)
  42. {
  43. /* USER CODE END WHILE */
  44. STEP_MOTOR_Run_Step4(10,10);
  45. delay_time+=2;
  46. //STEP_MOTOR_Run(100,50,MOTOR_MODE_FORWORD, delay_time++);
  47. //STEP_MOTOR_Run(1,50,MOTOR_MODE_FORWORD);
  48. HAL_GPIO_WritePin(GPIOC,LED_PIN,GPIO_PIN_SET); // close led
  49. HAL_Delay(500);
  50. HAL_GPIO_WritePin(GPIOC,LED_PIN,GPIO_PIN_RESET); //OPEN LED
  51. HAL_Delay(500);
  52. if(delay_time >100)
  53. break;
  54. }
  55. }
  56. /**
  57. * @brief System Clock Configuration
  58. * @retval None
  59. */
  60. void SystemClock_Config(void)
  61. {
  62. RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  63. RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  64. /** Initializes the RCC Oscillators according to the specified parameters
  65. * in the RCC_OscInitTypeDef structure.
  66. */
  67. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  68. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  69. RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  70. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  71. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  72. {
  73. Error_Handler();
  74. }
  75. /** Initializes the CPU, AHB and APB buses clocks
  76. */
  77. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  78. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  79. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  80. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  81. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  82. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  83. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  84. {
  85. Error_Handler();
  86. }
  87. }
  88. /* USER CODE BEGIN 4 */
  89. void LED_Init(void)
  90. {
  91. GPIO_InitTypeDef GPIO_InitStruct = {0};
  92. /* GPIO Ports Clock Enable */
  93. __HAL_RCC_GPIOC_CLK_ENABLE();
  94. /*Configure GPIO pin Output Level */
  95. HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
  96. /*Configure GPIO pin : PC13 */
  97. GPIO_InitStruct.Pin = GPIO_PIN_13;
  98. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  99. GPIO_InitStruct.Pull = GPIO_PULLUP;
  100. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  101. HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  102. }
  103. /* USER CODE END 4 */
  104. #ifdef USE_FULL_ASSERT
  105. /**
  106. * @brief Reports the name of the source file and the source line number
  107. * where the assert_param error has occurred.
  108. * @param file: pointer to the source file name
  109. * @param line: assert_param error line source number
  110. * @retval None
  111. */
  112. void assert_failed(uint8_t *file, uint32_t line)
  113. {
  114. /* USER CODE BEGIN 6 */
  115. /* User can add his own implementation to report the file name and line number,
  116. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  117. /* USER CODE END 6 */
  118. }
  119. #endif /* USE_FULL_ASSERT */

2.tb6612.h

  1. #ifndef __TB6612_H__
  2. #define __TB6612_H__
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. #include "stm32f1xx_hal.h"
  7. /*
  8. motor control pin
  9. */
  10. #define AIN1 GPIO_PIN_1
  11. #define AIN2 GPIO_PIN_2
  12. #define BIN1 GPIO_PIN_3
  13. #define BIN2 GPIO_PIN_4
  14. #define STBY GPIO_PIN_5
  15. #define MOTOR_MODE_FORWORD 0
  16. #define MOTOR_MODE_REVERSE 1
  17. #define MOTOR_MODE_BRAKE 2
  18. void STEP_MOTOR_init(void);
  19. void STEP_MOTOR_SetSpeed(int speed);
  20. void STEP_MOTOR_SetMode(int mode);
  21. void STEP_MOTOR_Step4(int step, int interval);
  22. void STEP_MOTOR_Run(int step, int speed, int mode, int arg);
  23. void STEP_MOTOR_Run_Step4(int steps,int interval);
  24. void STEP_MOTOR_Stop(void);
  25. void STEP_MOTOR_Brake(void);
  26. void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
  27. void Error_Handler(void);
  28. #ifdef __cplusplus
  29. }
  30. #endif
  31. #endif

 3.tb6612.c

  1. #include "tb6612.h"
  2. /* Private variables ---------------------------------------------------------*/
  3. static TIM_HandleTypeDef g_htim3;
  4. static int g_isBrake;
  5. /* USER CODE BEGIN PV */
  6. static TIM_OC_InitTypeDef gConfigOC = {0};
  7. void STEP_MOTOR_init(void)
  8. {
  9. /* USER CODE BEGIN TIM3_Init 0 */
  10. GPIO_InitTypeDef GPIO_InitStruct = {0};
  11. /* GPIO Ports Clock Enable */
  12. __HAL_RCC_GPIOA_CLK_ENABLE();
  13. /*Configure GPIO pin Output Level */
  14. HAL_GPIO_WritePin(GPIOA, AIN1|AIN2|BIN1|BIN2|STBY, GPIO_PIN_RESET);
  15. /*Configure GPIO pins : PA1 PA2 PA3 PA4 PA5 */
  16. GPIO_InitStruct.Pin = AIN1|AIN2|BIN1|BIN2|STBY;
  17. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  18. GPIO_InitStruct.Pull = GPIO_PULLUP;
  19. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  20. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  21. /* USER CODE END TIM3_Init 0 */
  22. TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  23. TIM_MasterConfigTypeDef sMasterConfig = {0};
  24. //TIM_OC_InitTypeDef sConfigOC = {0};
  25. /* USER CODE BEGIN TIM3_Init 1 */
  26. /* USER CODE END TIM3_Init 1 */
  27. g_htim3.Instance = TIM3;
  28. //g_htim3.Init.Prescaler = 16;
  29. g_htim3.Init.Prescaler = 8-1;
  30. g_htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  31. //g_htim3.Init.Period = 65535;
  32. g_htim3.Init.Period = 10-1; //TIMx->ARR
  33. g_htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  34. g_htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  35. if (HAL_TIM_Base_Init(&g_htim3) != HAL_OK)
  36. {
  37. Error_Handler();
  38. }
  39. sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  40. if (HAL_TIM_ConfigClockSource(&g_htim3, &sClockSourceConfig) != HAL_OK)
  41. {
  42. Error_Handler();
  43. }
  44. if (HAL_TIM_PWM_Init(&g_htim3) != HAL_OK)
  45. {
  46. Error_Handler();
  47. }
  48. sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  49. sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  50. if (HAL_TIMEx_MasterConfigSynchronization(&g_htim3, &sMasterConfig) != HAL_OK)
  51. {
  52. Error_Handler();
  53. }
  54. gConfigOC.OCMode = TIM_OCMODE_PWM1;
  55. gConfigOC.Pulse = 0;
  56. gConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  57. gConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  58. if (HAL_TIM_PWM_ConfigChannel(&g_htim3, &gConfigOC, TIM_CHANNEL_1) != HAL_OK)
  59. {
  60. Error_Handler();
  61. }
  62. if (HAL_TIM_PWM_ConfigChannel(&g_htim3, &gConfigOC, TIM_CHANNEL_2) != HAL_OK)
  63. {
  64. Error_Handler();
  65. }
  66. /* USER CODE BEGIN TIM3_Init 2 */
  67. /* USER CODE END TIM3_Init 2 */
  68. HAL_TIM_MspPostInit(&g_htim3);
  69. HAL_GPIO_WritePin(GPIOA,STBY,GPIO_PIN_SET); // enable MOTOR
  70. g_isBrake = 0;
  71. HAL_TIM_PWM_Start(&g_htim3,TIM_CHANNEL_1);
  72. HAL_TIM_PWM_Start(&g_htim3,TIM_CHANNEL_2);
  73. }
  74. void STEP_MOTOR_SetSpeed(int speed)
  75. {
  76. gConfigOC.Pulse = speed;
  77. if (HAL_TIM_PWM_ConfigChannel(&g_htim3, &gConfigOC, TIM_CHANNEL_1) != HAL_OK)//TIMx->CCR1
  78. {
  79. Error_Handler();
  80. }
  81. if (HAL_TIM_PWM_ConfigChannel(&g_htim3, &gConfigOC, TIM_CHANNEL_2) != HAL_OK)//TIMx->CCR2
  82. {
  83. Error_Handler();
  84. }
  85. }
  86. void STEP_MOTOR_SetMode(int mode)
  87. {
  88. switch(mode)
  89. {
  90. case MOTOR_MODE_FORWORD:
  91. HAL_GPIO_WritePin(GPIOA, AIN1|BIN1, GPIO_PIN_RESET);
  92. HAL_GPIO_WritePin(GPIOA, AIN2|BIN2, GPIO_PIN_SET);
  93. break;
  94. case MOTOR_MODE_REVERSE:
  95. HAL_GPIO_WritePin(GPIOA, AIN1|BIN1, GPIO_PIN_SET);
  96. HAL_GPIO_WritePin(GPIOA, AIN2|BIN2, GPIO_PIN_RESET);
  97. break;
  98. case MOTOR_MODE_BRAKE:
  99. HAL_GPIO_WritePin(GPIOA, AIN1|AIN2|BIN1|BIN2, GPIO_PIN_SET);
  100. }
  101. }
  102. //四拍单步驱动
  103. void STEP_MOTOR_Step4(int step, int interval)
  104. {
  105. switch(step)
  106. {
  107. case 0:
  108. HAL_GPIO_WritePin(GPIOA, AIN2|BIN1|BIN2, GPIO_PIN_RESET);
  109. HAL_GPIO_WritePin(GPIOA, AIN1, GPIO_PIN_SET);
  110. break;
  111. case 1:
  112. HAL_GPIO_WritePin(GPIOA, AIN1|BIN1|BIN2, GPIO_PIN_RESET);
  113. HAL_GPIO_WritePin(GPIOA, AIN2, GPIO_PIN_SET);
  114. break;
  115. case 2:
  116. HAL_GPIO_WritePin(GPIOA, AIN1|AIN2|BIN2, GPIO_PIN_RESET);
  117. HAL_GPIO_WritePin(GPIOA, BIN1, GPIO_PIN_SET);
  118. break;
  119. case 3:
  120. HAL_GPIO_WritePin(GPIOA, AIN1|AIN2|BIN1, GPIO_PIN_RESET);
  121. HAL_GPIO_WritePin(GPIOA, BIN2, GPIO_PIN_SET);
  122. break;
  123. default:
  124. break;
  125. }
  126. HAL_Delay(interval);
  127. STEP_MOTOR_Stop();
  128. }
  129. void STEP_MOTOR_Run(int steps, int speed, int mode, int arg)
  130. {
  131. int i;
  132. if(0)
  133. {
  134. HAL_GPIO_WritePin(GPIOA,STBY,GPIO_PIN_SET); // enable MOTOR
  135. g_isBrake = 0;
  136. }
  137. for(i = 0; i<steps; i++)
  138. {
  139. STEP_MOTOR_SetMode(mode);
  140. STEP_MOTOR_SetSpeed(speed);
  141. HAL_Delay(arg);
  142. }
  143. STEP_MOTOR_SetSpeed(0);
  144. //STEP_MOTOR_Brake();
  145. }
  146. void STEP_MOTOR_Run_Step4(int steps,int interval)
  147. {
  148. int i;
  149. for(i = 0; i < steps; i++)
  150. {
  151. g_step++;
  152. if(g_step>3)g_step=0;
  153. STEP_MOTOR_Step4(g_step, interval);
  154. }
  155. }
  156. void STEP_MOTOR_Stop(void)
  157. {
  158. HAL_GPIO_WritePin(GPIOA, AIN1|AIN2|BIN1|BIN2, GPIO_PIN_RESET);
  159. }
  160. void STEP_MOTOR_Brake(void)
  161. {
  162. HAL_GPIO_WritePin(GPIOA,STBY,GPIO_PIN_RESET); // disable MOTOR
  163. g_isBrake = 1;
  164. }
  165. /**
  166. * @brief This function is executed in case of error occurrence.
  167. * @retval None
  168. */
  169. void Error_Handler(void)
  170. {
  171. /* USER CODE BEGIN Error_Handler_Debug */
  172. /* User can add his own implementation to report the HAL error return state */
  173. __disable_irq();
  174. while (1)
  175. {
  176. }
  177. /* USER CODE END Error_Handler_Debug */
  178. }

六.调试曾经出现的问题:

电机不转,只有抖动,为了防止电机过热,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博客

TB6612FNG模块使用说明-CSDN博客

stm32如何控制TB6612步进电机 - CSDN文库

Stm32-使用TB6612驱动电机及编码器测速-CSDN博客

STM32_HAL库—PWM输出_stm32 hal pwm-CSDN博客

STM32通过TB6612FNG模块驱动电机_tb6612 步进电机-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/576499
推荐阅读
相关标签
  

闽ICP备14008679号