标题:
用51单片机控制两相四线步进电机
[打印本页]
作者:
rubiks
时间:
2015-11-16 23:31
标题:
用51单片机控制两相四线步进电机
最近学习步进电机的驱动原理,照着教材自己实践了一下用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();
}
}
}
}
作者:
路人。
时间:
2017-2-15 20:23
楼主uchar code 是怎么定义的?
作者:
朱青竹
时间:
2017-5-3 07:07
你那个按键不能识别吧
作者:
dfds
时间:
2018-1-3 15:49
请问转动的时候震动严重什么问题
作者:
AAAAAA666666
时间:
2018-3-9 17:27
能分享一下,接线图吗?
作者:
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--)其他不变,这样改不知道在单片机编程中是否合规。
为什么会考虑这个问题呢?
当需要循环计算指定角度步数的时候,需要累加循环次数,每八拍丢一步,实际上道最后差别就大了。
不知道我的思路对不对,希望楼主指点。
谢谢!
作者:
gfshao
时间:
2020-9-15 13:56
i=8 和i=0开始是一样的计数次数的
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1