|
以下是悬挂运动控制系统的程序,如何让步进电机走直线(水平线,垂直线,斜线)?
#include "reg52.h"
#include "math.h"
sbit P1_0=P1^0;//A步进电机端口
sbit P1_1=P1^1;//A步进电机端口
sbit P1_2=P1^2;//A步进电机端口
sbit P1_3=P1^3;//A步进电机端口
sbit P1_4=P1^4;//B步进电机端口
sbit P1_5=P1^5;//B步进电机端口
sbit P1_6=P1^6;//B步进电机端口
sbit P1_7=P1^7;//B步进电机端口
bit atzqd=0; //A电机停止启动 默认停止
bit btzqd=0; //B电机停止启动 默认停止
bit fz=0; //是否给x,y赋值 默认否
bit qr=0; //赋值后是否确认 默认否
unsigned char m,n,k,g,u=1,v=1;
float a=0; //计算得到的A电机步数
float b=0; //计算得到的B步进电机的步数
float L1,L2,L3,L4; //定义线的长度
bit azf=0; //A运转方向
bit bzf=0; //B运转方向
bit yx=1; //按键重复允许 默认否
float r; //给x,y赋值的中间变量
unsigned char p=0,q=0; //赋值和确认中间标志
float x1=0,x2=0; //x坐标
float y1=0,y2=0; //y坐标
int s=20;//定义转动速度,数值越大电机转速越慢反之则快
code unsigned char arunz[4]={0xef,0xdf,0xbf,0x7f}; //A电机正转
code unsigned char arunf[4]={0x7f,0xbf,0xdf,0xef}; //A电机反转
code unsigned char brunf[4]={0xfe,0xfd,0xfb,0xf7}; //B电机正转
code unsigned char brunz[4]={0xf7,0xfb,0xfd,0xfe}; //B电机反转
//unsigned char code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
void delay10ms(void) //延时程序 键盘的延时
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
void delay(m)//延时函数 步进电机的延时
{
for(n=0;n
for(k=0;k<50;k++);
}
void azrun()// A正转运行
{
for(g=0;g<4;g++)
{
P1=arunz[g];
delay(s);
}
}
void afrun()// A反转运行
{
for(g=0;g<4;g++)
{
P1=arunf[g];
delay(s);
}
}
void bzrun()// B正转运行
{
for(g=0;g<4;g++)
{
P1=brunz[g];
delay(s);
}
}
void bfrun()// B反转运行
{
for(g=0;g<4;g++)
{
P1=brunf[g];
delay(s);
}
}
void fuzhi() //x,y赋值函数
{
if(q==0) //起点x的值
{
if(p==0) x1=r; //一位数
if(p==1) x1=x1*10+r; //两位数
p++;
}
if(q==1) //起点y的值
{
if(p==0) y1=r; //一位数
if(p==1) y1=y1*10+r; //两位数
L1=sqrt((x1+3)*(x1+3)+(43-y1)*(43-y1)); //求L1长度
L2=sqrt((43-x1)*(43-x1)+(43-y1)*(43-y1)); //求L2长度
p++;
}
if(q==2) //终点x的值
{
if(p==0) x2=r; //一位数
if(p==1) x2=x2*10+r; //两位数
p++;
}
if(q==3) //终点y的值
{
if(p==0) y2=r; //一位数
if(p==1) y2=y2*10+r; //两位数
L3=sqrt((x2+3)*(x2+3)+(43-y2)*(43-y2)); //求L3长度
L4=sqrt((43-x2)*(43-x2)+(43-y2)*(43-y2)); //求L4长度
if(L3>L1) {azf=1;a=12*(L3-L1);} //
if(L3
if(L4>L2) {bzf=1;b=12*(L4-L2);} //
if(L4
p++;
}
fz=0; //运行完毕后跳出
}
void queren() //确认函数 每输入一个坐标点的x或y值就确认一下
{
p=0;
q++;
if(q==4) q=0;
qr=0; //运行完毕后跳出
}
void Getch() //矩阵键盘程序
{
unsigned char X,Y,Z;
P2=0xff;
P2=0x0f; //先对P2置数 行扫描
if(P2!=0x0f) //判断是否有键按下
{delay10ms(); //延时,软件去干扰
if(P2!=0x0f) //确认按键按下X = P2;
{
X=P2; //保存行扫描时有键按下时状态
P2=0xf0; //列扫描
Y=P2; //保存列扫描时有键按下时状态
Z=X|Y; //取出键值
switch(Z) //判断键值(那一个键按下)
{
case 0xee: {if(yx==1){r=0;fz=1;yx=0;}} ; break; //0对键值赋值
case 0xde: {if(yx==1){r=1;fz=1;yx=0;}} ; break; //1
case 0xbe: {if(yx==1){r=2;fz=1;yx=0;}} ; break; //2
case 0x7e: {if(yx==1){r=3;fz=1;yx=0;}} ; break; //3
case 0xed: {if(yx==1){r=4;fz=1;yx=0;}} ; break; //4
case 0xdd: {if(yx==1){r=5;fz=1;yx=0;}} ; break; //5
case 0xbd: {if(yx==1){r=6;fz=1;yx=0;}} ; break; //6
case 0x7d: {if(yx==1){r=7;fz=1;yx=0;}} ; break; //7
case 0xeb: {if(yx==1){r=8;fz=1;yx=0;}} ; break; //8
case 0xdb: {if(yx==1){r=9;fz=1;yx=0;}} ; break; //9
case 0xbb: {if(yx==1){qr=1;yx=0;}} ; break; //A
case 0x7b: {if((yx==1)&&(q==0)){atzqd=1;btzqd=1;yx=0;}} ; break; //B
case 0xe7: {azf=0;azrun();P1=0Xff;}; break; //C
case 0xd7: {azf=1;afrun();P1=0Xff;}; break; //D
case 0xb7: {bzf=0;bfrun();P1=0Xff;}; break; //E
case 0x77: {bzf=1;bzrun();P1=0Xff;}; break; //F
}
}
}
else yx=1;
}
void yunxing() //步进电机运行函数
{
unsigned char i,j;
if(atzqd==1) //A步进电机
{
if(a>0) //步骤未走完
for(i=u;i>0;i--){
if(azf==0) azrun(); //正转
if(azf==1) afrun(); //反转
a--;
}
else { //步骤已走完
atzqd=0;
P1=0xff; //端口置1,防止电流过大
}
}
if(btzqd==1) //B步进电机
{
if(b>0) //步骤未走完
for(j=v;j>0;j--){
if(bzf==0) bzrun(); //正转
if(bzf==1) bfrun(); //反转
b--;
}
else { //步骤已走完
btzqd=0;
P1=0xff; //端口置1,防止电流过大
}
}
if(a>b){u=a/b;v=1;}
if(a
}
void main(void)
{
while(1)
{
Getch();
if(fz==1) fuzhi();
if(qr==1) queren();
yunxing();
}
}
|
|