完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
概述
随着嵌入式系统的发展,步进电机的使用开始激增,只要涉及到把物体从一个地方移动到另外一个地方,都少不了步进电机的身影。本教程以stm32为例,使用ULN2003,TB6600电机驱动板,A4988,DRV8825,介绍步进电机的常用驱动方式。 从ULN2003开始 首先从最简单的入手,用ULN2003芯片,来驱动这种淘宝单片机套件中经常见到(但其实并没有什么用处)的5V四相五线步进电机。 长这个样子 用了配套的驱动板,但其实可以直接把ULN2003芯片插面包板上使用 (不知道我这么打广告这家淘宝店给不给钱) 上面提到了四相五线,仔细看有一条红线,即为5V电源线,还有黄、橙、粉、蓝四线,即名字里的四相,每条线都连接了电机内部的一个线圈,转子可以看做是一个磁铁,给四个线圈依次通电,线圈通电产生磁性,使转子旋转。这里有几种信号的输入方法,参考了一个很不错的制作网站中的一个帖子,链接附在这里:howtomechatronics 如上图所示,当给其中一个线圈通电时,对应线圈变为红色,产生磁性,那么怎么才能给线圈通电呢?之前我们提到了五线中还有一条5V的电源线,那么当把某一线圈接地时,电流便会流过线圈,这样,ULN2003的作用就很明显了 ——将对应引脚接地。 如下图所示,ULN2003的工作方式是这样的,正视芯片(缺口端朝上),左边最下面的引脚接地,当左边的引脚输入高电平时,右边与它平行的引脚接地,所以我们只要用stm32控制对应的引脚依次为高电平就可以让它转动起来了。 接线如下图所示,用了野火的f103ZET6的核心板,PA5,PA6,PA7,PA8依次接IN1,IN2,IN3,IN4。用两节AA电池供电,在这里要注意,不能用板子直接供电,因为电机在启动瞬间会产生很大的感应电流而烧坏板子。为了使电平统一,还应该把板子的GND与电源负极连接。 (这里有一点小问题,就是Fritzing中没有我们用到的步进电机类型,所以在用了四线的代替) 实物图: 一、开始———波驱动或者单个线圈激发(Wave Drive or Single-Coil Excitation) 从上图我们可以看到,这个驱动方式是依次给线圈通电,然后在通电线圈断电的同时给下一个线圈通电,按照这个顺序循环往复。 下面是程序: 首先我们在user创建bsp_gpio.h与bsp_gpio.c,来初始化GPIO口,如接线所示,PA4-PA7依次接IN1-IN4 //IN1-PA4 #define IN1_GPIO_PORT GPIOA #define IN1_GPIO_CLK RCC_APB2Periph_GPIOA #define IN1_GPIO_PIN GPIO_Pin_4 //IN2-PA5 #define IN2_GPIO_PORT GPIOA #define IN2_GPIO_CLK RCC_APB2Periph_GPIOA #define IN2_GPIO_PIN GPIO_Pin_5 //IN3-PA6 #define IN3_GPIO_PORT GPIOA #define IN3_GPIO_CLK RCC_APB2Periph_GPIOA #define IN3_GPIO_PIN GPIO_Pin_6 //IN1-PA7 #define IN4_GPIO_PORT GPIOA #define IN4_GPIO_CLK RCC_APB2Periph_GPIOA #define IN4_GPIO_PIN GPIO_Pin_7 之后我们使用直接操作BSRR与BRR寄存器的方式来控制IO /* 直接操作寄存器的方法控制IO */ #define digitalHi(p,i) {p->BSRR=i;} //输出为高电平 #define digitalLo(p,i) {p->BRR=i;} //输出低电平 /* 定义控制IO的宏 */ #define IN1_HIGH digitalHi(IN1_GPIO_PORT,IN1_GPIO_PIN) #define IN1_LOW digitalLo(IN1_GPIO_PORT,IN1_GPIO_PIN) #define IN2_HIGH digitalHi(IN2_GPIO_PORT,IN2_GPIO_PIN) #define IN2_LOW digitalLo(IN2_GPIO_PORT,IN2_GPIO_PIN) #define IN3_HIGH digitalHi(IN3_GPIO_PORT,IN3_GPIO_PIN) #define IN3_LOW digitalLo(IN3_GPIO_PORT,IN3_GPIO_PIN) #define IN4_HIGH digitalHi(IN4_GPIO_PORT,IN4_GPIO_PIN) #define IN4_LOW digitalLo(IN4_GPIO_PORT,IN4_GPIO_PIN) 使用宏定义对IO口封装,使Main函数更加直观,编写更加简单 之后在bsp_gpio.c中我们定义函数void GPIO_Config(void)来初始化IO口,全部设置为通用推挽输出,速度为50MHz。 void GPIO_Config(void) { /*定义一个GPIO_InitTypeDef类型的结构体*/ GPIO_InitTypeDef GPIO_InitStructure; /*开启引脚相关的GPIO外设时钟*/ RCC_APB2PeriphClockCmd( IN1_GPIO_CLK | IN2_GPIO_CLK | IN3_GPIO_CLK | IN4_GPIO_CLK , ENABLE); /*选择要控制的GPIO引脚*/ GPIO_InitStructure.GPIO_Pin = IN1_GPIO_PIN; /*设置引脚模式为通用推挽输出*/ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*设置引脚速率为50MHz */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /*调用库函数,初始化GPIO*/ GPIO_Init(IN1_GPIO_PORT, &GPIO_InitStructure); /*选择要控制的GPIO引脚*/ GPIO_InitStructure.GPIO_Pin = IN2_GPIO_PIN; /*调用库函数,初始化GPIO*/ GPIO_Init(IN2_GPIO_PORT, &GPIO_InitStructure); /*选择要控制的GPIO引脚*/ GPIO_InitStructure.GPIO_Pin = IN3_GPIO_PIN; /*调用库函数,初始化GPIOF*/ GPIO_Init(IN3_GPIO_PORT, &GPIO_InitStructure); /*选择要控制的GPIO引脚*/ GPIO_InitStructure.GPIO_Pin = IN4_GPIO_PIN; /*调用库函数,初始化GPIOF*/ GPIO_Init(IN4_GPIO_PORT, &GPIO_InitStructure); //所有引脚初始化为低电平 IN1_LOW; IN2_LOW; IN3_LOW; IN4_LOW; } 成功了!电机转动起来,并且能够改变方向 二、其它驱动方法 在上面我们成功驱动电机使其转动起来,但是这样的方式效率很低,原文作者还提到了更好的几种驱动方法 (上图)这种方法延长了线圈的通电时间,使得同时会有两个线圈通电,但是用这种方法一转仍然是四步。 (上图)于是有了半步驱动这种方式,这其实是上面两种方式的结合,用这种方式控制,一转变成了八步。 (上图)现在用的最多的是这种微步控制方式,可以看到结果调制的正弦波被输入到电机中,用这种方式,转子的转动更加平滑,同时电机各部分受到的力也随之减小,这样电机工作过程中的振动与丢步大大减小。这就是所谓的输入pwm波控制步进电机。 但是问题在于,pwm波的调制不像输出高低电平那么简单,而且一般用到的步进电机驱动电流超过了板子的提供范围,所以在实际应用中,更多的是使用驱动板或者驱动芯片,这将在之后的文章中讲到。 |
|
|
|
只有小组成员才能发言,加入小组>>
2386 浏览 0 评论
8910 浏览 4 评论
36486 浏览 19 评论
4981 浏览 0 评论
24307 浏览 34 评论
1375浏览 2评论
1627浏览 1评论
2017浏览 1评论
1441浏览 0评论
386浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 04:03 , Processed in 1.004646 second(s), Total 47, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号