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 版权协议,转载请附上原文出处链接和本声明。