草庐IT

基于STM32之控制步进电机,学到即赚到!(含主代码)

不说二话的自家人 2023-04-09 原文

目录

前言

一、关于步进电机那点事

二、接线问题

三、主要代码

四、总结


前言

最近发现电机类的步进电机挺有趣的,于是趁快开学了有空再码一篇,分享一下自己的学习心得,有哪里写的不好欢迎随时指正。

一、关于步进电机那点事

这次使用的是二相步进电机,博客上也有许多关于步进电机的博文啊,质量也是参差不齐,今天就给大家仔细的介绍一下该电机,我主要还是继承以往的风格,资料方面我也讲的少,主要还是侧重实操方向,希望能够带给大家帮助

下面是图: 

首先要认识一下步进电机上的几条线:

四条线(红、蓝、绿、黑)

正常来说对应A+、A-、B+、B-,在电机上基本上也都会标明代表含义,其实步进电机的原理其实都差不多,主要就是学会使用和了解原理就基本上达到我们的目的了,如果想要深入学习,那可以再继续研究······

那么怎么使用呢?首先就要搭配一款步进电机的驱动器了,网上随便都可以买到,如图:

 这里我们很明显可以看到它有12个接口,这里再详细介绍一下如何使用接口:

V+:连接电源正极(注意电压在9V~32V之间即可,过大的话你懂得)

GND:连接电源负极

A+:连接电机绕组A+相

A- : 连接电机绕组A-相

B+:连接电机绕组B+相

B- : 连接电机绕组B-相

CP+:脉冲信号输入正 ( PUL+ )(取决于共阴、共阳接法再来接线,共阴的话CP-接地,CP+接脉冲信号即定时器PWM输出)

CP-:脉冲信号输入负  ( PUL-)

DIR+:电机正、反转控制正(同样取决于共阴共阳接法)

DIR-:电机正、反转控制负

EN+:电机脱机控制正(可以不接)

EN-:电机脱机控制负

二、接线问题

上面到这可能对它的接线有了一个想法了,那么具体如何接线呢?嘿嘿,这里有共阴和共阳的常见的两种接法,具体参照下图:

 这里我采用了共阴极的接法

那么我的接线:

DIR+:PA8(随便一个端口即可)

DIR-:GND

CP+:PA1(TIM2通道2)

CP-:GND

ENA不接

三、主要代码

这里的代码搬运后修改一些的,即可上手即可用

主函数

#include "stm32f10x.h"
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "key.h"
#include "led.h"	 
#include "usmart.h"	
#include "driver.h"

//共阴
/*
CP+->PA.1   CP-接GND
DIR+->PA.8  DIR-接GND
*/

int main(void)
{	 
	delay_init();	    	 	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 	
	uart_init(115200);	     
	KEY_Init();			
	Driver_Init();			
	TIM2_Init(999,72-1);       
	while(1) 
	{	
			Locate_Rle2(500,CW);
			delay_ms(5000);
			delay_ms(5000);
			delay_ms(5000);
			Locate_Rle2(500,CCW);
			delay_ms(5000);
			delay_ms(5000);
			delay_ms(5000);
		}

}	

 定时器函数:

#include "stm32f10x.h"
#include "driver.h"
#include "delay.h"
#include "usart.h"

long current_pos[2]={0,0}; 
int motor_dir2=0;
u8 count[2]={0,0};

void Driver_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	
	GPIO_Init(GPIOA, &GPIO_InitStructure);					
	GPIO_SetBits(GPIOA,GPIO_Pin_8);						
}


