如何限定步进电机只在一个角度内转动?

 

 //功能:控制步进电机活动范围在90度以内,在此区间内,通过光电管控制步进电机的正反转:光电管被遮挡反转,无遮挡正转。
 #include <reg52.h>
#include <intrins.h>
#define	uchar unsigned char
#define uint unsigned int
sbit motor = P1^0;//位定义电机脉冲信号端口
sbit block = P1^1;  //位定义接收光电开关遮挡信号的端口
sbit dir = P1^2;//位定义步进电机方向控制端口
sbit WE = P2^7;
sbit DU = P2^6;	
sbit stop = P1^3;
sbit beep = P2^3;
uchar i;	   //电机转动角度,i = 1 表示转动1.8度 
uint maxSum = 1600;	   //步进电机能转到的最大步数,一步为1.8度
int sumDegree;		   //记录电机转过的角度数

void delay(void)   //误差 -0.217013888889us
{
    uchar a,b;
    for(b=20    ;b>0;b--)		//初值80
        for(a=10;a>0;a--);
}

//void delay_ms(uchar i)   //误差 -0.000000000227us,延时0.1秒
//{
//    uchar a,b,c;
//    for(c=13*i;c>0;c--)
//        for(b=247;b>0;b--)
//            for(a=142;a>0;a--);
//    _nop_;  //if Keil,require use intrins.h
//}

void motor_degree(uchar i)	   // i取值0-255
{
	dir = 0;	 //方向设置为正转
	while(i--)		//i个脉冲,步进电机转动i*1.8度
	{
		motor = 0;
		delay();
		motor = 1;
		delay();		//1个脉冲,步进电机转动1.8度	
	}
}

void invert_motor_degree(uchar i)	// i取值0-255
{
 	dir = 1; //方向设置为反转
	while(i--)		 //i个脉冲,步进电机转动i*1.8度
	{
		motor = 0;
		delay();
		motor = 1;
		delay();	  //1个脉冲,步进电机转动1.8度
	}
}
void InitShumaguan()
{
 	WE = 1;	  //打开位选锁存器
	P0 = 0xfe;	 //选中第一位数码管1111 1110
	WE = 0;  //	  锁存位选数据
}

void shumaguanShow1()
{
	WE = 1;	  //打开位选锁存器
	P0 = 0xfe;	 //选中第一位数码管1111 1110
	WE = 0;  //	  锁存位选数据

	DU = 1;
	P0 = 0x06;	 
	DU = 0;
//	beep = 0;  //报警提示
}

void shumaguanShow0()
{
	WE = 1;	  //打开位选锁存器
	P0 = 0xfe;	 //选中第一位数码管1111 1110
	WE = 0;  //	  锁存位选数据

	DU = 1;
	P0 = 0x3f;	 
	DU = 0;
//	beep = 1;
}

void shumaguanShowError()
{
    WE = 1;	  //打开位选锁存器
	P0 = 0x00;	 //选中第一位数码管1111 1110
	WE = 0;  //	  锁存位选数据

 	DU = 1;
	P0 = 0x79;	//数码管显示字母E
	DU = 0;
//	beep = 0;   //报警提示
}

void shumaguanShowStraight()
{
	WE = 1;//打开位选
	P0 = 0x00;//左边第一位数码管显示
	WE = 0;	//关闭位选	

	DU = 1;	//打开段选
	P0 = 0x40; //显示-
	DU = 0;	//关闭段选
}
void main()
{
	InitShumaguan();//第一位数码管选定
	while(1)
	{
		while(sumDegree <= maxSum && sumDegree >= 0 )  //如果步数和大于0,小于  最大步数,可以继续后退
	     {
		 	 if(block == 0)		   //光电开关被遮挡,反转1步
			 {	
				shumaguanShow1();  //数码管显示1
				invert_motor_degree(1);//   反转1步
				sumDegree--; 	//总步数减1
			 }
  		   	 if(block == 1)			//光电开关无遮挡
			{     		   
				shumaguanShow0();  //数码管显示0		  
				motor_degree(1);//	无遮挡,正转1步
				sumDegree++;    //总步数加1
			}
		 }                                     //如果步数和等于0,说明在最前方,任何情况都不前进,有遮挡后退
	while(sumDegree < 0)	//如果步数和小于0,则不能后退了,有遮挡不动,无遮挡前进。
		{
			if(block == 0)	   //光电开关被遮挡,电机不动
			{
			 	shumaguanShowError();  //报警提示
			}
			if(block == 1)	   //光电开关无遮挡,电机正转
			{
				shumaguanShow0();
				motor_degree(1);	//正转1步
				sumDegree++;	//总步数加1
			}
		}
	while(sumDegree > maxSum)	 //如果步数和大于50,则不能前进了,无遮挡不动,有遮挡反转。
		{
	 		if(block == 0) 	//光电开关有遮挡,电机反转
				{
				 	shumaguanShow1();
					invert_motor_degree(1);
					sumDegree--;
				}
			if(block == 1)	//光电管无遮挡,电机不动,显示机械臂伸直状态----
				{
				 	shumaguanShowStraight();
				}
		}
	}		
}	















			

想让步进电机限制在0-90度之间旋转,这里有两个状态,状态1:步进电机处于零度角,状态2:步进电机处于90度角。

这里我用了查询方式,设置一个计步器,正转步数加1,反转步数减1,步数加到最大步数,步进电机就不能正转了,光电管检测不到障碍物,就进入一个空函数中不断循环,这就解决了不超过90度的问题。步数减到0,步进电机就不能反转了,光电管检测到障碍物,就进入到另一个空函数不断循环,这就解决了不小于0度的问题。

注意,每次检测完障碍物,执行相应的函数后,一定要再返回来判断角度是不是在0-90以内。这就从根本上杜绝了电机瞎转。

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值