STM32F407简单驱动步进电机(标准库)

配置

单片机型号:STM32F104ZGT6

步进电机:YK28HB40-01A

驱动器:YKD2204M-Plus

接线方式:

pu+:接对应的产生PWM的引脚,这里接PF9,对应TIM14_CH1通道!

pu-:接单片机的GND;

DR+:接单片机的3.3V(电机转动的方向固定)或者单片机的控制引脚这里是PF8

DR-:接单片机的GND;

这里没有使用电机的使能引脚!!!

-V:接24V的负极

+V:接24V的正极

A+:接的步进电机的红线(需要参考对应的原理图,不同的电机接法存在差异)

A-:步进电机的蓝线

B+:步进电机的绿线

B-:步进电机的黑线

采用定时器主从模式,发送固定脉冲,控制步进电机的转动;

比如在驱动器上,将脉冲调到1600挡位,表示当有1600个脉冲到来时,电机转动一周。如果输入800个脉冲,则电机就转动半圈;

主定时器采用TIM14_CH1;

从定时器采用TIM12_ITR3;

 

 表72在407中文手册370页;  表79在464页;  图165在446页;  图166在447页

代码部分

采用标准库进行开发,先创建好工程!

再创建一个pwm.c和pwm.h文件就可以驱动了!

pwm.c

