当前位置:   article > 正文

【STM32】实战3.2—用STM32与TB6600驱动器驱动42步进电机(二)_tb6600驱动器 stm32

tb6600驱动器 stm32

目录

0 参考资料出处

1 实验预期效果

2 加减速曲线

2.1 曲线离散化处理与算法实现 

2.2 举例说明

3 软件配置

3.1 定时器配置

3.1.1 TIM8 简介与主要特性

​3.1.2 PWM相关概念回顾

3.2 串口配置 

代码编写


0 参考资料出处

参考博客:
        1、CUBEMX教程—— STM32F407实现多步进电机型加减速全过程_新时代弄潮儿的博客-CSDN博客_stm32控制步进电机

        2、STM32 HAL库 实现控制步进电机 正转、反转、T型加减速_Gerhart658的博客-CSDN博客_stm32步进电机库

        3、步进电机S型加速_新时代弄潮儿的博客-CSDN博客_步进电机s加速曲线

        4、stm32输出比较PWM_小聪不想秃头的博客-CSDN博客_stm32输出pwm最大频率

        5、; 

参考论文:

        [1] 陈祖霖,黄峰,吴靖等.步进电机S曲线调速控制研究[J].福州大学学报:自然科学版,2019,47(5):640-645.

1 实验预期效果

        完成两路步进电机的正反转加减速(通过串口控制、非可移动电源供电)。

2 加减速曲线

2.1 曲线离散化处理与算法实现 

        根据论文[1]

        离散化处理: 

         算法实现

         参数设置及计算:

2.2 举例说明

3 软件配置

3.1 定时器配置

3.1.1 TIM8 简介与主要特性

        Max timer clock:168MHz 

         TIM1 和 TIM8 简介: 

        高级控制定时器(TIM1 和 TIM8)包含一个 16 位自动重载计数器,该计数器由可编程预分 频器驱动。
        此类定时器可用于各种用途,包括测量输入信号的脉冲宽度(输入捕获),或者生成输出波形(输出比较、PWM 和带死区插入的互补 PWM)。
        使用定时器预分频器和 RCC 时钟控制器预分频器,可将脉冲宽度和波形周期从几微秒调制 到几毫秒。
        高级控制定时器(TIM1 和 TIM8)和通用 (TIMx) 定时器彼此完全独立,不共享任何资源。 

          TIM1 和 TIM8 主要特性
        TIM1 和 TIM8 定时器具有以下特性:
        ● 16 位递增、递减、递增/递减自动重载计数器。
        ● 16 位可编程预分频器,用于对计数器时钟频率进行分频(即运行时修改),分频系数
        介于 1 到 65536 之间。
        ● 多达 4 个独立通道,可用于:
                — 输入捕获
                — 输出比较
                — PWM 生成(边沿和中心对齐模式)
                — 单脉冲模式输出
        ● 带可编程死区的互补输出。
        ● 使用外部信号控制定时器且可实现多个定时器互连的同步电路。
        ● 重复计数器,用于仅在给定数目的计数器周期后更新定时器寄存器。
        ● 用于将定时器的输出信号置于复位状态或已知状态的断路输入。
        ● 发生如下事件时生成中断/DMA 请求:
                — 更新:计数器上溢/下溢、计数器初始化(通过软件或内部/外部触发)
                — 触发事件(计数器启动、停止、初始化或通过内部/外部触发计数)
                — 输入捕获
                — 输出比较
                — 断路输入
        ● 支持定位用增量(正交)编码器和霍尔传感器电路。
        ● 外部时钟触发输入或逐周期电流管理。

3.1.2 PWM相关概念回顾

【可先学习博客:stm32输出比较PWM_小聪不想秃头的博客-CSDN博客_stm32输出pwm最大频率

        (1)计数寄存器(CNT),这个寄存器存储计数器当前的计数值,可以在运行时被读取。
        (2)预分频寄存器(PSC),寄存器数值范围0至65535,对应于分频系数1至65536。 
        (3)自动重载寄存器(ARR),这个寄存器存储的是定时器计数周期。

         CubeMX参数配置:

模式描述

冻结

Frozen (used for Timing base)
CNT=CCR时,REF保持为原状态
匹配时置有效电平Active Level on matchCNT=CCR时,REF置有效电平

匹配时置无效电平

Inactive Level on match

CNT=CCR时,REF置无效电平

匹配时电平翻转

Toggle on match
CNT=CCR时,REF电平翻转

强制为无效电平

Forced Active
CNT与CCR无效,REF强制为无效电平

强制为有效电平

Forced Inactive
CNT与CCR无效,REF强制为有效电平
PWM模式1向上计数: CNT<CCR时,REF置有效电平,CNT≥CCR时, REF置无效电平
向下计数: CNT>CCR时,REF置无效电平,CNT≤CCR时, REF置有效电平
PWM模式2向上计数: CNT<CCR时,REF置无效电平,CNT≥ CCR时,REF置有效电平
向下计数: CNT>CCR时,REF置有效电平,CNT≤CCR时, REF置 无效电平

【手动设置可参看博客:stm32定时器输出PWM流程讲解_Good boy-dai的博客-CSDN博客_pwm流程图

【相关HAL库函数可参看博客:4.基于STM32CubeMX使用TIM定时器_tao_sc的博客-CSDN博客_cubemx tim设置

3.2 串口配置 

代码编写

  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2022 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 "tim.h"
  22. #include "usart.h"
  23. #include "gpio.h"
  24. #include "bsp_stepmotor.h"
  25. #include "math.h"
  26. uint32_t step_to_run[2]={86400,86400}; //uniform velocity step_total = ACCELERATED_SPEED_LENGTH*2 + step_to_run
  27. //uint16_t step_to_run[4]={6800,6800,6800,6800};
  28. float fre[ACCELERATED_SPEED_LENGTH]; //array_frequency
  29. unsigned short period[ACCELERATED_SPEED_LENGTH]; //array_ARR
  30. void SystemClock_Config(void);
  31. void CalculateSModelLine(float fre[], unsigned short period[], float len, float fre_max, float fre_min, float flexible)
  32. {
  33. int i = 0;
  34. float deno ;
  35. float melo ;
  36. float delt = fre_max - fre_min;
  37. for(i = 0; i < len; i++)
  38. {
  39. melo = flexible * (i-len/2) / (len/2);
  40. deno = 1.0f / (1 + expf(-melo)); //expf is a library function of exponential(e)
  41. fre[i] = fre_min + delt * deno;
  42. period[i] = (unsigned short)(10000000.0f / fre[i]); // 10000000 is the timer driver frequency
  43. }
  44. return ;
  45. }
  46. void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
  47. {
  48. static uint32_t count[2]={0,0};
  49. //static uint32_t count[4]={0,0,0,0};
  50. static uint32_t num_callback[2]={0,0};
  51. //static uint32_t num_callback[4]={0,0,0,0};
  52. static uint8_t status[2]={1,1};
  53. //static uint8_t status[4]={1,1,1,1};
  54. if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
  55. {
  56. num_callback[0]++;
  57. if(num_callback[0]%2==0)
  58. {
  59. switch(status[0])
  60. {
  61. case ACCEL://Acceleration
  62. __HAL_TIM_SetAutoreload(&htim8,period[count[0]]);
  63. __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_1,period[count[0]]/2);
  64. count[0]++;
  65. if(count[0]>=ACCELERATED_SPEED_LENGTH)
  66. {
  67. status[0]=3;
  68. }
  69. break;
  70. case RUN://Uniform Velocity
  71. step_to_run[0]--;
  72. if(step_to_run[0]<1)
  73. status[0]=2;
  74. break;
  75. case DECEL://Deceleration
  76. count[0]--;
  77. __HAL_TIM_SetAutoreload(&htim8,period[count[0]]);
  78. __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_1,period[count[0]]/2);
  79. if(count[0]<1)
  80. status[0]=0;
  81. break;
  82. case STOP://STOP
  83. //Close the channel
  84. TIM_CCxChannelCmd(TIM8, TIM_CHANNEL_1, TIM_CCx_DISABLE);
  85. __HAL_TIM_CLEAR_FLAG(&htim8, TIM_FLAG_CC1);
  86. break;
  87. }
  88. }
  89. }
  90. else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
  91. {
  92. num_callback[1]++;
  93. if(num_callback[1]%2==0)
  94. {
  95. switch(status[1])
  96. {
  97. case ACCEL://Acceleration
  98. __HAL_TIM_SetAutoreload(&htim8,period[count[1]]);
  99. __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_2,period[count[1]]/2);
  100. count[1]++;
  101. if(count[1]>=ACCELERATED_SPEED_LENGTH)
  102. {
  103. status[1]=3;
  104. }
  105. break;
  106. case RUN://Uniform Velocity
  107. step_to_run[1]--;
  108. if(step_to_run[1]<1)
  109. status[1]=2;
  110. break;
  111. case DECEL://Deceleration
  112. count[1]--;
  113. __HAL_TIM_SetAutoreload(&htim8,period[count[1]]);
  114. __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_2,period[count[1]]/2);
  115. if(count[1]<1)
  116. status[1]=0;
  117. break;
  118. case STOP://STOP
  119. //Close the channel
  120. TIM_CCxChannelCmd(TIM8, TIM_CHANNEL_2, TIM_CCx_DISABLE);
  121. __HAL_TIM_CLEAR_FLAG(&htim8, TIM_FLAG_CC2);
  122. break;
  123. }
  124. }
  125. }
  126. /*
  127. else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
  128. {
  129. num_callback[2]++;
  130. if(num_callback[2]%2==0)
  131. {
  132. switch(status[2])
  133. {
  134. case ACCEL://??
  135. __HAL_TIM_SetAutoreload(&htim8,period[count[2]]);
  136. __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_3,period[count[2]]/2);
  137. count[2]++;
  138. if(count[2]>=ACCELERATED_SPEED_LENGTH)
  139. {
  140. status[2]=3;
  141. }
  142. break;
  143. case RUN://??
  144. step_to_run[2]--;
  145. if(step_to_run[2]<1)
  146. status[2]=2;
  147. break;
  148. case DECEL://??
  149. count[2]--;
  150. __HAL_TIM_SetAutoreload(&htim8,period[count[2]]);
  151. __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_3,period[count[2]]/2);
  152. if(count[2]<1)
  153. status[2]=0;
  154. break;
  155. case STOP://??
  156. // ????
  157. TIM_CCxChannelCmd(TIM8, TIM_CHANNEL_3, TIM_CCx_DISABLE);
  158. __HAL_TIM_CLEAR_FLAG(&htim8, TIM_FLAG_CC3);
  159. break;
  160. }
  161. }
  162. }
  163. else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)
  164. {
  165. num_callback[3]++;
  166. if(num_callback[3]%2==0)
  167. {
  168. switch(status[3])
  169. {
  170. case ACCEL://??
  171. __HAL_TIM_SetAutoreload(&htim8,period[count[3]]);
  172. __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_4,period[count[3]]/2);
  173. count[3]++;
  174. if(count[3]>=ACCELERATED_SPEED_LENGTH)
  175. {
  176. status[3]=3;
  177. }
  178. break;
  179. case RUN://??
  180. step_to_run[3]--;
  181. if(step_to_run[3]<1)
  182. status[3]=2;
  183. break;
  184. case DECEL://??
  185. count[3]--;
  186. __HAL_TIM_SetAutoreload(&htim8,period[count[3]]);
  187. __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_4,period[count[3]]/2);
  188. if(count[3]<1)
  189. status[1]=0;
  190. break;
  191. case STOP://??
  192. // ????
  193. TIM_CCxChannelCmd(TIM8, TIM_CHANNEL_4, TIM_CCx_DISABLE);
  194. __HAL_TIM_CLEAR_FLAG(&htim8, TIM_FLAG_CC4);
  195. break;
  196. }
  197. }
  198. }
  199. */
  200. }
  201. /**
  202. * @brief The application entry point.
  203. * @retval int
  204. */
  205. int main(void)
  206. {
  207. HAL_Init();
  208. SystemClock_Config();
  209. MX_GPIO_Init();
  210. MX_TIM8_Init();
  211. MX_USART1_UART_Init();
  212. /* USER CODE BEGIN 2 */
  213. CalculateSModelLine(fre,period,ACCELERATED_SPEED_LENGTH,FRE_MAX,FRE_MIN,4); //len = ACCELERATED_SPEED_LENGTH flexible = 4(flexible:4~6)
  214. HAL_TIM_Base_Start(&htim8);
  215. HAL_TIM_OC_Start_IT(&htim8, TIM_CHANNEL_1);
  216. HAL_TIM_OC_Start_IT(&htim8, TIM_CHANNEL_2);
  217. /*
  218. HAL_TIM_OC_Start_IT(&htim8, TIM_CHANNEL_3);
  219. HAL_TIM_OC_Start_IT(&htim8, TIM_CHANNEL_4);
  220. */
  221. /* USER CODE END 2 */
  222. while (1)
  223. {
  224. }
  225. }
  226. /**
  227. * @brief System Clock Configuration
  228. * @retval None
  229. */
  230. void SystemClock_Config(void)
  231. {
  232. RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  233. RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  234. /** Configure the main internal regulator output voltage
  235. */
  236. __HAL_RCC_PWR_CLK_ENABLE();
  237. __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  238. /** Initializes the RCC Oscillators according to the specified parameters
  239. * in the RCC_OscInitTypeDef structure.
  240. */
  241. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  242. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  243. RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  244. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  245. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  246. RCC_OscInitStruct.PLL.PLLM = 8;
  247. RCC_OscInitStruct.PLL.PLLN = 168;
  248. RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  249. RCC_OscInitStruct.PLL.PLLQ = 4;
  250. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  251. {
  252. Error_Handler();
  253. }
  254. /** Initializes the CPU, AHB and APB buses clocks
  255. */
  256. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  257. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  258. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  259. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  260. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  261. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  262. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  263. {
  264. Error_Handler();
  265. }
  266. }
  267. /* USER CODE BEGIN 4 */
  268. /* USER CODE END 4 */
  269. /**
  270. * @brief This function is executed in case of error occurrence.
  271. * @retval None
  272. */
  273. void Error_Handler(void)
  274. {
  275. /* USER CODE BEGIN Error_Handler_Debug */
  276. /* User can add his own implementation to report the HAL error return state */
  277. __disable_irq();
  278. while (1)
  279. {
  280. }
  281. /* USER CODE END Error_Handler_Debug */
  282. }
  283. #ifdef USE_FULL_ASSERT
  284. /**
  285. * @brief Reports the name of the source file and the source line number
  286. * where the assert_param error has occurred.
  287. * @param file: pointer to the source file name
  288. * @param line: assert_param error line source number
  289. * @retval None
  290. */
  291. void assert_failed(uint8_t *file, uint32_t line)
  292. {
  293. /* USER CODE BEGIN 6 */
  294. /* User can add his own implementation to report the file name and line number,
  295. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  296. /* USER CODE END 6 */
  297. }
  298. #endif /* USE_FULL_ASSERT */
  1. #ifndef __bsp_stepmotor_H
  2. #define __bsp_stepmotor_H
  3. #include "tim.h"
  4. #ifdef __cplusplus
  5. extern "C" {
  6. #endif
  7. #define S_ACCEL 1
  8. #define T_ACCEL 0
  9. /* S????? */
  10. #define ACCELERATED_SPEED_LENGTH 3000
  11. #define FRE_MIN 500
  12. #define FRE_MAX 100000
  13. #define STOP 0
  14. #define ACCEL 1
  15. #define DECEL 2
  16. #define RUN 3
  17. #endif
  18. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

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

闽ICP备14008679号