1. 如何使用单片机精确控制步进电机
如何用单片机控制步进电机
步进电机是机电控制中一种常用的执行机构,它的用途是将电脉冲转化为角位移,通俗地说:当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(及步进角)。通过控制脉冲个数即可以控制角位移量,从而达到准确定位的目的;同时通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。
一、步进电机常识
常见的步进电机分三种:永磁式(PM),反应式(VR)和混合式(HB),永磁式步进一般为两相,转矩和体积较小,步进角一般为7.5度或15度;反应式步进一般为三相,可实现大转矩输出,步进角一般为1.5度,但噪声和振动都很大。在欧美等发达国家80年代已被淘汰;混合式步进是指混合了永磁式和反应式的优点。它又分为两相和五相:两相步进角一般为1.8度而五相步进角一般为0.72度。这种步进电机的应用最为广泛。
二、永磁式步进电机的控制
下面以电子爱好者业余制作中常用的永磁式步进电机为例,来介绍如何用单片机控制步进电机。图1是35BY型永磁步进电机的外形图,图2是该电机的接线图,从图中可以看出,电机共有四组线圈,四组线圈的一个端点连在一起引出,这样一共有5根引出线。要使用步进电机转动,只要轮流给各引出端通电即可。将COM端标识为C,只要AC、C、BC、C,轮流加电就能驱动步进电机运转,加电的方式可以有多种,如果将COM端接正电源,那么只要用开关元件(如三极管),将A、B、轮流接地。列出了该电机的一些典型参数:表135BY48S03型步机电机参数型号步距角相数电压电流电阻最大静转距定位转距转动惯量35BY48S03 7.5 4 12 0.26 47 180 65 2.5 有了这些参数,不难设计出控制电路,因其工作电压为12V,最大电流为0.26A,因此用一块开路输出达林顿驱动器(ULN2003)来作为驱动,通过P1.4~P1.7来控制各线圈的接通与切断。开机时,P1.4~P1.7均为高电平,依次将P1.4~P1.7切换为低电平即可驱动步进电机运行,注意在切换之前将前一个输出引脚变为高电平。如果要改变电机的转动速度只要改变两次接通之间的时间,而要改变电机的转动方向,只要改变各线圈接通的顺序。
2. 求单片机控制步进电机简单的c程序
几相的步进电机啊?用不用驱动芯片?用的话选什么型号的驱动芯片?你要说具体点啊!
先给你三相的,个不用驱动芯片的步进电机程序。(驱动电路自己做)
#include
#define
uchar
unsigned
char
#define
uint
unsigned
int
uint
time
void
timer1(void)
interrupt
1
using
1{
//定时器0中断,定时1ms//
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
time++;
}
void
delay(uint
n){
//一般延时
while(--n);
}
void
delay(uint
dtime){
//延时
TR0=1;
while(time<=dtime);
time=0;
TR0=0;
}
void
moto(bit
cf,uchar
n,uint
dtime){
//电机驱动子程序,
uchar
idata
zhpai[4]={0x78,0xb8,0xd8,0xe8};
uchar
idata
fpai[4]={0xe8,0xd8,0xb8,0x78};
uchar
i,l=0;
if(cf==0)
//正转,A-B-C-A
for(i=0;i<n;i++){
P1=zhpai[l];//P1.7~1.4为输出口,分别为A、B、C、D
l++;
delay(dtime);
if(l==4)l=0;
}
else{
//反转,C-B-A-C
for(i=0;i<n;i++){
P1=fpai[l];
l++;
delay(dtime);
if(l==4)l=0;
}
}
}
void
main(){
TMOD=0x01;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
EA=1;
ET0=1;
while(1){
moto(0,4,70);//正转,转四相,每相间隔70ms
delay(10000);
moto(1,4,70);//反转,转四相,每相间隔70ms
delay(10000);
}
}
改为四相了,你看看吧。不懂再问吧。
3. 51单片机C语言程序按键控制步进电机转速
sbit K1=P1^0;
sbit K2=P1^1;
char y=0;
while(1)
{
pangan();
for(i=0;i<4;i++) //4相
{
/*P1=F_Rotation[i]; //输出对应的相 可以自行换成反转表格
Delay(500); //改变这个参数可以调整电机转速
Delay(5000);*/
P1=B_Rotation[i];
Delay(265+y);
P1=F_Rotation[i];
Delay(265+y);
}
}
void pangan()
{
if(K1==0)
{ y++; //加
while(~k1)
}
if(K2==0)
{ y--;
while(~k2); //减
}
}
}
没有下上限 要是调的话 需要判断显示延时时间
4. 单片机控制步进电机
这是我自己做过的。源码都给你了
#include<reg52.h>
#include<intrins.h>
#include<absacc.h>
#include<string.h>
#define uchar unsigned char
#define uint unsigned int
uint count; //当前计数值
uint distance;
bit intt=1;
unsigned char cont=0;
unsigned char co=0;
uchar buf;
//uchar m,lm,cm;
/**************针脚定义************/
sbit rect_wave=P2^0; //晶振控制信号
sbit RS=P1^0;
sbit RW=P1^1;
sbit EN=P1^2;
sbit CLR=P1^3;
sbit DATA=P1^4;
sbit CLK=P1^5;
sbit d=P2^1;
sbit cp=P2^2;
sbit dir=P2^3;
/***********************************/
/**************函数声明************/
void time0over(void); //定时器计时程序
void clrlcd(void); //clr LCD
void c_send(unsigned char y); //发命令
void reset(void); // reset LCD
void d_send(unsigned char x); //发数据
void pos(unsigned char pos); //设定显示位置
void l_delay(unsigned int t); //长延时
void trans(j);
void ret(void); //初始化系统
void retcont(void); //定时器复位
void math(void); //计算测量距离
/***************************/
void init(void)
{ TH1=0xf3;
TL1=0xf3;
PCON=0x80;
TR1=1;
SCON=0x50; /*串口初始化设置,波特率4800BPS*/
}
//*******************************//
void send(uchar dat) /*发送子程序*/
{ //uchar i;
/*发送一个数据*/
SBUF=dat;
while(TI==0);
TI=0;
}
/***********************************/
void turn (void) //电机转动控制
{
unsigned char x;
cont++;
cp=~cp;
l_delay(50);
cp=~cp;
co++;
if(co == 3)
{d=~d;
}
if(co == 4)
{d=~d;
co=0;
}
if (cont == 200) //判断是否进行反转复位
{dir=~dir;
cont=0;
for(x=0;x < 200;x++)
{cp=~cp;
l_delay(5);
cp=~cp;
co++;
if(co == 3)
{d=~d;
}
if(co == 4)
{d=~d;
co=0;
}
}
dir=~dir;
cont=0;
}
}
/**************子程序**********************/
void int0 () interrupt 0 //中断0服务程序
{
EX0=0; //关闭中断
TR0=0; //关闭定时器
TF0=0; //标志位清零
rect_wave=0; //停止发送超声波
intt=0;
}
void work(void)
{
if(!intt)
{
intt=1;
if (distance < 400)
{
buf=distance;
send(buf);
turn();
math();} //计算所测得的距离
l_delay(5); //延时
retcont(); //定时器复位
rect_wave=1;
count=0;
}
}
void math(void) //计算所测得的距离
{ uchar m,lm,cm;
cm=distance%10; //取距离的最低位
distance=distance/10; //取距离的次高位
lm=distance%10;
distance=distance/10; //取距离的最高位
m=distance%10;
clrlcd(); //输出计算结果
pos(0);
d_send('d');
d_send('i');
d_send('s');
d_send('=');
//pos(4);
d_send(m+0x30);
d_send(lm+0x30);
d_send(cm+0x30);
d_send('c');
d_send('m');
l_delay(500);
}
void time0over(void) //定时器计时程序
{ TF0=0;
count++;
distance=count;
}
/*
void trans(j)
{
switch(j)
{
case 0: d_send('0');break;
case 1: d_send('1');break;
case 2: d_send('2');break;
case 3: d_send('3');break;
case 4: d_send('4');break;
case 5: d_send('5');break;
case 6: d_send('6');break;
case 7: d_send('7');break;
case 8: d_send('8');break;
case 9: d_send('9');break;
}
}
*/
delay() //延时
{
int i;
for(i=0;i<1000;i++);
}
void l_delay(unsigned int t) //延时
{
unsigned int p;
unsigned int j;
for(j=0;j<t;j++)
{
for(p=0;p<1000;p++);
}
}
void reset(void) // reset LCD
{
delay();
c_send(0x38);
c_send(0x01);
c_send(0x06);
c_send(0x0c);
c_send(0x80);
}
void clrlcd(void) // clr LCD
{
delay();
c_send(0x01);
}
void pos(unsigned char pos) //设定显示位置
{
c_send(pos | 0x80);
}
void c_send(unsigned char y) //发命令
{
unsigned char i;
EN=1;
RS=0;
RW=0;
for(i=0;i<8;i++)
{
if(_crol_(y,i)&0x80)
DATA=1;
else
DATA=0;
CLK=0;
CLK=1;
}
EN=0;
delay();
}
void d_send(unsigned char x) //发数据
{
unsigned char i;
EN=1;
RS=1;
RW=0;
for(i=0;i<8;i++)
{
if(_crol_(x,i)&0x80)
DATA=1;
else
DATA=0;
CLK=0;
CLK=1;
}
EN=0;
delay();
}
void ret(void) //初始化计数器
{ TMOD=0x22; //设置定时器计数器1为工作方式2
TH0=0xc6; //设置计数初值高字节
TL0=0xc6; //设置计数初值低字节
count=0;
IE=0x00; //禁止中断
TF0=0; //溢出标志位清零
TR0=1; //打开定时器1
rect_wave=1;
EA=1; //打开中断
IP=0x01; //外部中断0为高中断优先级
IT0=0; //外部中断低电平触发シ?
EX0=1;
}
void retcont(void)
{ TF0=0; //溢出标志位清零
TR0=1; //打开定时器1
EA=1; //打开中断
IP=0x01; //外部中断0为高中断优先级
IT0=0; //外部中断下降沿触发
EX0=1;
rect_wave=1;
}
/**************主程序************/
void main(void)
{ rect_wave=0;
reset();
l_delay(10);
ret();
init();
math();
for(;;)
{
if(TF0)
{
time0over();
}
work();
}
}
5. 一个51单片机同时控制2个步进电机的C语言程序
#include<reg52.h>
#include<intrins.h>
#define mode 0x81 // 方式0,A口、B口输出,C口高4位输出,低4位输入
# include "stdio.h"
# include "string.h"
# include "math.h"
xdata unsigned char PA _at_ 0x7f00;
xdata unsigned char PB _at_ 0x7f01;
xdata unsigned char PC _at_ 0x7f02;
xdata unsigned char caas _at_ 0x7f03; //控制字
sbit P32=P3^2;
sbit P33=P3^3;
sbit P35=P3^5;
#define uchar unsigned char
#define uint unsigned int
unsigned char h,Pos ;
unsigned int R,NX,NY;
unsigned char key;
code unsigned char KeyTable[] = { // 键码定义
0x0f, 0x0b, 0x07, 0x03,
0x0e, 0x0a, 0x06, 0x02,
0x0d, 0x09, 0x05, 0x01,
0x0c, 0x08, 0x04, 0x00
};
code unsigned char LEDMAP[] = { // 八段管显示码
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
};
unsigned char Code_ ; // 字符代码寄存器
#define PD1 61 // 122/2 分成左右两半屏(122x32)
unsigned char Column;
unsigned char Page_ ; // 页地址寄存器 D1,DO:页地址
unsigned char Code_ ; // 字符代码寄存器
unsigned char Command; // 指令寄存器
unsigned char LCDData; // 数据寄存器
xdata unsigned char CWADD1 _at_ 0x1cff; // 写指令代码地址(E1)
xdata unsigned char DWADD1 _at_ 0x1eff; // 写显示数据地址(E1)
xdata unsigned char CRADD1 _at_ 0x1dff; // 读状态字地址(E1)
xdata unsigned char DRADD1 _at_ 0x1fff; // 读显示数据地址(E1)
xdata unsigned char CWADD2 _at_ 0x3cff; // 写指令代码地址(E2)
xdata unsigned char DWADD2 _at_ 0x3eff; // 写显示数进地址(E2)
xdata unsigned char CRADD2 _at_ 0x3dff; // 读状态字地址(E2)
xdata unsigned char DRADD2 _at_ 0x3fff; // 读显示数据地址(E2)
//----------------------液晶-----------------
// 清屏
// ************************ 中文显示程序 ***********************************/
/*************************直线 插 补***************************8*/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=50;y>0;y--);
}
void zhengx()
{
PA=0x00;
delay(10);
PA=0x01;
delay(10);
}
void fux()
{
PA=0x02;
delay(10);
PA=0x03;
delay(10);
}
void zhengy()
{
PB=0x00;
delay(10);
PB=0x10;
delay(10);
}
void fuy()
{
PB=0x20;
delay(10);
PB=0x30;
delay(10);
}
void xian(int NX,int NY)
{int FM, NXY, XOY,ZF,z;
FM=0;
{if(NX>0)
if(NY>0)
XOY=1;
else
XOY=4;
else
if(NY>0)
XOY=2;
else
XOY=3;}
for(NXY= fabs(NX) + fabs(NY)-1;NXY>=0&&P32!=0&&P33!=0;NXY--)
{ {if(NX>0)
if(NY>0)
XOY=1;
else
XOY=4;
else
if(NY>0)
XOY=2;
else
XOY=3;}
for(NXY= fabs(NX) + fabs(NY)-1;NXY>=0;NXY--)
{ if(FM>=0)
{if(XOY==1||XOY==4)
{ZF=1;
zhengx();
}
else
{ZF=2;
fux();
}
FM=FM-fabs(NY);
}
else
{if(XOY==1||XOY==2)
{
ZF=3;
zhengy();
}
else
{ZF=4;
fuy();
}
FM=FM+fabs(NX);
}
}
for(z=0;z<200;z++)
{P35 = 0;
delay(10);
P35 = 1;
delay(10);
}
}
}
/*************************圆 弧 插 补***************************8*/
void yuanhu1( int X0,int Y0, int NX, int NY ,int RNS )
{
int NXY,BS,ZF,XM,YM,z;
int FM=0;
BS=fabs(NX-X0) + fabs(NY-Y0);
XM=fabs(X0);
YM=fabs(Y0);
for(NXY= fabs(NX-X0) + fabs(NY-Y0)-1;NXY>=0&&P32!=0&&P33!=0;NXY--)
{
if(RNS==1||RNS==3||RNS==6||RNS==8)
{
if(FM<0)
{
if(RNS==1||RNS==8)
{ZF=1;
zhengx();
}
else
{ZF=2;
fux();}
FM=FM+2*fabs(XM)+1;
XM=XM+1;
}
else
{
if(RNS==1||RNS==6)
{
ZF=3;
fuy();
}
else
{ZF=4;
zhengy();
}
FM=FM-2*fabs(YM)+1;
YM=YM-1;
}
}
else
if(FM>=0)
{
if(RNS==2||RNS==7)
{ZF=1;
zhengx();
}
else
{ZF=2;
fux();
}
FM=FM-2*fabs(XM)+1;
XM=XM-1;
}
else
{
if(RNS==2||RNS==5)
{ZF=3;
zhengy();}
else
{ZF=4;
fuy();}
FM=FM+2*fabs(YM)+1;
YM=YM+1;
}
}
if(P32==0||P33==0)
{
for(z=0;z<200;z++)
{P35 = 0;
delay(10);
P35 = 1;
delay(10);
}
}
}
int shu1 ()
{
int i=0,j=0,k=3;
while (1)
{
if(testkey())
{ delay(300);
delay1();
if(testkey())
{ j=getkey();
if(j!=14)
{i=i*10 + j;
k--;}
}}
if(k==0)
break;
}
return i;
}
int shu2 ()
{
int i=0,j=0,k=3;
while (1)
{
if(testkey())
{ delay(300);
delay1();
if(testkey())
{ j=getkey();
if(j!=14)
{i=i*10 + j;
k--;}
}}
if(k==0)
break;
}
return i;
}
void yuanhuchabu1()
{ int q=0;
delay(300);
R=shu1();
yj1();
q=R/100;
Page_ = 0x00;
Column = 0x35;
Code_ = q;
WriteCHN8x16();
q=R%100;
q=q/10;
Page_ = 0x00;
Column = 0x40;
Code_ = q;
WriteCHN8x16();
q=R%10;
Page_ = 0x00;
Column = 0x48;
Code_ = q;
WriteCHN8x16();
yuanhu1(R,0,0,R,5);
yuanhu1(0,R,-R,0,6);
yuanhu1(-R,0,0,-R,7);
yuanhu1(0,-R,R,0,8);
}
void yuanhuchabu2()
{ int q=0;
delay(300);
R=shu1();
yj1();
q=R/100;
Page_ = 0x00;
Column = 0x35;
Code_ = q;
WriteCHN8x16();
q=R%100;
q=q/10;
Page_ = 0x00;
Column = 0x40;
Code_ = q;
WriteCHN8x16();
q=R%10;
Page_ = 0x00;
Column = 0x48;
Code_ = q;
WriteCHN8x16();
yuanhu1(0,R,R,0,1);
yuanhu1(R,0,0,-R,4);
yuanhu1(0,-R,-R,0,3);
yuanhu1(-R,0,0,R,2);
}
void xianchabu()
{ int q1=0,q2=0;
delay(300);
NX=shu1();
delay(300);
NY=shu2();
yj2();
Page_ = 0x00;
Column = 0x25;
Code_ = 0x10;
WriteCHN8x16();
q1=NX/100;
Page_ = 0x00;
Column = 0x30;
Code_ = q1;
WriteCHN8x16();
q1=NX%100;
q1=q1/10;
Page_ = 0x00;
Column = 0x37;
Code_ = q1;
WriteCHN8x16();
q1=NX%10;
Page_ = 0x00;
Column = 0x40;
Code_ = q1;
WriteCHN8x16();
q2=NY/100;
Page_ = 0x00;
Column = 0x50;
Code_ =q1;
WriteCHN8x16();
q2=NY%100;
q2=q2/10;
Page_ = 0x00;
Column = 0x58;
Code_ = q2;
WriteCHN8x16();
q2=NY%10;
Page_ = 0x00;
Column = 0x60;
Code_ = q2;
WriteCHN8x16();
Page_ = 0x00;
Column = 0x72;
Code_ = 0x11;
WriteCHN8x16();
xian(NX,NY );
}
void main()
{ int q=0,q1=0,q2=0;
caas=mode;
PA=0X00;
PB=0X00;
PC=0x00;
R=0X00;
while(1)
{
if(testkey())
{
delay1();
if(testKey())
{ delay1();
if(getkey()==15)
{
delay(300);
yuanhuchabu1();
}
else if(getkey()==10)
{ delay(300);
yuanhuchabu2();
}
else if(getkey()==13)
{
xianchabu();
}
else if(getkey()==1)
{
zhengx();
}
else if(getkey()==2)
{
fux();
}
else if(getkey()==3)
{
zhengy();
} else if(getkey()==4)
{
fuy();
}
}
}
if(GetKey()==12)
{ break;}
}
}
6. 关于51单片机控制步进电机编程(c语言),求助
#include<reg52.h>
#defineucharunsignedchar
#defineuintunsignedint
ucharkey_l,key,i;
ucharcodetemp1[]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};
ucharcodetemp2[]={0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01};
ucharcodeaa[16]=":";
ucharcodesmg[]="";
sbite=P2^6;
sbitrs=P2^4;
sbitrw=P2^5;
voiddelay(inttt)
{
while(tt--);
}
voidw_cmd(uchardd)
{
rs=0;
rw=0;
e=0;
delay(50);
P0=dd;
e=1;
delay(50);
e=0;
delay(50);
}
voidw_dat(uchardd)
{
rs=1;
rw=0;
e=0;
delay(50);
P0=dd;
e=1;
delay(50);
e=0;
}
voidinit(ucharsmg4[],uchartime[])
{
w_cmd(0x38);
delay(2000);
w_cmd(0x38);
delay(500);
w_cmd(0x38);//注意顺序,设置工作方式,显示模式设置
delay(500);
w_cmd(0x08);//注意顺序,关闭显示
w_cmd(0x01);//清屏
w_cmd(0x07);//光标·画面滚动模式设置
w_cmd(0x0c);//显示及光标模式设置
w_cmd(0x80);//
for(i=0;i<16;i++)
w_dat(time[i]);
w_cmd(0x80+0X40);
for(i=0;i<16;i++)
w_dat(smg4[i]);
}
voidTb(ucharsmg[],ucharn,uchars,ucharl,uchard)
{
unsignedcharm;
w_cmd(0x82);
for(m=n;m<s;m++)
w_dat(smg[m]);
w_cmd(0x80+0X42);
for(m=l;m<d;m++)
w_dat(smg[m]);
}
voidmain()
{
init(aa,aa);
while(1)
{
P1=0xf0;
key_l=P1;
if(key_l!=0xf0)
{
delay(100);
if(key_l!=0xf0)
{
P1=key_l|0x0f;
key=P1;
}
}
switch(key)
{
case0xee:Tb(smg,0,10,11,21);
for(i=0;i<8;i++)
{
P2=temp1[i];
delay(500);
}
break;
case0xde:Tb(smg,0,10,19,29);
for(i=0;i<8;i++)
{
P2=temp1[i];
delay(300);
}
break;
case0xbe:Tb(smg,0,10,30,40);
for(i=0;i<8;i++)
{
P2=temp1[i];
delay(100);
}
break;
case0x7e:P2=0xff;Tb(smg,0,10,39,49);break;
case0xed:Tb(smg,50,60,11,21);
for(i=0;i<8;i++)
{
P2=temp2[i];
delay(200);
}
break;
case0xdd:Tb(smg,50,60,19,29);
for(i=0;i<8;i++)
{
P2=temp2[i];
delay(120);
}
break;
case0xbd:P2=0xff;Tb(smg,50,60,40,50);break;
}
}
}