#include "PWM.h"
#include "stm32f4xx.h" /*
*PF9  TIM14_CH1通道
*PF8	方向引脚
*/
void TIM14_PWM_Init(void)	//主定时器	//uint32_t arr,uint32_t psc
{	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);  //使能定时器 14 时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); 	//使能PORTF时钟GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GPIOF9 复用为定时器 14GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           //GPIOF9GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉GPIO_Init(GPIOF,&GPIO_InitStructure);              //初始化PF9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;           //GPIOF8GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;        //功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //复用推挽输出GPIO_Init(GPIOF,&GPIO_InitStructure);              //初始化PF8//TIM_InternalClockConfig()TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_TimeBaseStructure.TIM_Period =100-1; //arr; //设置自动重装载值  100-1TIM_TimeBaseStructure.TIM_Prescaler =1050-1;//psc; //设置预分频值TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim  0=TIM_CKD_DIV1TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式TIM_TimeBaseInit(TIM14, &TIM_TimeBaseStructure); //根据指定的参数初始化 TIMx 的TIM_OCInitTypeDef TIM_OCInitStructure;TIM_OCStructInit(&TIM_OCInitStructure);	//默认的初始化TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择 PWM 模式 1TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能TIM_OCInitStructure.TIM_OCPolarity =TIM_OCPolarity_High;//输出极性高 //TIM_OCPolarity_Low; //输出极性低TIM_OCInitStructure.TIM_Pulse=50;//CCRTIM_OC1Init(TIM14, &TIM_OCInitStructure); //初始化 TIM//TIM_SelectMasterSlaveMode();//TIM_SelectOutputTrigger();TIM_OC1PreloadConfig(TIM14,TIM_OCPreload_Enable);	//通道1的CCR可以更改TIM_ARRPreloadConfig(TIM14,ENABLE);	//使能ARR预装载寄存器TIM_Cmd(TIM14, DISABLE); //使能 TIM14}void TIM12_Init(void)//从定时器
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM12,ENABLE);  //使能定时器 12 时钟TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_TimeBaseStructure.TIM_Period = 65535; //设置自动重装载值  100-1TIM_TimeBaseStructure.TIM_Prescaler =1-1; //设置预分频值TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim  0=TIM_CKD_DIV1TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式TIM_TimeBaseInit(TIM12, &TIM_TimeBaseStructure); //根据指定的参数初始化 TIMx 的//TIM_SelectMasterSlaveMode(TIM12,);TIM_SelectInputTrigger(TIM12,TIM_TS_ITR3);	//TIM14主   TIM12从:ITR3TIM_SelectSlaveMode(TIM12,TIM_SlaveMode_External1);//从模式TIM_ITConfig(TIM12,TIM_IT_Update,DISABLE);TIM_ARRPreloadConfig(TIM12,ENABLE);	//使能ARR预装载寄存器NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel=TIM8_BRK_TIM12_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;NVIC_Init(&NVIC_InitStructure);TIM_Cmd(TIM12, DISABLE); //使能 TIM12
}/**
uint16_t Num    发送的脉冲数(从定时器的ARR值)
uint8_t Dir     步进电机的旋转方向
uint16_t Speed	速度(更改主定时器的ARR值)
*/
void PWM_Output_Speed(uint16_t Num,uint8_t Dir,uint16_t Speed)
{if(Dir==1){GPIO_ResetBits(GPIOF,GPIO_Pin_8);//正转}else{GPIO_SetBits(GPIOF,GPIO_Pin_8);  //反转}TIM_Cmd(TIM12, DISABLE);//关闭TIM12使能TIM_SetAutoreload(TIM12,Num);//从新设置ARR计数值TIM_GenerateEvent(TIM12,TIM_EventSource_Update);//配置由软件生成定时器事件,新修改ARR计数值后,马上软件更改一次事件TIM_Cmd(TIM12, ENABLE); //使能 TIM12TIM_ClearITPendingBit(TIM12,TIM_IT_Update);//清楚中断标志位TIM_ITConfig(TIM12,TIM_IT_Update,ENABLE);//开启定时器12的中断TIM_SetAutoreload(TIM14,Speed);//从新设置ARR计数值TIM_GenerateEvent(TIM14,TIM_EventSource_Update);//配置由软件生成定时器事件,新修改ARR计数值后,马上软件更改一次事件TIM_SetCompare1(TIM14,Speed/2);	//设置CCR的值为ARR的一半,占空比为50%TIM_GenerateEvent(TIM14,TIM_EventSource_CC1);//配置后由软件生成通道一的事件,马上生效TIM_Cmd(TIM14, ENABLE); //使能 TIM14	
}void TIM8_BRK_TIM12_IRQHandler(void)
{if(TIM_GetITStatus(TIM12,TIM_IT_Update) != RESET){TIM_ClearITPendingBit(TIM12,TIM_IT_Update);TIM_Cmd(TIM12, DISABLE);//关闭TIM12使能TIM_Cmd(TIM14, DISABLE);//关闭TIM14使能TIM_ITConfig(TIM12,TIM_IT_Update,DISABLE);//关闭定时器12的中断}
}

pwm.h

#ifndef __PWM_H__
#define __PWM_H__#include "stm32f4xx.h" void TIM14_PWM_Init(void);	//uint32_t arr,uint32_t psc
void TIM12_Init(void);
void PWM_Output_Speed(uint16_t Num,uint8_t Dir,uint16_t Speed);#endif

main函数部分

#include "stm32f4xx.h"                  // Device header
#include "pwm.h"int main()
{TIM14_PWM_Init();	//168M/168=1Mhz的计数频率,重装载值100,所以PWM频率为 1M/100=1Khz.TIM12_Init();PWM_Output_Speed(3200,0,40);//发送的脉冲数	步进电机的旋转方向	速度(更改主定时器的ARR值)while(1){}}

通过PWM_Output_Speed(3200,0,40);输入 3200个脉冲,电机逆时针转2圈。最后一位参数为速度;

PWM_Output_Speed(1600,1,40);就是沿顺时针方向旋转一周;

通过修改PWM_Output_Speed();可以实现电机的角度、方向、速度控制。

其他方式的pwm简单驱动

采用定时器的翻转模式,驱动电机的转动:

#include "PWM.h"
#include "stm32f4xx.h" /*
*PF9  TIM14_CH1通道
*PF8 为方向引脚
*/uint16_t CCR1=1000;void TIM14_PWM_Init(uint32_t arr,uint32_t psc)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);  //使能定时器 14 时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); 	//使能PORTF时钟GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GPIOF9 复用为定时器 14GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           //GPIOF9GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉GPIO_Init(GPIOF,&GPIO_InitStructure);              //初始化PF9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;           //GPIOF8GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;        //功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //复用推挽输出GPIO_Init(GPIOF,&GPIO_InitStructure);              //初始化PF8TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_TimeBaseStructure.TIM_Period = arr-1; //设置自动重装载值  输出频率TIM_TimeBaseStructure.TIM_Prescaler =psc-1; //设置预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim  0=TIM_CKD_DIV1TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式TIM_TimeBaseInit(TIM14, &TIM_TimeBaseStructure); //根据指定的参数初始化 TIMx 的TIM_OCInitTypeDef TIM_OCInitStructure;TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; //翻转模式 //TIM_OCMode_PWM1; //选择 PWM 模式 1TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能TIM_OCInitStructure.TIM_OCPolarity =TIM_OCPolarity_High;//输出极性高 //TIM_OCPolarity_Low; //输出极性低TIM_OCInitStructure.TIM_Pulse=CCR1; //CCRTIM_OC1Init(TIM14, &TIM_OCInitStructure); //初始化 TIMTIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Disable);//失能  //使能TIM14在CCR1上的预装载寄存器  TIM_OCPreload_Enable
//	TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPE使能 TIM_ClearFlag(TIM14,TIM_FLAG_CC1);	//清除定时器中断标志位TIM_ITConfig(TIM14,TIM_FLAG_CC1,ENABLE);    //开启定时器比较中断NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel=TIM8_TRG_COM_TIM14_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;NVIC_Init(&NVIC_InitStructure);TIM_Cmd(TIM14, ENABLE); //使能 TIM14
}void TIM8_TRG_COM_TIM14_IRQHandler(void)
{uint16_t num = 0;if(TIM_GetITStatus(TIM14,TIM_FLAG_CC1)==SET){TIM_ClearITPendingBit(TIM14,TIM_FLAG_CC1);num=TIM_GetCapture1(TIM14);TIM_SetCompare1(TIM14,num+CCR1);}
}

 在main函数中调用TIM14_PWM_Init(65536,1);

运行结果就是使电机沿单一方向转动,通过修改ARR值可以调速;

通过在main函数调用下面函数,可控制电机的旋转方向;(引脚接线注意接对)

GPIO_SetBits(GPIOF,GPIO_Pin_8);  //反转
GPIO_ResetBits(GPIOF,GPIO_Pin_8); //正转

直接输出pwm波形的驱动

pwm.c

#include "PWM.h"
#include "stm32f4xx.h" 
//#include "uart.h"/*
*PF9  TIM14_CH1通道
*
*/
void TIM14_PWM_Init(uint32_t arr,uint32_t psc)
{GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);  //使能定时器 14 时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); 	//使能PORTF时钟GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GPIOF9 复用为定时器 14GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           //GPIOF9GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉GPIO_Init(GPIOF,&GPIO_InitStructure);              //初始化PF9TIM_TimeBaseStructure.TIM_Period = arr; //设置自动重装载值  100-1TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim  0=TIM_CKD_DIV1TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式TIM_TimeBaseInit(TIM14, &TIM_TimeBaseStructure); //根据指定的参数初始化 TIMx 的TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择 PWM 模式 1TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能TIM_OCInitStructure.TIM_OCPolarity =TIM_OCPolarity_High; //TIM_OCPolarity_Low; //输出极性低TIM_OCInitStructure.TIM_Pulse=50;//CCRTIM_OC1Init(TIM14, &TIM_OCInitStructure); //初始化 TIMTIM_Cmd(TIM14, ENABLE); //使能 TIM14}

在main函数中调用TIM14_PWM_Init(100-1,1680-1);

运行结果就是使电机沿单一方向转动,通过修改ARR值可以调速;

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

linux-DNS解析

dns解析 dns:域名系统,将域名和ip地址互相映射的一个分布式的数据库,方便用户访问互联网。 ip地址:是所有设备和网站在互联网上的唯一地址,通信一定是ip和ip之间的通信。 dns解析:根据域名在互联网当中找…

光伏电站容量计算方法科普

光伏电站的容量计算是设计和评估光伏系统性能的关键步骤。通过了解光伏电站的容量,我们可以预估其发电量,优化系统设计,并确保系统能满足电力需求。本文将详细介绍几种常见的光伏电站容量计算方法,并特别介绍小程序“光伏一点通”…

采集opc da 转 profinet IO项目案例

目录 1 案例说明 1 2 VFBOX网关工作原理 1 3 应用条件 2 4 查看OPC DA服务器的相关参数 2 5 配置网关采集opc da数据 4 6 用profinet IO协议转发数据 6 7 在服务器上运行仰科OPC DA采集软件 9 8 案例总结 11 1 案例说明 在OPC DA服务器上运行OPC DA client软件查看OPC DA服务…

循环矩阵和BCCB矩阵与向量乘积的快速计算——矩阵向量乘积与频域乘积之间的转换

目录 循环矩阵循环矩阵的定义特征值与特征向量循环矩阵的对角化 循环矩阵与向量的乘积 BCCB矩阵BCCB矩阵的定义BCCB矩阵的对角化BCCB 矩阵与向量的乘积BCCB 矩阵与向量乘积的实现 总结 循环矩阵(Circulant Matrix)和块循环对称矩阵(Block Cir…

(动画版)排序算法 -希尔排序

文章目录 1. 希尔排序(Shellsort)1.1 简介1.2 希尔排序的步骤1.3 希尔排序的C实现1.4 时间复杂度1.5 空间复杂度1.6 希尔排序动画 1. 希尔排序(Shellsort) 1.1 简介 希尔排序(Shells Sort),又…

蓝桥杯每日真题 - 第7天

题目:(爬山) 题目描述(X届 C&C B组X题) 解题思路: 前缀和构造:为了高效地计算子数组的和,我们可以先构造前缀和数组 a,其中 a[i] 表示从第 1 个元素到第 i 个元素的…

socketcan-goloang

模拟接收 模拟发送 package mainimport ("context""fmt""go.einride.tech/can""go.einride.tech/can/pkg/candevice""go.einride.tech/can/pkg/socketcan" )func main() {// linux系统设置// sudo ip link add dev can0 ty…

Java期末复习暨学校第五次上机课作业

Java期末复习暨学校第五次上机课作业:掌握类的定义、掌握类的封装、熟悉类的成员方法的调用。 第一题: 先定义两个整形变量x和y,然后showMessage方法打印防御塔的位置。 然后通过new关键字实例化了一个TowerDefense对象t1,并把x赋值为3&…

【目标检测】【Ultralytics-YOLO系列】Windows11下YOLOV5人脸目标检测

【目标检测】【Ultralytics-YOLO系列】Windows11下YOLOV5人脸目标检测 文章目录 【目标检测】【Ultralytics-YOLO系列】Windows11下YOLOV5人脸目标检测前言YOLOV5模型运行环境搭建YOLOV5模型运行数据集准备YOLOV5运行模型训练模型验证模型推理 总结 前言 Ultralytics YOLO 是一…

【启明智显分享】5G CPE与5G路由器到底有什么区别?

5G路由器和5G CPE在功能和应用场景上存在很明显的差异,小编做了详细比较,希望能帮助到你进一步了解他们的区别及应用。 一、定义与功能 5G路由器 5G路由器是一个将5G网络连接转换为Wi-Fi信号的设备,使多个Wi-Fi设备可以通过5G网络进行连接…

【go从零单排】File Paths文件路径

🌈Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 📗概念 在 Go 中,处理文件路径通常使用 path/filepath 包。这个包提供了一系…

【数据分享】中国渔业统计年鉴(1979-2024) pdf

数据介绍 一、《中国渔业统计年鉴》以正式出版年份标序。其统计数据起讫日期:渔民家庭收支调查起讫时间为 2022年11月1日至2023年10月31日,其他数据起讫时间为2023年1月1日至2023年12月31日。 二、统计数据中,远洋渔业数据按照远洋渔业管理办法进行统计…

Windows10“大限”将至或加速政企信创进程

近日,微软公司正式宣布将于2025年10月14日终止对Windows 10系统的支持服务。Windows 10“退休”在即,信息安全风险陡增——对此,360织语的安全专家认为,对于政企用户而言,不管是选择继续使用Windows 10,还是…

文本嵌入方案大总结:从词向量到句向量

这里写目录标题 文本嵌入方案总结一、文本嵌入三种层次 词向量应用: 句向量应用: 扩展:文本嵌入和句子相似度、文本匹配的逻辑关系? 二、词向量有哪些方案、优缺点、工具?方案一:统计编码方案二&…

第23天Linux下常用工具(二)

目录 第四章 GDB调试工具 4.1gdb的作用 4.2调试代码的流程 4.3gdb的安装 4.4 gdb的使用 第五章 makefile工程管理工具 5.1makefile的作用 5.2makefile的运行 5.3make的安装 5.4makefile的编写方法 5.5makefile的语法 5.6makefile使用示例 第四章 GDB调试工具 4.1g…

ubuntu22.04与ubuntu24.10使用Remmina远程桌面共享

1. ubuntu22.04启用远程桌面共享 点击Remote Desktop,按下图设置 成功启用 2.ubuntu24.10远程桌面启用 选择远程桌面选项 启用远程桌面共享与远程控制 启用远程登陆

基于51单片机的高压锅控制系统proteus仿真

地址: https://pan.baidu.com/s/16BuxmKYUprTGbkEj_BWGvQ 提取码:1234 仿真图: 芯片/模块的特点: AT89C52/AT89C51简介: AT89C52/AT89C51是一款经典的8位单片机,是意法半导体(STMicroelectro…

D3的竞品有哪些,D3的优势,D3和echarts的对比

D3 的竞品 ECharts: 简介: ECharts 是由百度公司开发的一款开源的 JavaScript 图表库,提供了丰富的图表类型和高度定制化的配置选项。特点: 易于使用,文档详尽,社区活跃,支持多种图表类型(如折线图、柱状图、饼图、散点…

2024年11月13日

1.创业法律指南 留置权和其他三个权 定金和订金 一般保证和连带保证 1.案例 物权编之担保法律制度案例一 冯系养鸡专业户,为改建鸡会和引进良种需资金20万元。冯向陈借款10万元,以自己的一套价值10万元的音响设备抵押,双方立有抵押字据&a…

从电动汽车到车载充电器:LM317LBDR2G 线性稳压器在汽车中的多场景应用

附上LM317系列选型: LM317BD2TG-TO-263 LM317BTG-TO-220 LM317BD2TR4G-TO-263 LM317D2TG-TO-263 LM317D2TR4G-TO-263 LM317TG-TO-220 LM317LBDR2G-SOP-8 LM317LDR2G-SOP-8 LM317MABDTG-TO-252 LM317MABDTRKG-TO-252 LM317MA…