STM32+TMC2209控制步进电机正反转。

STM32F103ZET6+TMC2209控制步进电机正反转

  • 1. 步进电机介绍
  • 2 驱动器TMC2209介绍
    • 2.1 引脚图及其功能
    • 2.2 细分介绍
    • 2.3 TMC控制驱动器接法
  • 3 控制器介绍
    • 3.1 确定控制引脚
    • 3.2 UBEMX配置
      • 3.2.1 GPIO配置
      • 3.2.2 NVIC配置
      • 3.2.3 RCC配置
      • 3.2.4 SYS配置
      • 3.2.5 USRAT2配置(PS:没用上可以跳过)
      • 3.2.6 保存并生成工程
  • 4 代码部分

1. 步进电机介绍

  • 本实验采用2项步进电机,电机只有2项,A+\A-\B+\B-。
  • 电机步距角1.8°
    在这里插入图片描述

2 驱动器TMC2209介绍

2.1 引脚图及其功能

在这里插入图片描述
在这里插入图片描述

2.2 细分介绍

在这里插入图片描述

  • 8细分控制精度=1.8°/8=0.225°,电机转一周需要1600个脉冲。
  • 16细分控制精度=1.8°/16=0.1125°,电机转一周需要3200个脉冲。
  • 32细分控制精度=1.8°/32=0.05625°,电机转一周需要6400个脉冲。
  • 64细分控制精度=1.8°/64=0.0140625°,电机转一周需要12800个脉冲。
    满足绝大多数精度场景,如低精度机床、家电、3D打印等。

2.3 TMC控制驱动器接法

这里只需要使用13个引脚
EN:控制器使能引脚,接GND, 电机才能工作。
DIR:控制方向,这个引脚的高\低电平分别控制正\反转
VM:给电机的电压(4.75—>28VDC),可以选择24V电源供电,没24V直流电源可以在网上买一个。电机电压5V可能导致电机丢步,尽量选择24V的直流电源。
GND:VM的GND
STEP: 控制脉冲,一个占空比为50%高电平、一个占空比50%的低电平为一个脉冲。
MS1\MS2: 控制细分,参考2.2节
VDD: 给TMC2209供电,供+5V供电。
GND: VDD的GND
A1\A2\B1\B2: 参考第1节的电机。

3 控制器介绍

  • STM32F103ZET6(正点原子V3)

3.1 确定控制引脚

  • 将下面的引脚与2.3的引脚连接,具体位置如下图红圈位置。
    DIR: PF12/FSMC_A6
    STEP: PG1/FSMC_A11
    EN: PF14/FSMC_A8
    MS1: PF15/FSMC_A9
    MS2: PG0/FSMC_VA10
    VDD: 见下图红圈位置
    GND: 见下图红圈位置
    在这里插入图片描述

3.2 UBEMX配置

3.2.1 GPIO配置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2.2 NVIC配置

在这里插入图片描述在这里插入图片描述

3.2.3 RCC配置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2.4 SYS配置

  • 用的ST-link V2的仿真器,选择下面这个:
    在这里插入图片描述

3.2.5 USRAT2配置(PS:没用上可以跳过)

在这里插入图片描述

3.2.6 保存并生成工程

在这里插入图片描述

4 代码部分

主要修改main.c,其他的不用管。

/* 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 "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
// UART_HandleTypeDef huart2a;
/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
// static void MX_GPIO_Init(void);
// static void MX_USART2_UART_Init(void);
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void SubdivisionSet(uint8_t i);												//细分设置
void MoveStep(uint8_t DIR_Flag,uint32_t Step);				//电机移动多少步
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
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();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
	SubdivisionSet(64);													//细分设置为64
	HAL_GPIO_WritePin(GPIOG,STEP_Pin, GPIO_PIN_SET);
																							//STEP设置为高

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
		MoveStep(1,12800*10);													//正转一圈
		HAL_Delay(2000);														//延时2S
		MoveStep(0,12800*10);													//反转一圈
		HAL_Delay(2000);														//延时2S
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief SubdivisionSet
	* 细分设置
  * @retval None
  */
