找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4476|回复: 10
收起左侧

请教关于四相五线步进电机的步数控制问题

[复制链接]
ID:191929 发表于 2017-6-20 22:34 | 显示全部楼层 |阅读模式
请教关于四相五线步进电机的步数控制问题???
有没有实际的例子供参考,就是转一定步数自动停下来那种,
回复

使用道具 举报

ID:164602 发表于 2017-6-21 08:30 | 显示全部楼层
分享我的学习笔记和例程:
/*学习笔记:
(1)正反转一般用的是高精度的“四相单双八拍”工作方式,即A-AB-B-BC-C-CD-D-DA,每个脉冲电机转动的角度叫步距角。
我使用的步进电机,参数如图所示,步距角5.625度,但是减速电机,减速比为64,即,每个脉冲,电机外轴实际转动角度为步距角的64分之一。
(2)表格数据的得来:        A B   C D
                                        1 0        0 0         (0xf8)
                                        1 1        0 0         (0xfc)
                                        0 1        0 0         (0xf4)
                                        0 1        1 0         (0xf6)
                                        0 0        1 0         (0xf2)
                                        0 0        1 1         (0xf3)
                                        0 0        0 1         (0xf1)
                                        1 0        0 1         (0xf9)
此ABCD对应电机驱动板(达林顿管IC芯片ULN2003A)中的输入端IN1~IN4,它又对应着单片机
IO口,本实例对应的是P2口的低四位;若想换IO口或位,此数据要调整。
(3)步进电机转动不能太快,是因为:
   保持转矩————步进电机通电但没有转动时,定子锁住转子的力矩。
   它是步进电机最重要的参数之一,
   通常步进电机在低速时的力矩接近保持转矩。由于步进电机的输出力矩随速度的增大而不断
   衰减,输出功率也随速度的增大而变化,所以保持转矩就成了衡量步进电机最重要参数之一。
   按自购步进电机的参数,则知:最好最小延时为0.002s,即本程序中i=285,可保持转矩。
(4)自购步进电机的步距角为5.625度,减速比为1:64。可见,要让眼睛看到的轴转180度,则
   提供的脉冲次数为n=180*64/5.625=2048=256*8个。但有误差,转动持续一段时间,就会有
   失调角。
(5)由于想显示转动的角度,而显示程序要用时间,所以本程序有些不对,现在还没有好办法让
   电机转动更快些。另:k5、k6让电机转动特定角度程序,还有点问题,按下后,再按,要重
   新计算初值。可以用变量控制,但太繁琐,暂时没管它,只要按下后等待转停就好
(6)程序功能:开机时,步进电机按正常速度(中速)正向转动,最多转动5圈;
        按独立键k1:正向快转;
        按独立键k2:反向快转;
        按独立键k3:每按一次,减速一次,从最快到最慢需按四次,以后按键无效;
        按独立键k4:每按一次,加速一次,从最慢到最快需按四次,以后按键无效;
        按独立键k5:中速正向转动90度;
        按独立键k6:中速反向转动180度;
*/

#include <reg51.h>

#define Rotation P2  //定义电机转动相数据的输入控制口,本例是P2口的低四位。

unsigned char code F_Rotation[8]={0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1,0xf9};//正转(逆时针)表格
unsigned char code B_Rotation[8]={0xf9,0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8};//反转(顺时针)表格

sbit k1=P3^7;                //以下六个为独立键盘
sbit k2=P3^6;
sbit k3=P3^5;
sbit k4=P3^4;
sbit k5=P3^3;
sbit k6=P3^2;
unsigned int Time;
unsigned int jd;       
bit k=0;

void Delay10ms(unsigned int c)//10ms延时程序
{
    unsigned char a,b;
    for(c;c>0;c--)
        for(b=38;b>0;b--)
            for(a=130;a>0;a--);
}

void Delay(unsigned int i)//延时7us
{
        while (--i);
}

void  Motor()        //电机旋转子函数
{
        unsigned char i;
        for(i=0;(i<8);i++)
        {
                if (jd==0)       
                {
                        Rotation=0xf0;
                        break;
                }
                if (k==0)
                {
                        Rotation=(F_Rotation);
                }               
                else
                {
                        Rotation=(B_Rotation);
                }
                Delay(Time);
                jd--;
                                                       
        }
}

