找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 16233|回复: 6
收起左侧

用51单片机控制两相四线步进电机

  [复制链接]
rubiks 发表于 2015-11-16 23:31 | 显示全部楼层 |阅读模式
最近学习步进电机的驱动原理,照着教材自己实践了一下用ULN2003驱动28BYJ-48两相5线步进电机,可以正常转动。手头有一个旧光驱,拆开发现里面有三个电机,其中有一个控制激光头寻迹的两相四线步进电机,我就用51的单片机让它也转起来。一开始照葫芦画瓢用ULN2003驱动,结果发现无论如何也不行。原来ULN2003基本没输出电流,只能驱动有公共端的两相五线、两相六线步进电机,不能驱动2相4线步进电机。然后改用L293D驱动,可以转动。通过按钮控制正反转时发现,按键释放后,电机迅速发热,烫手。用万用表测量,发现电机A,A-或B,B-直接存在电位差!应该是按键释放时,IN1-IN4没有归零。找到问题,就容易解决了。修改程序,可以完美运行,键1按下正转,释放停下,键2按下反转,释放停下。IN1-IN4分别接P1口的低四位。工作方式选用8拍。
A       1     1     0     0     0     0     0     1
A-      0     0     0     1     1     1     0     0
B       0     1     1     1     0     0     0     0
B-      0     0     0     0     0     1     1     1
附上源程序,仅供参考。
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit K3=P2^5;
sbit K4=P2^4;
//k3正转。k4反转。释放停止
uchar code step_table[]={0x8,0xa,0x2,0x6,0x4,0x5,0x1,0x9};
void delay(unsigned int m)
    {
      unsigned int i,j;
      for(i=m;i>0;i--)
       for(j=110;j>0;j--);
         }
void xp()//x轴正转
{
while(!K3)
        {
                        uint i;
                for(i=0;i<8;i++)
                {
                        P1=step_table[ i];
                        delay(10);
                }
        
        }
P1=0;//按键释放时,反转P1停在table某处,导致电机有电压从而使电机发热,需要归零。
}
void xn()//x轴反转
{
                        uint i;
while(!K4)
        {
                for(i=8;i>0;i--)
                {
                        P1=step_table[ i];
                        delay(10);
                }
        
        }
P1=0;//按键释放时,反转P1停在table某处,导致电机有电压从而使电机发热,需要归零。
}
void main()
{
while(1)
{
                if(K3==0)
                {
                        delay(20);
                        if(K3==0)
                        {
                //        LED1=0;
                        xp();
                        }
                }
                if(K4==0)
                {
                        delay(20);
                        if(K4==0)
                        {
                //        LED1=0;
                        xn();
                        }
                }

}
}

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的积分奖励!

查看全部评分

回复

使用道具 举报

Jeff_BlindCat 发表于 2020-7-9 00:09 | 显示全部楼层
楼主你好,我在调试你这个程序的时候发现了一个疑问,不知道是否可商榷?
在X轴反转函数里面
void xn()//x轴反转
{
                        uint i;
while(!K4)
        {
                for(i=8;i>0;i--)
                {
                        P1=step_table[ i];
                        delay(10);
                }

这个for循环for(i=8;i>0;i--)可以调试通,但是反转实际运行步数是少一步的,这样会不会有丢步现象。


这是地址数组真值表:
uchar code step_table[]={0x8,0xa,0x2,0x6,0x4,0x5,0x1,0x9};
数组循环i++是正确,因为X轴正转的for循环是i++:for(i=0;i<8;i++)
数组的下标是从零开始,这样八位table取值是0,1,2,3,4,5,6,7,刚好匹配,


==========================重点
在反转中采用for循环i--:for(i=8;i>0;i--),
当第一次循环取的数值是step_table[i=8],实际上这已经数组越界,但是越界为什么会能转,因为只有几十毫秒的通电循环,可能堵转,这样第二步(step_table[i=7]是倒叙数组表也就是取的正传最后一位是正确的)当循环到step_table[i=0]时,因为判断条件是i>0,这样正转第一步也就是i=0是不赋值的,出现舍弃现象, X轴反转函数P1=step_table[0]是不执行的;会不会出现丢步?

===========================测试过程
按照这个思路修改调试:
先修改反转循环for(i=7;i>=0;i--),调试运行到最后一步I=0第一次可以,随后下一步出现堵转,
跟踪发现:在反转函数中,当i=0循环完毕后随后下一步,会出现随机数整数,在看开始定义约定。

unsigned int i,j;
这个unsigned 参数类型约定了无符号整形,查询一部分文档才发现无符号随机数的跳转,因为不同于数组赋值真值表,所以出现堵转。

按照保险的做法,又声明一个反转数组,只是把位置颠倒过来:
正转:uchar code step_table[]={0x8,0xa,0x2,0x6,0x4,0x5,0x1,0x9};
反转:uchar code step_table[]={0x9,0x1,0x5,0x4,0x6,0x2,0xa,0x8};
然后反转for循环是i++:for(i=0;i<8;i++)
这样步数同步了。
还一种方法,声明i参数不要unsigned 无符号声明,原来您的代码只是修改为for(i=7;i>=0;i--)其他不变,这样改不知道在单片机编程中是否合规。

为什么会考虑这个问题呢?
当需要循环计算指定角度步数的时候,需要累加循环次数,每八拍丢一步,实际上道最后差别就大了。

不知道我的思路对不对,希望楼主指点。
谢谢!
回复

使用道具 举报

路人。 发表于 2017-2-15 20:23 来自手机 | 显示全部楼层
楼主uchar code 是怎么定义的?
回复

使用道具 举报

朱青竹 发表于 2017-5-3 07:07 来自手机 | 显示全部楼层
你那个按键不能识别吧
回复

使用道具 举报

dfds 发表于 2018-1-3 15:49 | 显示全部楼层
请问转动的时候震动严重什么问题
回复

使用道具 举报

AAAAAA666666 发表于 2018-3-9 17:27 | 显示全部楼层
能分享一下,接线图吗?
回复

使用道具 举报

gfshao 发表于 2020-9-15 13:56 | 显示全部楼层
i=8 和i=0开始是一样的计数次数的

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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