void SubdivisionSet(uint8_t i)
{
	if(i==8)
	{
		HAL_GPIO_WritePin(GPIOG,MS2_Pin, GPIO_PIN_RESET);
		HAL_GPIO_WritePin(GPIOF,MS1_Pin, GPIO_PIN_RESET);
	}
	else 	if(i==32)
	{
		HAL_GPIO_WritePin(GPIOG,MS2_Pin, GPIO_PIN_RESET);
		HAL_GPIO_WritePin(GPIOF,MS1_Pin, GPIO_PIN_SET);
	}
	else 	if(i==64)
	{
		HAL_GPIO_WritePin(GPIOG,MS2_Pin, GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOF,MS1_Pin, GPIO_PIN_RESET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOG,MS2_Pin, GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOF,MS1_Pin, GPIO_PIN_SET);
	}
}
/**
  * @brief DelayNop
	* 延时
  * @retval None
  */
void DelayNop(uint8_t i)
{
	uint32_t 	j;
	do
	{
		for(j=0;j<100;j++){;}
	}while(i--);
}
/**
  * @brief MoveStep
	* 电机移动多少步
  * @retval None
  */
void MoveStep(uint8_t DIR_Flag,uint32_t Step)
{
	//uint8_t		j=200;
	uint32_t		j=1;
	uint32_t 	i;
	
	//电机使能
	HAL_GPIO_WritePin(GPIOF,EN_Pin, GPIO_PIN_RESET);
	
	if(DIR_Flag)
	{
		//正转
		HAL_GPIO_WritePin(GPIOF,DIR_Pin, GPIO_PIN_SET);
	}
	else
	{
		//反转
		HAL_GPIO_WritePin(GPIOF,DIR_Pin, GPIO_PIN_RESET);
	}
	
	for(i=0;i<Step;i++)
	{
		//发送脉冲
		HAL_GPIO_WritePin(GPIOG,STEP_Pin, GPIO_PIN_RESET);
		
		//if(j>1)	j--;
		//else;		
		DelayNop(j);
		HAL_GPIO_WritePin(GPIOG,STEP_Pin, GPIO_PIN_SET);
		DelayNop(j);
	}
	
	HAL_Delay(10);
	//电机非使能
	HAL_GPIO_WritePin(GPIOF,EN_Pin, GPIO_PIN_SET);
}
/**
  * @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_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  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_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
//void MX_USART2_UART_Init(void)
//{

//  /* USER CODE BEGIN USART2_Init 0 */

//  /* USER CODE END USART2_Init 0 */

//  /* USER CODE BEGIN USART2_Init 1 */

//  /* USER CODE END USART2_Init 1 */
//  huart2a.Instance = USART2;
//  huart2a.Init.BaudRate = 115200;
//  huart2a.Init.WordLength = UART_WORDLENGTH_8B;
//  huart2a.Init.StopBits = UART_STOPBITS_1;
//  huart2a.Init.Parity = UART_PARITY_NONE;
//  huart2a.Init.Mode = UART_MODE_TX_RX;
//  huart2a.Init.HwFlowCtl = UART_HWCONTROL_NONE;
//  huart2a.Init.OverSampling = UART_OVERSAMPLING_16;
//  if (HAL_UART_Init(&huart2a) != HAL_OK)
//  {
//    Error_Handler();
//  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

//}

/**
  * @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 */
}

#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 */

  • 这边的代码是选择64细分,正转10圈-等待2S-反转10圈-等待2S。
    在这里插入图片描述
  • 编译代码烧录到单板
    仿真器配置参考link中13节。
    在这里插入图片描述
  • 这样,就可以控制电机正反转啦。
    ps: 正点原子STM32战舰版V3的板子每次烧录需要摁红色reset按钮,烧录才能生效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/800495.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《Programming from the Ground Up》阅读笔记:p49-p74