void main()
{
        unsigned char m;                  //松键时消抖用变量
        m=0;
        Time=250;
        jd=20480;
        while(1)                                  //总循环
        {
               
                if(k1==0)                          //扫描法判断独立按键k1是否按下
                {
                        Delay10ms(1);          //消抖
                        if(k1==0)                  //再次判断k1是否按下
                        {

                                Time=150;
                                k=0;
                                jd=20480;

                                while((m<50)&&(k1==0))
                            {
                                    Delay10ms(1);
                                    m++;
                            }
                            m=0;
                        }
                }

                if(k2==0)                         //扫描独立键盘k2
                {
                        Delay10ms(1);
                        if(k2==0)
                        {

                                Time=150;
                                k=1;
                                jd=20480;

                                while((m<50)&&(k2==0))
                            {
                                    Delay10ms(1);
                                    m++;
                            }
                            m=0;
                        }
                }

                if(k3==0)                                  //扫描独立键盘k3
                {                                                         
                        Delay10ms(1);
                        if(k3==0)
                        {
                               
                                Time=Time+100;
                                if (Time>500)
                                {
                                        Time=500;
                                }
                                jd=20480;

                                while((m<50)&&(k3==0))
                            {
                                    Delay10ms(1);
                                    m++;
                            }
                            m=0;
                        }
                }

                if(k4==0)                                        //扫描独立键盘k4
                {
                        Delay10ms(1);
                        if(k4==0)
                        {

                                Time=Time-100;
                                if (Time<150)
                                {
                                        Time=150;
                                }
                                jd=20480;

                                while((m<50)&&(k4==0))
                            {
                                    Delay10ms(1);
                                    m++;
                            }
                            m=0;
                        }
                }

                if(k5==0)                                        //扫描独立键盘k5
                {
                        Delay10ms(1);
                        if(k5==0)
                        {

                                Time=250;
                                k=0;
                                jd=1024;        //只转90度

                                while((m<50)&&(k5==0))
                            {
                                    Delay10ms(1);
                                    m++;
                            }
                            m=0;
                        }
                }

                if(k6==0)
                {
                        Delay10ms(1);
                        if(k6==0)
                        {

                                Time=250;
                                k=1;
                                jd=2048;

                                while((m<50)&&(k6==0))
                            {
                                    Delay10ms(1);
                                    m++;
                            }
                            m=0;
                        }
                }

                Motor();//调用电机转动子程序

        }
}

另外,本例程是我本人在学习单片机初期的成果,没有用定时器来控制转速,你可以自己修改。
我的学习心得可是好东西哦。呵呵
回复

使用道具 举报

ID:164602 发表于 2017-6-21 08:35 | 显示全部楼层
刚才忘了贴图了。

步进电机参数

步进电机参数

独立按键电路

独立按键电路

步进电机驱动原理图.pdf

12.88 KB, 下载次数: 18

回复

使用道具 举报

ID:191929 发表于 2017-6-21 16:03 | 显示全部楼层
谢谢,谢谢,谢谢
回复

使用道具 举报

ID:164602 发表于 2017-6-21 16:54 | 显示全部楼层
惜缘2008 发表于 2017-6-21 16:03
谢谢,谢谢,谢谢

不用客气,我也是这样在别人的帮助下学习的,互相帮助,共同进步!能帮到你就好!
回复

使用道具 举报

ID:191929 发表于 2017-6-21 22:47 | 显示全部楼层
谢谢了,问题解决了
回复

使用道具 举报

ID:627828 发表于 2019-10-24 14:11 | 显示全部楼层
正好需要,学习下
回复

使用道具 举报

ID:616759 发表于 2019-10-28 09:36 | 显示全部楼层
一楼正解,毕设做的有电机驱动模块,就是用的这个方法,不过我没有用芯片驱动电机,用的三极管
回复

使用道具 举报

ID:652598 发表于 2020-5-20 21:16 | 显示全部楼层

有没有基于模糊pid控制的呀
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表