51单片机矩阵键盘细分器控制步进电机

51单片机细分器控制步进电机

**步进电机具有快速启动、精确定位和直接将数字量转化为角度量的优点,是工业传动和工业定
位系统主要元件之一,当然肯定是还有比步进电机更好的电机,不过因为步进电机价格的原因会有很多手工达人会选择步进电机。步进电机的控制器有很多种,当然我最喜欢的肯定是用细分器来控制,还有很多人会用uln2003模块来控制步进电机
**
在这里插入图片描述

直接上代码

main.c

#include "main.h"
#include "bujdj.h"

/*137个脉冲每毫米*/
/*步进电机驱动方法只需要给步进脉冲就行了  一般根据多少细分还有电流大小来决定每毫米多少脉冲*/
/*使用前先接好限位开关防止步进电机撞上卡死后烧坏*/
/*经贸旅游学校  勾云鹏     步进电机驱动程序*/


void zldjinit(void);  //直流电机控制函数
void Delay1000ms();
void keyscan();  //矩阵键盘
void bjdjinit();  //步进电机初始化
void bjdjkz(bit fx,uchar d);  //步进电机控制函数

void main()
{
	mbbs=1000;	   //移动步数
	bjdjinit();  //步进电机回原点
	zldjinit();   //直流电机初始化
	while(1)
	{
		keyscan();
		if(keyfhz==1)
		{
		bjdjkz(0,1);
		}
		if(keyfhz==2)
		{
		bjdjkz(1,1);
		}
		if(keyfhz==3)
		{
		bjdjkz(0,3);
		}
	}

}


void bjdjinit()
{
	uint i;
			dir=0;	//步进电机方向设置
			while(RL!=0){clkout;} //判断步进电机是否到限位,是就换方向,否则继续移动
			 if(RL==0){dir=1;dqbs=reum;}
			for(i=0;i<dqbs;i++)
			 {
			 clkout;  
			 }
}

void bjdjkz(bit fx,uchar d)  //fx 步进电机移动的方向,d 步进电机移动多少cm;
{
		uint i,var; //计数
		var=d*490; //这个根据设置细分根据实际情况来改
		if(fx)
		{dir=1;}else{dir=0;}
	  for(i=0;i<var;i++)
			 {
			 clkout;//步进电机移动宏
			 }
}

void zldjinit(void)     //直流电机控制函数
{

	yz=1;
	zz=0;
	delay(55000);
	delay(55000);
	Delay1000ms();
	Delay1000ms();
	yz=0;
	zz=1;
	delay(55000);
	delay(55000);
	Delay1000ms();
	Delay1000ms();
	zz=1;
	yz=1;
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;
	_nop_();
	_nop_();
	i = 43;
	j = 6;
	k = 203;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void keyscan()
    {
     uchar num=255;	
	   EA = 0;
     wor1=wor2=wor3=wor4=lor1=lor2=lor3=lor4=1;
		 wor1=0;
		 if(lor1==0)num=1;
		 else if(lor2==0)num=2;
		 else if(lor3==0)num=3;
		 else if(lor4==0)num=4;
     wor1=1;
		 wor2=0;
		 if(lor1==0)num=5;
		 else if(lor2==0)num=6;
		 else if(lor3==0)num=7;
		 else if(lor4==0)num=8;  
		 wor2=1;
		 wor3=0;
		 if(lor1==0)num=9;
		 else if(lor2==0)num=10;
		 else if(lor3==0)num=11;
		 else if(lor4==0)num=12;
		 wor3=1;
		 wor4=0;
		 if(lor1==0)num=13;
		 else if(lor2==0)num=14;
		 else if(lor3==0)num=15;
		 else if(lor4==0)num=16;
		 EA=1;
		 delay(7000);
		 keyfhz = num;	//直接给值
		 
    }

当然我这里是没有使用中断函数来实现步进电机控制的,我这种方法是不能用在主程序多的情况下的否则程序就会出现问题,步进电机的速度也会慢,使用中断的话可以很好的控制步进电机的速度,也不容易受干扰。

#include "main.h"


//void t1init(void)
//{
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x0A;		//设置定时初值
	TH1 = 0xF3;		//设置定时初值
	TF1 = 0;		//清除TF1标志
//	TMOD=0x01;
//	TR1 = 1;		//定时器1开始计时
//  EA=ET1=1;
//}


//void t1zd() interrupt 3
//{
//	uchar t;
	TL1 = 0x0A;		//设置定时初值
	TH1 = 0xF3;		//设置定时初值
//	TL1=(65536-speed)%256;
//	TH1=(65536-speed)/256;
//	switch(djzt){
//		case 0:			  //0~2为初始定位
//			dir=0;
//			djzt=1;			
//		case 1:			  //去参考点
//			if(RL==1){ clkout;break;}
//			else {dir=1;dqbs=reum;djzt=2;}			
//		case 2:			  //去0点
//			if(dqbs--){ clkout;break;}
//			else  {dqbs=0;djzt=3;}
//		case 3:			  //跟踪状态
//			if(dqbs<mbbs){
//				dir=1; clkout; dqbs++;		
//			}
//			else if(dqbs>mbbs){
//				dir=0; clkout; dqbs--;
//			}
//	}	 	

//}

这里是主函数的.h文件

#ifndef _MAIN_H_
#define	_MAIN_H_

#include <reg52.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

sbit dir = P3^4;	//步进电机方向控制  0右   1左
sbit clk = P3^5;	//步进电机进步脉冲
sbit RL = P3^3;		//右到位
//sbit LL = P3^5;     //左到位
sbit zz = P2^0;		//直流电机左控制
sbit yz = P2^1;		//直流电机右控制
sbit wor1 = P0^0;
sbit wor2 = P0^1;
sbit wor3 = P0^2;
sbit wor4 = P0^3;
sbit lor1 = P2^4;
sbit lor2 = P2^5;
sbit lor3 = P2^6;
sbit lor4 = P2^7;
sbit led = P1^0;

#define clkout{clk=0;delay(2);clk=1;delay(80);}  //进步宏

#define mover 0 //左
#define movel 1 //右
#define reum  3850 //归0步数

uint dqbs,mbbs;
uchar keyfhz=255,smgz1;
uchar djzt=0;  //电机工作状态  1=回参考点   2=归0  3=跟踪

void delay(uint i){while(i--);}	   //延时程序   50000约等于0.5秒

#endif

版权声明:本文为weixin_43366287原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>