《Programming from the Ground Up》学习第3天&#xff0c;p49-p74总结&#xff0c;总计26页。 一、技术总结 1.function (1)定义 p49, Functions are unit of code that do a defined piece of work on specified types of data。 函数是在指定类型的数据上完成所定义的某…

实验二:图像灰度修正

目录 一、实验目的 二、实验原理 三、实验内容 四、源程序和结果 源程序(python): 结果: 五、结果分析 一、实验目的 掌握常用的图像灰度级修正方法,包括图象的线性和非线性灰度点运算和直方图均衡化法,加深对灰度直方图的理解。掌握对比度增强、直方图增强的原理,…

数据库启动报ORA-600 6711故障分析处理---惜分飞

几个月以前的一个数据库故障,今天拿出来在win上重新分析,数据库启动报ORA-600 6711错 C:\Users\XFF>SQLPLUS / AS SYSDBA SQL*Plus: Release 12.1.0.2.0 Production on 星期日 7月 14 16:17:32 2024 Copyright (c) 1982, 2014, Oracle. All rights reserved. 已连接到空…

发那科机床切换程序号

此需求一般出现在要通过发那科机床做自动化单元的情况。通过发那科SDK给发那科寄存器指令&#xff0c;进而实现&#xff0c;机床自动程序号切换。 一、更改3006参数&#xff1a;开启工件号检索功能 二、更改G24的值&#xff08;0-9999&#xff09; G24为需要切换的程序号。 三、…

UML顺序图的建模技术及应用示例

新书速览|《UML 2.5基础、建模与设计实践》 顺序图是强调消息时间顺序的交互图&#xff0c;它描述了对象之间传送消息的时间顺序&#xff0c;用于表示用例中的行为顺序。顺序图将交互关系表示为一个二维图&#xff0c;横轴代表在协作中各独立对象的类元角色&#xff1b;纵轴是…

怎样在 PostgreSQL 中优化对大表的并发读取操作?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 怎样在 PostgreSQL 中优化对大表的并发读取操作&#xff1f;一、了解 PostgreSQL 中的大表和并发读取&…

Linux C语言基础 day10

目录 学习目标&#xff1a; 学习内容&#xff1a; 1.指针指向数组 1.1 指针与数组的关系 1.2 指针与一维数组关系实现 1.2.1 指针与一维数组的关系 1.2.2 指针指向一维整型数组作为函数参数传递 课外作业&#xff1a; 学习目标&#xff1a; 一周掌握 C基础知识 学习内…

mysql-connector-java 8.0.33 反序列化漏洞

前言 经过与oracle官方沟通&#xff0c;在最新的mysql-connector-j 9.0.0里不存在这个问题&#xff0c;所以他们不认为这是个漏洞 不过确实&#xff0c;mysql-connector-java这个分支已经迁移到mysql-connector-j了&#xff0c;当时没注意&#xff0c;交的时候只注意了mysql-c…

C#知识|账号管理系统:添加账号的功能笔记

哈喽,你好啊,我是雷工! 本节记录账号管理系统中添加账号的逻辑过程,以下为学习笔记。 01 实现内容 ①:实现当点击【保存到数据库】按钮时,将账号名称、原创篇数、账号简介、账号类型显示的内容存储到LGAccountManagerDB数据库的Account表中; ②:实现点击【保存到数据库…

从LeetCode215看排序算法

目录 LeetCode215 数组的第K个最大元素 ① 第一反应&#xff1a;java的内置排序Arrays.sort() ② 冒泡排序 ③归并排序&#xff08;先分解再合并&#xff09; ④快速排序&#xff08;边分解边排序&#xff09; ⑤堆排序 LeetCode215 数组的第K个最大元素 给定整数数组 nums…

LLM(大语言模型)解码时是怎么生成文本的?

