Ⅰ 51單片機控制步進電機
這個簡單,讓我來教樓主怎麼玩
首先我說下思路:
我們採用P1口來採集ADC0832的8位數據,用P0.0口控制步進電機動作,利用T0的時間中斷來採集P1口的ADC0832數據並做出比較後設置步進電機啟動標志位start=1;並設置他的運行頻率,當然,樓主沒說怎麼比較,我這就只是寫了個簡單的例子,一通百通,希望對你有幫助
下面是程序:
#include <reg51.h> //選用晶振11.0592MHz
unsigned int m=0,n=0; //設置循環的周期
unsigned char start=0,t0temp=0;
sbit Y0=P0^0; //控制步進電機的管腳
delay()
{
unsigned char i,j;
for(i=m;i>0;i--)
for(j=n;i>0;j--);
}
main()
{
//自檢測T0時間設置
ET0=1;
TMOD|=0x01;
TH0=0XFC; //1ms中斷掃描
TL0=0X66;
IT0=1; //下降沿觸發
TR0=0; //關閉掃描
/***********************初始化完畢***********************/
//****************I/O口程序
while(1)
{
while(start)
{
delay();
Y0=~Y0;
}
}
}
void counter1(void) interrupt 1 //T0計時器中斷
{
if(t0temp%4)t0temp++; //4ms時間才採集一次P0口的數據
else
{
t0temp++;
//這里就寫你怎麼做對比的程序,我舉個例子
if(P1>150)
{start=1;n=1000;m=0;} //入錯採用12M晶振,那這時候控制步進電機的輸出周期就是1ms一次,也就是1000HZ
else {start=0;n=0;m=0;}
}
}
//PS:我在輸出頻率中用了兩個全局變數m,n可以延遲很長時間,樓主可以根據需要選用,一般16位的,選用一個就可以了,另一個放棄
OK,至於電路圖,我軟體沒有ADC0832的封裝,不然就發給你了,但想來樓主完全就沒必要擔心,ADC0832的8位數據接到P1口,P0.0控制步進電機啟動的三極體,電路圖就那麼簡單!
Ⅱ 基於51單片機的步進電機控制器
給你個程序看看能不能用?呵呵
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar fzhuan[]={0x03,0x01,0x09,0x08,0x0c,0x04,0x06,0x02};
uchar zzhuan[]={0x02,0x06,0x04,0x0c,0x08,0x09,0x01,0x03};
sbit P00=P0^0;
sbit P01=P0^1;
uchar temp;
uint i;
void delay()
{ uint i,j;
for(i=50;i>0;i--)
{for(j=100;j>0;j--);}}
main()
{ P0=0x03;
while(1)
{ if(P00==0)
{do
{ P1=zzhuan[i];
delay();
i++;
if(i==8)
{i=0;}
}while(P00==0);}
else if(P01==0)
{ do
{ P1=fzhuan[i];
delay();
i++;
if(i==8)
{i=0;}
}while(P01==0); }
}
}
模擬電路圖傳不上去!!!
Ⅲ 一個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;}
}
}
Ⅳ 51單片機控制直流電機和步進電機
其實一般步進電機使用ULN2003驅動的,直流電機一般用(H橋)L298N來驅動
如果你想方便一點L298N也能驅動步進電機
L298N有那種一個小板的電路跟第一個電路的區別就是沒有電機,其它都有,你看著辦吧!!
Ⅳ 跪求 51單片機控制步進電機
//兩相5、6線步進電機,分為四拍和八拍,這里介紹輸出八拍方式:A-AC-C-CB-B-BD-D-DA
//四拍:A-C-B-D,因此在八拍的基礎上減去中間的就可以了,不過步距角要大一倍
#include <reg51.h>
#include <intrins.h>
sbit la=P2^0; //定義兩相電機的四組線,從板上設計來分配,選擇P2口的低四位輸出,相應的輸出也可以反應在LED燈上
//P2。0為A相,P2。1為B相,P2。2為C相,P2。3為D相
sbit lb=P2^1;
sbit lc=P2^2;
sbit ld=P2^3;
#define uchar unsigned char
code unsigned int lhj[]={1,50,100,1,50,80,1,100,50,0,120,40,0,30,80,0,50,100,
1,50,120,0,200,80,1,400,20,1,50,130,0,200,90,0,50,150};
//定義電機動作的參數,每三個數為一組,第一個是方向(1、正轉,0、反轉)
//第二個是步進量,第三個是轉速
unsigned char key();//鍵盤動作,這里的鍵盤掃描只用到四個按鍵有效(板上標的0,4,8,C)
unsigned char right(unsigned int Speed,unsigned int road); //正轉
unsigned char left(unsigned int Speed,unsigned int road); //反轉
void mDelay(unsigned int DelayTime); //延時函數
void main()
{
uchar i=0;
while(1){
if(key()==0xde){//8的按鍵按下
for(i=0;i<34;i+=3){//循環輸出我們定義好的動作數據
if(lhj[i]) //調入數組,先判斷正反轉
right(lhj[i+1],lhj[i+2]); //兩個參數代表步進量和轉速
else
left(lhj[i+1],lhj[i+2]);
if(key()==0xee)//C的按鍵按下
break;
}
}
}
}
unsigned char right(unsigned int Speed,unsigned int road)//兩個參數代表步進量和轉速
{
//步進節拍:A-AC-C-CB-B-BD-D-DA
while(1){
if(!Speed) //判斷步進量走完沒?以下都是,每走一步,判斷一次
break;
ld=1;
la=0; //a
mDelay(road);//這里的延時就可控制轉速
if(!Speed--)
break;
lc=0; //ac
mDelay(road);
if(!Speed--)
break;
la=1; //c
mDelay(road);
if(!Speed--)
break;
lb=0; //cb
mDelay(road);
if(!Speed--)
break;
lc=1; //b
mDelay(road);
if(!Speed--)
break;
ld=0; //bd
mDelay(road);
if(!Speed--)
break;
lb=1; //d
mDelay(road);
if(!Speed--)
break;
la=0; //da
mDelay(road);
Speed--;
}
P3=P3|0x0f;//將四個腳輸出置高
}
unsigned char left(unsigned int Speed,unsigned int road)//兩個參數代表步進量和轉速
{
//步進節拍A-AD-D-DB-B-BC-C-CA
while(1){
if(!Speed)//判斷步進量走完沒?以下都是,每走一步,判斷一次
break;
lc=1;
la=0; //a
mDelay(road);
if(!Speed--)
break;
ld=0; //ad
mDelay(road);
if(!Speed--)
break;
la=1; //d
mDelay(road);
if(!Speed--)
break;
lb=0; //db
mDelay(road);
if(!Speed--)
break;
ld=1; //b
mDelay(road);
if(!Speed--)
break;
lc=0; //bc
mDelay(road);
if(!Speed--)
break;
lb=1; //c
mDelay(road);
if(!Speed--)
break;
la=0; //ca
mDelay(road);
Speed--;
}
P3=P3|0x0f;//將四個腳輸出置高
}
void mDelay(unsigned int DelayTime) //延時函數
{
unsigned char j=0;
while(DelayTime--){
for(j=0;j<10;j++){}
}
}
unsigned char key()//鍵盤掃描是否有鍵按下,這里只掃描一列四個鍵,其它不用
{
uchar KeyV;
P0=0xfe;
KeyV=P0;
if(KeyV==0xfe)//只掃描一列
return(0);
mDelay(100);
KeyV=P0;
if(KeyV==0xfe)
return(0);
else
return(KeyV);
}
請將p2口改為p0口
Ⅵ 51單片機, 編一個控制步進電機轉動的程序。
#include <reg51.h> //51晶元管腳定義頭文件
#include <intrins.h>//內部包含延時函數 _nop_();
#define uchar unsigned char
#define uint unsigned int
uchar code FFW[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9};
uchar code REV[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1};
/********************************************************/
/*
/* 延時t毫秒
/* 11.0592MHz時鍾,延時約1ms
/*
/********************************************************/
void delay(uint t)
{
uint k;
while(t--)
{
for(k=0; k<125; k++)
{ }
}
}
/********************************************************/
/*
/*步進電機正轉
/*
/********************************************************/
void motor_ffw(uint n)
{
uchar i;
uint j;
for (j=0; j<12*n; j++) //轉1×n圈
{
for (i=0; i<8; i++) //一個周期轉30度
{
P1 = FFW[i]; //取數據
delay(15); //調節轉速
}
}
}
/********************************************************/
/*
/*步進電機反轉
/*
/********************************************************/
void motor_rev(uint n)
{
uchar i;
uint j;
for (j=0; j<12*n; j++) //轉1×n圈
{
for (i=0; i<8; i++) //一個周期轉30度
{
P1 = REV[i]; //取數據
delay(15); //調節轉速
}
}
}
/********************************************************
*
* 主程序
*
*********************************************************/
main()
{
while(1)
{
motor_ffw(5); //電機正轉
delay(5000); //換向延時
//motor_rev(5); //電機反轉
//delay(1000); //換向延時
}
}
/********************************************************/
Ⅶ 如何用51單片機PWM控制3個步進電機
用單片機同時是不可能的,當然,時間間隔小到可以接受,跑幾個任務,那也可以視為同時。要實現真正意義上的同時,用FPGA/CPLD是可以完成的。
話說回來,也許你的同時並不是說一定嚴格地同時工作,只是說一個單片機去控制四個步進電機,那就好辦多了。
一個步進電機,比如4相5線那種,4個IO口可控制一個,四個步進電機就要16個,驅動晶元用ULN2003即可。
當然,如果你的IO口不允許使用這么多,那也可以通過串轉並的方法,擴展IO口,比如用74HC595,三根IO口控制它,它可以級聯,三根線可以控制很多片。一片為8位,兩片就為16位,3片為24位 ……
Ⅷ 如何用51單片機控制4個步進電機
控制一個步進電機只需要三個引腳。51控制四個完全夠用。
Ⅸ 關於51單片機控制步進電機
看不懂!
2003前面需不需要接光耦,是根據你的電路來說的,它主要是搞干擾和解決電壓不一致而用來隔離電源的。
你的步進電機和控制線路板電源如果共地,我常覺得就沒有必要接了,因為干擾信號還會通過地線傳到控制部分。
如果說要接的話,4N25和2003輸入端之間肯定是要加個電阻的,限流嗎!,1K就行,而且在1K電阻與2003輸入端最好接一個4.7K電阻,4.7K電阻的另一端接地線,這樣,在4N25不工作的情況下,通過4.7K電阻將2003輸入端接地。
2003的內部是一組達林頓管,你可以理解為放大倍數很高的三極體,你用到的控制極就是其基極,所以,它有0.7V電壓就可以工作了。但一般在使用時,還是要保證提供2V以上,不然可能不會很可靠。
最後一個問題我看不明白,什麼叫承受4N25的電壓?它們是串聯的,所以最多叫能否承受電流!這可以通過上面串1K電阻解決!