void TIM2_Init(u16 arr,u16 psc)
{		 					 
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 	
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);                                                                      	

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;				//TIM2_CH2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;			
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
	
	TIM_TimeBaseStructure.TIM_Period = arr;					 
	TIM_TimeBaseStructure.TIM_Prescaler =psc;				
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; 			
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 		
	TIM_ClearITPendingBit(TIM2,TIM_IT_Update);				

	TIM_UpdateRequestConfig(TIM2,TIM_UpdateSource_Regular); 
	TIM_SelectOnePulseMode(TIM2,TIM_OPMode_Single);			
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;		
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
	TIM_OCInitStructure.TIM_Pulse = arr>>1; 				
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 
	TIM_OC2Init(TIM2, &TIM_OCInitStructure); 				

	TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);  		
	TIM_ARRPreloadConfig(TIM2, ENABLE); 					
	
	TIM_ITConfig(TIM2, TIM_IT_Update ,ENABLE);  			
 
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  		
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 		
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 	
	NVIC_Init(&NVIC_InitStructure);  						
	
	TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  			
	TIM_Cmd(TIM2, DISABLE);  															  
}
/******* TIM2*********/
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_FLAG_Update)!=RESET)
	{
		TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);	
		count[0]++; 
		TIM_GenerateEvent(TIM2,TIM_EventSource_Update);
	
		TIM_Cmd(TIM2, ENABLE);  					  

		if(count[0]==200)
		{
			if(motor_dir2==CW) 						  
				current_pos[0]+=count[0];
			else          							  
				current_pos[0]-=count[0];
			TIM_Cmd(TIM2, DISABLE);  				  		
			printf("motor2µ±Ç°Î»ÖÃ=%ld\r\n",current_pos[0]);
			count[0]=0;
		}
	
	}
}

void TIM2_Startup(u32 frequency)   
{
	u16 temp_arr=1000000/frequency-1; 
	TIM_SetAutoreload(TIM2,temp_arr);
	TIM_SetCompare2(TIM2,temp_arr>>1); 
	
	TIM_SetCounter(TIM2,0);
	TIM_Cmd(TIM2, ENABLE);  
}


void Locate_Rle2(u32 frequency,DIR_Type dir) 
{
	
	if(TIM2->CR1&0x01)
	{
		printf("\r\nThe last time pulses is not send finished,wait please!\r\n");
		return;
	}
	if((frequency<20)||(frequency>100000))
	{
		printf("\r\nThe frequency is out of range! please reset it!!(range:20Hz~100KHz)\r\n");
		return;
	}
	motor_dir2=dir;
	
	DRIVER_DIR2=motor_dir2;				
	TIM2_Startup(frequency);			
}

 到这里你就会发现其实原理还是相当简单的,剩下的也不再深入了,希望能够对大家帮助哈哈

实现目的:

该程序就是实现正转后隔一会再反转,大家可以根据自己需求设置到自己想要的转动情况,同时要让他停下来,只需要在自己需要的地方设置一个TIM_SetCompare2(TIM2,0)即可停下,可以自由设置。

四、总结

今天关于步进电机就暂且介绍到这里,后面有需要会再特别介绍一下,文章写得还是比较简单,相信对于你还是可以很轻松入手的,到这里别忘了给点个赞,收藏一波,顺道关注一下,厚着脸皮求三连哈哈。

有需要代码可以随时评论留下邮箱即可,看到即回,其他博文也一样,有需要即可评论带上邮箱,同时欢迎交流学习

 

题外话:

挺喜欢彭于晏说的一句话:“我就是没有才华,所以才用命去拼!”

学习32之路固然辛苦,但要是坚持下来了,那不是很酷?哈哈哈

有关基于STM32之控制步进电机,学到即赚到!(含主代码)的更多相关文章

  1. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  2. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  3. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  4. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  5. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  6. ruby-on-rails - 浏览 Ruby 源代码 - 2

    我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru

  7. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  8. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  9. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  10. 程序员如何提高代码能力? - 2

    前言作为一名程序员,自己的本质工作就是做程序开发,那么程序开发的时候最直接的体现就是代码,检验一个程序员技术水平的一个核心环节就是开发时候的代码能力。众所周知,程序开发的水平提升是一个循序渐进的过程,每一位程序员都是从“菜鸟”变成“大神”的,所以程序员在程序开发过程中的代码能力也是根据平时开发中的业务实践来积累和提升的。提高代码能力核心要素程序员要想提高自身代码能力,尤其是新晋程序员的代码能力有很大的提升空间的时候,需要针对性的去提高自己的代码能力。提高代码能力其实有几个比较关键的点,只要把握住这些方面,就能很好的、快速的提高自己的一部分代码能力。1、多去阅读开源项目,如有机会可以亲自参与开源

随机推荐