‘壹’ 一个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单片机控制步进电机
这个简单,让我来教楼主怎么玩
首先我说下思路:
我们采用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单片机PWM控制3个步进电机
用单片机同时是不可能的,当然,时间间隔小到可以接受,跑几个任务,那也可以视为同时。要实现真正意义上的同时,用FPGA/CPLD是可以完成的。
话说回来,也许你的同时并不是说一定严格地同时工作,只是说一个单片机去控制四个步进电机,那就好办多了。
一个步进电机,比如4相5线那种,4个IO口可控制一个,四个步进电机就要16个,驱动芯片用ULN2003即可。
当然,如果你的IO口不允许使用这么多,那也可以通过串转并的方法,扩展IO口,比如用74HC595,三根IO口控制它,它可以级联,三根线可以控制很多片。一片为8位,两片就为16位,3片为24位 ……
‘肆’ 51单片机控制直流电机和步进电机
其实一般步进电机使用ULN2003驱动的,直流电机一般用(H桥)L298N来驱动
如果你想方便一点L298N也能驱动步进电机
L298N有那种一个小板的电路跟第一个电路的区别就是没有电机,其它都有,你看着办吧!!
‘伍’ 求51单片机控制步进电机程序
;//****************************************************************
;//*文件名: StepM FOR 51MCU
;功能: 开关控制步进电机的正转、反转和停止。
;接线: 用导线对应连接步进电机模块的SMA~SMD到CPU模块的P10~P13,
; 八位逻辑电平输出的K0~K2对应连接CPU模块的P15~P17。
;//****************************************************************
;K0——停止
;K1——正转
;K2——反转
ORG 0000
LJMP START
ORG 0100H
START:
LOOP: MOV P1,#00H ; 步进电机停止
ORL P1,#0E0H
MOV A,P1
JNB ACC.5,STOP ; 停止
JNB ACC.6,FOR ; 正转
JNB ACC.7,rev ; 反转
JMP LOOP ;
FOR: MOV R0, #00H ; 正转到tab取码指针初值
for1: MOV A,R0 ; 取码
MOV DPTR,#TABLE ;
MOVC A,@A+DPTR
JZ LOOP ; 是否到了结束码00h
CPL A ;把acc反向
MOV P1,A ;输出到p1开始正转
CALL DELAY ;转动的速度
INC R0 ;取下一个码
JMP FOR1 ;继续正转
rev: MOV R0,#0AH ;反转到tab取码指针初值
rev1: MOV A,R0
MOV DPTR,#TABLE ;取码
MOVC A,@A+DPTR
JZ LOOP ;是否到了结束码00h
CPL A ;把acc反向
MOV P1,A ;输出到p1开始反转
CALL DELAY ;转动的速度
INC R0 ;取下一个码
JMP REV1 ;继续反转
stop:
MOV P1, #00H
JMP LOOP
DELAY: MOV R1,#150 ;步进电机的转速20ms
D1: MOV R2,#248
DJNZ R2,$
DJNZ R1,D1
RET
TABLE:
db 01h,03h,02h,06h,04h,0ch,08h,09h ;正转表
db 00 ;正转结束
db 01h,09h,08h,0ch,04h,06h,02h,03h ;反转
db 00 ;反转结束
END
‘陆’ 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控制
‘捌’ 如何用51单片机控制4个步进电机
控制一个步进电机只需要三个引脚。51控制四个完全够用。
‘玖’ 如何实现51单片机控制四个步进电机工作
最好是使用单片机+专用运动控制芯片来做,毕竟单片机程序是按顺序的,很难各自独立,带上专用芯片就不一样了,可以独立控制,互不干扰,比如hmc8043,用起来很方便