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;
}
}
}