步进电机控制器的设计
下面是我写的一个简单的程序,但是我不知道该怎么修改才能满足题目的要求以及转速和角位移的显示程序,麻烦各位帮我看看,说说你们的想法,现在这谢了啊
#include <reg51.h> //51芯片管脚定义头文件
#include <intrins.h> //内部包含延时函数 _nop_();
#define uchar unsigned char
#define uint unsigned int
uchar i,j,k;
uchar code zhengcode[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09}; //四相八拍正转编码
uchar code fancode[8]={0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01}; ////四相八拍反转编码
sbit K1 = P3^2; //正转
sbit K2 = P3^3; //反转
sbit K3 = P3^4; //停止
void main()
{ TMOD=0X01;
TH0=0xff;
TL0=0xf6; //定时0.01ms
EA=1;
ET0=1;
TR0=1;
i=0;
j=0;
k=100;
if(K1==0)
{ while(1)
{ P1=zhengcode[i];
if(K3==0)
{break;}
}
}
else if(K2==0)
{ while(1)
{ P1=fancode[j];
if(K3==0)
{break;}
}
}
else P1=0xf0;
}
void intt0() interrupt 1
{ k--;
TH0=0xff;
TL1=0xf6;
if(k==0)
{ k=100;
i++;
j++;}
if(i==7)
{i=0;}
if(j==7)
{j=0;}
}
你现在能控制电机正反转动了吗?我也没有做过,一步一步的做吧,先让电机转起来,再来调速, 精度之类的功能
不知道你显示部分电路有了没有,是用液晶显示,还是用LED,请先说明一下,对应的外部电路有,才好对应进行编程...
你的程序还有很多没有完成。
单片机控制步进马达的方向,速度,位移的程序很简单。调速我还没有搞过。
用一个步进马达控制器就可以了。
用单片机设计一个步进电机控制器。要求能对步进电机实现正、反转及速度控制,同时能对步进电机进行位置控制,这个很简单。
这个问题是要能够设定步进电机的转速啊,通过键盘设定。你会编写这个程序吗?
下面是我的完整程序,就是我调节的转速好没有与实际的转速一一对应。你能帮我改写吗?
#include <reg51.h>
#include <intrins.h>
void delayNOP()
{_nop_();_nop_();_nop_();_nop_();}
#define uchar unsigned char
#define uint unsigned int
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
uchar keycode,scan1,scan2;
uchar chuzhi;
uchar shedingzhuansu[4]={0x00,0x01,0x00,0x00}; //存储转速
uchar shedingjiaodu[4]={0x03,0x00,0x00,0x00}; //存储角度
uint zhuanguojiaodu=0,number;//计算转过的角度和脉冲计数
uchar code FFW[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9}; //反转码
uchar code REV[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1}; //正传码
uchar m,v=0,q=0;
uint zhuansu,jiaodu; //设置的转速和角度
bit zhengrunflag=0,fanrunflag=0,stopflag=0,zhuansushezhiflag=1,jiaodushezhiflag=0,shuzi; //区分控制键和数字键标志
bit on_off=0; //运行与停止标志
bit direction; //正反标志
uint data_temp,data_temP1,data_temp2,data_temp3,data_temp4;
void delay(uint t) //延时函数
{
uchar k;
while(t--)
{
for(k=0; k<125; k++)
{ }
}
}
bit lcd_busy() // 检查LCD忙不忙
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
void lcd_wcmd(uchar cmd) // LCD写指令
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
void lcd_wdat(uchar dat) //LCD写数据
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
void lcd_clr() // LCD清屏
{ lcd_wcmd(0x01);
delay(5);
}
void lcd_init() // LCD初始化
{
delay(30);
lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x0c); //显示开,关光标
delay(5);
lcd_wcmd(0x06); //移动光标
delay(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delay(5);
}
uchar keyscan()//矩阵键盘线反转法扫描程序
{
uchar i=0;
P3=0xf0;
scan1=P3;
if(scan1!=0xf0)
{ delay(8);
if(scan1!=0xf0)
{ P3=0x0f;
scan2=P3;
keycode=(scan1|scan2);
switch(keycode)
{ case 0xee: zhengrunflag=1;shuzi=0;break;
case 0xde: fanrunflag=1;shuzi=0;break;
case 0xbe: stopflag=1;shuzi=0;break;
case 0xed: zhuansushezhiflag=1;shuzi=0;break;
case 0xdd: jiaodushezhiflag=1;shuzi=0;break;
case 0xbd: chuzhi=0;shuzi=1;break;
case 0x7d: chuzhi=1;shuzi=1;break;
case 0xeb: chuzhi=2; shuzi=1;break;
case 0xdb: chuzhi=3;shuzi=1;break;
case 0xbb: chuzhi=4;shuzi=1;break;
case 0x7b: chuzhi=5;shuzi=1;break;
case 0xe7: chuzhi=6;shuzi=1;break;
case 0xd7: chuzhi=7;shuzi=1;break;
case 0xb7: chuzhi=8;shuzi=1;break;
case 0x77: chuzhi=9;shuzi=1;break;
}
}
else shuzi=0;
}
else shuzi=0;
return shuzi;
}
void zhuansutiaojie() // 转速调节程序
{ uint i, j=0;
for(i=0;i<4;i++)
{ while(!keyscan())
{;}
shedingzhuansu[j]=chuzhi;
lcd_wcmd(j|0x80);
lcd_wdat(shedingzhuansu[j]+0x30);
j++;
delay(500);
}
zhuansushezhiflag=0;
zhuansu=shedingzhuansu[0]*1000;
zhuansu=zhuansu+shedingzhuansu[1]*100;
zhuansu=zhuansu+shedingzhuansu[2]*10;
zhuansu=zhuansu+shedingzhuansu[3];//设定的转速
}
void jiaodutiaojie() // 角度调节
{ uint i,j=0;
for(i=0;i<4;i++)
{
while(! keyscan());
{;}
shedingjiaodu[j]=chuzhi;
lcd_wcmd((0x40+j)|0x80);
lcd_wdat(shedingjiaodu[j]+0x30);
j++;
delay(500);
}
jiaodushezhiflag=0;
jiaodu=shedingjiaodu[0]*1000;
jiaodu=jiaodu+shedingjiaodu[1]*100;
jiaodu=jiaodu+shedingjiaodu[2]*10;
jiaodu=jiaodu+shedingjiaodu[3]; //设置的角度
}
void data_conv() // 数据转化函数
{
data_temP1=data_temp/1000;
data_temP1=data_temP1+0x30;
data_temp2=data_temp%1000/100;
data_temp2=data_temp2+0x30;
data_temp3=data_temp%1000%100/10;
data_temp3=data_temp3+0x30;
data_temp4=data_temp%10;
data_temp4=data_temp4+0x30;
}
void data_dis() //步进电机显示函数
{ data_temp = zhuanguojiaodu; //显示转过角度
data_conv();
lcd_wcmd(0x48|0x80);
lcd_wdat(data_temP1);
lcd_wcmd(0x49|0x80);
lcd_wdat(data_temp2);
lcd_wcmd(0x4a|0x80);
lcd_wdat(data_temp3);
lcd_wcmd(0x4b|0x80);
lcd_wdat(data_temp4);
}
void motor_DR()
{
if(direction==1)
{lcd_wcmd(0x47|0x80);
lcd_wdat(0x2b);
}
else
{ lcd_wcmd(0x47|0x80);
lcd_wdat(0x2d);
}
}
void motor_RUN() // 步进电机运转子程序
{
if(on_off==1)
{ TR0=1;
motor_DR();
}
else
{ TR0=0; P1 =0x0f; }
}
void main() //主程序
{
delay(10);
lcd_init();
lcd_clr();
lcd_wcmd(0x00|0x80);
lcd_wdat(shedingzhuansu[0]+0x30);
lcd_wdat(shedingzhuansu[1]+0x30);
lcd_wdat(shedingzhuansu[2]+0x30);
lcd_wdat(shedingzhuansu[3]+0x30);
lcd_wcmd(0x40|0x80);
lcd_wdat(shedingjiaodu[0]+0x30);
lcd_wdat(shedingjiaodu[1]+0x30);
lcd_wdat(shedingjiaodu[2]+0x30);
lcd_wdat(shedingjiaodu[3]+0x30);
TMOD = 0x01; //T0定时方式1
TL0 = 0x9c; //定时时间为0.1ms
TH0 = 0xff;
EA = 1;
ET0 = 1;
P1 = 0x0f;
while(1)
{ keyscan();
if(zhuansushezhiflag==1) // 开始调节速度
{ zhuansutiaojie();}
if(jiaodushezhiflag==1) //开始调节角度
{
jiaodutiaojie();}
if(zhengrunflag==1) //正转键
{ zhuanguojiaodu=0;
number=0;
on_off=1;
direction=1;
motor_RUN();
zhengrunflag=0;
}
if(fanrunflag==1) // 反转键
{ zhuanguojiaodu=0;
number=0;
on_off=1;
direction=0;
motor_RUN();
fanrunflag=0;
}
if(stopflag==1) // 停止键
{
on_off=0;
motor_RUN();
stopflag=0;
}
if(zhuanguojiaodu==jiaodu) //判断是否达到了设置角度
{ zhuanguojiaodu=0;
P1=0x0f;
on_off=0;
motor_RUN();
}
data_dis(); //显示函数
}
}
void motor_onoff() interrupt 1 //定时器0中断服务程序
{
TL0 = 0x9c;
TH0 = 0xff;
q++;
if(q <zhuansu)
{ return; }
else
{ q=0;
number++; //脉冲计数
zhuanguojiaodu=number*2; //转过角度
if(direction==1) //方向标志
{ if(v<8)
{P1 = FFW[v];v++;
} //取数据,正转
if(v==8)
{ v=0; }
}
else
{ if(v<8)
{P1 = REV[v];v++;
} //取数据,反转
if(v==8)
{ v=0; }
}
//电机转动角度
}
}
这是我的这个设计的电路原理图

这么好的东西