Part1配置及参数 transformers4.28.1 源码地址&#xff1a;transformers/configuration_utils.py at v4.28.1 huggingface/transformers (github.com) 文档地址&#xff1a;Generation (huggingface.co) 对于生成任务而言&#xff1a;text-decoder, text-to-text, speech-…

详解MySQL中的递归查询

MySQL中的递归查询主要通过WITH RECURSIVE语句来实现&#xff0c;这在处理具有层级关系或树形结构的数据时非常有用。下面将通过一个具体的例子来详细解释如何在MySQL中使用递归查询。 示例场景 假设我们有一个部门表&#xff08;departments&#xff09;&#xff0c;其中包含…

Zynq系列FPGA实现SDI编解码转SFP光口传输(光端机),基于GTX高速接口,提供6套工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案在Xilinx-Kintex7上的应用 3、详细设计方案设计原理框图输入Sensor之-->OV5640摄像头输入Sensor之-->HDMIVDMA图像缓存RGB转BT1120GTX 解串与串化SMPTE SD/HD/3G SDI IP核BT1120转RGBHDMI输…

Rust 通过 Deref trait 将智能指针当作常规引用处理

通过 Deref trait 将智能指针当作常规引用处理 实现 Deref trait 允许我们重载 解引用运算符&#xff08;dereference operator&#xff09;*&#xff08;与乘法运算符或通配符相区别&#xff09;。通过这种方式实现 Deref trait 的智能指针可以被当作常规引用来对待&#xff…

基于IDEA的Lombok插件安装及简单使用

lombok介绍 Lombok能以注解形式来简化java代码&#xff0c;提高开发效率。开发中经常需要写的javabean&#xff0c;都需要花时间去添加相应的getter/setter&#xff0c;也许还要去写构造器、equals等方法&#xff0c;而且需要维护。而Lombok能通过注解的方式&#xff0c;在编译…

Qt中文个数奇数时出现问号解决

Qt中文个数奇数时出现问号解决 目录 Qt中文个数奇数时出现问号解决问题背景问题场景解决方案 问题背景 最近在开发一个小工具&#xff0c;涉及到一些中文注释自动打印&#xff0c;于是摸索如何把代码里面的中文输出到csv文件中&#xff0c;出现了乱码&#xff0c;按照网上的攻…

供应链管理(SCM):如何在颜值和体验上发力

要在供应链管理系统&#xff08;SCM&#xff09;中在颜值和体验上发力&#xff0c;让用户感觉耳目一新&#xff0c;可以采取以下措施&#xff1a; 界面设计优化&#xff1a; 对供应链管理系统的界面进行优化&#xff0c;注重界面的美观、简洁和易用性。采用现代化的设计风格、…

Python酷库之旅-第三方库Pandas(026)

目录 一、用法精讲 65、pandas.bdate_range函数 65-1、语法 65-2、参数 65-3、功能 65-4、返回值 65-5、说明 65-6、用法 65-6-1、数据准备 65-6-2、代码示例 65-6-3、结果输出 66、pandas.period_range函数 66-1、语法 66-2、参数 66-3、功能 66-4、返回值 6…

Gooxi受邀参加第三届中国数据中心服务器与设备峰会

7月2-3日&#xff0c;第三届中国数据中心服务器与设备峰会在上海召开&#xff0c;作为国内最聚焦在服务器领域的专业峰会&#xff0c;吸引了来自全国的行业专家、服务器与机房设备厂家&#xff0c;企业IT用户&#xff0c;数据中心业主共同探讨AIGC时代下智算中心设备的设计之道…

【Linux】03.权限

一、权限的概念 Linux下有两种用户&#xff1a;超级用户&#xff08;root&#xff09;、普通用户。 超级用户&#xff1a;可以在 linux 系统下做任何事情&#xff0c;不受限制普通用户&#xff1a;在linux下做有限的事情超级用户的命令提示符是“#”&#xff0c;普通用户的命…