51单片机控制步进电机运动,LCD上没数据显示,电机不转,
#include <reg51.h>
#include <intrins.h> //内部包含延时函数 _nop_();
#define uchar unsigned char
#define uint unsigned int
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
uchar code FFW[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9}; //正转相序编码
uchar code REV[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1};
sbit K1 = P3^0; //运行与停止
sbit K2 = P3^1; //设圈数
sbit K3 = P3^2; //方向转换
sbit K4 = P3^3; //转速加
sbit K5 = P3^4; //点动
sbit K6 = P3^5;
sbit K7 = P3^6;
sbit K8 = P3^7;
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
bit on_off=0,on_off1=0; //运行与停止标志
bit direction=1; //方向标志
bit rate_dr=1; //速率标志
bit snum_dr=1; //圈数标志
uchar code cdis1[ ] = {" STEPPING MOTOR "};
uchar code cdis2[ ] = {"CONTROL PROCESS"};
uchar code cdis3[ ] = {" STOP "};
uchar code cdis4[ ] = {"NUM: RATE: "};
uchar code cdis5[ ] = {" RUNNING "};
uchar code cdis6[ ] = {" DIAN DONG "};
uchar m,v=0,q=0,q1;
uint number=0,number1=0;
uchar snum=10,snum1=10,number2=0; //预设定圈数
uchar rate=2,rate_ctr; //预设定速率
uchar data_temp,data_temp1,data_temp2;
/********************************************************/
/*
/* 延时t毫秒
/* 11.0592MHz时钟,延时约1ms
/*
/********************************************************/
void delay(uint t) //tms
{
uchar k;
while(t--)
{
for(k=0; k<125; k++)
{ }
}
}
/********************************************************/
void delayB(uchar x) //x*0.14MS
{
uchar i;
while(x--)
{
for (i=0; i<13; i++)
{ }
}
}
/********************************************************/
/********************************************************/
/*
/*检查LCD忙状态
/*lcd_busy为1时,忙,等待。为0时,闲,可写指令与数据。
/*
/********************************************************/
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
/********************************************************/
/*
/*写指令数据到LCD
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。
/*
/********************************************************/
void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/********************************************************/
/*
/*写显示数据到LCD
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。
/*
/********************************************************/
void lcd_wdat(uchar dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/********************************************************/
/*
/* LCD初始化设定
/*
/********************************************************/
void lcd_init()
{
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);
}
/********************************************************/
/*
/* 设定显示位置
/*
/********************************************************/
void lcd_pos(uchar pos)
{
lcd_wcmd(pos | 0x80); //数据指针=80+地址变量
}
/********************************************************/
/*
/* LCD1602初始显示子程序
/*
/********************************************************/
void LCD_init_DIS()
{
delay(10); //延时
lcd_init(); //初始化LCD
lcd_pos(0); //设置显示位置为第一行的第1个字符
m = 0;
while(cdis1[m] != '\0')
{ //显示字符
lcd_wdat(cdis1[m]);
m++;
}
lcd_pos(0x40); //设置显示位置为第二行第1个字符
m = 0;
while(cdis2[m] != '\0')
{
lcd_wdat(cdis2[m]); //显示字符
m++;
}
delay(3000); //延时
lcd_pos(0); //设置显示位置为第一行的第1个字符
m = 0;
while(cdis3[m] != '\0')
{ //显示字符
lcd_wdat(cdis3[m]);
m++;
}
lcd_pos(0x40); //设置显示位置为第二行第1个字符
m = 0;
while(cdis4[m] != '\0')
{
lcd_wdat(cdis4[m]); //显示字符
m++;
}
for(m=0;m<2;m++)
{
lcd_pos(0x0c+m); //显示方向符号
lcd_wdat(0x3e);
}
}
/********************************************************/
/*
/*数据转换子程序
/*
/********************************************************/
void data_conv()
{
data_temp1=data_temp/10; //高位
if(data_temp1==0)
{data_temp1=0x20;} //高位为0不显示
else
{data_temp1=data_temp1+0x30;}
data_temp2=data_temp%10; //低位
data_temp2=data_temp2+0x30;
}
/********************************************************/
/*
/*数据显示子程序
/*
/********************************************************/
void data_dis()
{
data_temp = snum; //显示圈数
data_conv();
lcd_pos(0x44);
lcd_wdat(data_temp1);
lcd_pos(0x45);
lcd_wdat(data_temp2);
data_temp = rate; //显示速率
data_conv();
lcd_pos(0x4d);
lcd_wdat(data_temp1);
lcd_pos(0x4e);
lcd_wdat(data_temp2);
}
/********************************************************
/*
/* 显示运行方向符号
/*
/********************************************************/
void motor_DR()
{
if(direction==1) //正转方向标志
{ for(m=0;m<2;m++)
{
lcd_pos(0x0c+m); //显示方向符号
lcd_wdat(0x3e);
}
}
else
{ for(m=0;m<2;m++) //反转方向标志
{
lcd_pos(0x0c+m); //显示方向符号
lcd_wdat(0x3c);
}
}
}
/********************************************************
/*
/* 显示运行状态
/*
/********************************************************/
void motor_RUN()
{
if(on_off==1)
{ TR0=1;
lcd_pos(0); //设置显示位置为第一行的第1个字符
m = 0;
while(cdis5[m] != '\0')
{ lcd_wdat(cdis5[m]); //RUNNING
m++; }
motor_DR(); //
}
else
{ TR0=0; P1 =0x0f;
lcd_pos(0); //设置显示位置为第一行的第1个字符
m = 0;
while(cdis3[m] != '\0')
{ lcd_wdat(cdis3[m]); //STOP
m++; }
motor_DR(); //
snum=snum1; //
number1=0; //清圈数计数器
}
}
/********************************************************
*
* 主程序
*
*********************************************************/
main()
{
LCD_init_DIS();
TMOD = 0x11; //T0定时方式1
TL0 = 0xff;
TH0 = 0xf5;
TL1 = 0xff;
TH1 = 0xf5;
EA = 1;
ET0 = 1;
ET1=1;
P1 = 0x0f;
while(1)
{
if(K1==0)
{
delay(20);
if(K1==0)
{
while(K1==0); //等待键释放
on_off=~on_off;
motor_RUN();
}
} //K1 end
/********************************************************/
if(K2==0)
{
delay(20);
if(K2==0)
{
if(snum_dr==1)
{ snum++;
snum1=snum;
if(snum==0x14) //14H=20
{ snum_dr=~snum_dr;}
}
else
{snum--;
snum1=snum;
if(snum==0x01)
{ snum_dr=~snum_dr; }
}
}
delay(100);
} //K2 end
/********************************************************/
if(K3==0)
{
delay(20);
if(K3==0)
{
direction=~direction;
motor_DR();
}
delay(100);
}//K3 end
/********************************************************/
if(K4==0)
{
delay(20);
if(K4==0)
{
if(rate_dr==1)
{ rate++;
if(rate==0x10)
{ rate_dr=~rate_dr;}
}
else
{
rate--;
if(rate==0x01)
{ rate_dr=~rate_dr; }
}
}
delay(100);
} //K4 end
/********************************************************/
if(number1==snum1) //与设定圈数是否相等
{ number1=0;
on_off=0;
TR0=0;
snum=snum1;
P1=0x0f;
motor_RUN();
}
data_dis();
/********************************************************/
if(K5==0) //点动
{
on_off1=1;
motor_RUN1();
while(K5==0) {
;
}
on_off1=0;
motor_RUN1();
}
} // while(1) end
} //main end
/********************************************************/
/*
/* 定时器 0 中断
/*
/********************************************************/
void motor_onoff() interrupt 1
{
TL0 = 0xff;
TH0 = 0xf5;
q++;
if(q < rate)
{ return; }
else
{ q=0;
number++; //脉冲计数加一
if(number==4096) //8*8个脉冲电机转一圈,又减速比为1/64,故电机外轴转一圈为64*64个脉冲
{ snum--;
number=0;
number1++; } //电机已转动圈数加一
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; }
}
}
}
/********************************************************/
/*
/* 定时器 1 中断
/*
/********************************************************/
void motor_onoff1() interrupt 3
{
TL1 = 0xff;
TH1 = 0xf5;
q1++;
if(q1 < rate)
{ return; }
else
{ q1=0;
number2++; //脉冲计数
if(number2==4096) //64个脉冲电机转一圈
{
number2=0;
} //电机转动圈数
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; }
}
}
}
求帮忙啊!大神在哪里呢?
学学学习学习啊
来人啊,帮忙啊!好着急
小编,我不会,问别人吧。
期待有解决的我也借鉴一下
我这是怎么了?
#include<reg51.h>
#define uchar unsigned char
#definr uint unsigned int
sbit k1=P3^4; //启动、停止按键
sbit k2=P3^5; //减速
sbit k3=P3^6; //加速
sbit k4=P3^7; //正反转
sbit k5=P3^2; //模式控制
sbit RS=P0^5;
sbit RW=P0^6;
sbit E=P0^7;
sbit ENA=P1^2; //使能信号
sbit IN1=P1^0; //电机输入线
sbit IN2=P1^1;
bit model=1; //手动、自动 默认手动
bit direc=1; //转向标志 默认正转
int rate=1; //高电平时间常数
int num=0; //中断记录
int count=0; //1ms中断记录
uchar code tab1[]=" welcome";
uchar code tab2[]=" 2015/8/12";
uchar code tab3[]=" motor control";
uchar code tab4[]=" team:DXS DS GF";
uchar code tab5[]="Dire: Model:";
uchar code tab6[]="Rate: T:30";
void delay_xus(uint x)
{
while(x--);
}
void delay(uint x)
{
uint y;
for(;x>0;x--)
for(y=110;y>0;y--);
}
void w_com(uint com) //写命令
{
RS=RW=E=0;
P2=com;
E=1;
delay_xus(1);
E=0;
}
void w_data(uint dat) //写数据
{
RS=1;
RW=E=0;
P2=dat;
E=1;
delay_xus(1);
E=0;
}
void w_shuzu(int addr,uchar code *p) //显示字符串
{
int i;
w_com(0x80+addr);
delay_xus(1);
for(i=0;p[i]!='\0';i++)
{
w_data(p[i]);
delay_xus(1);
}
}
void disp() //显示速度、转向、模式
{
if(rate<10)
{
w_com(0x80+0x45);
delay_xus(1);
w_data('');
delay_xus(1);
w_com(0x80+0x46);
delay_xus(1);
w_data(rate%10+0x30);
delay_xus(1);
}
else
{
w_com(0x80+0x45);
delay_xus(1);
w_data(rate/10+0x30);
delay_xus(1);
w_com(0x80+0x46);
delay_xus(1);
w_data(rate%10+0x30);
delay_xus(1);
}
if(direc==1)
{
w_shuzu(0x06,"F");
}
else
{
w_shuzu(0x06,"R");
}
if(model==0) w_shuzu(0x0f,"H");
else w_shuzu(0x0f,"A");
}
void int() //主程序初始化
{
w_com(0x38);
delay_xus(1);
w_com(0x0c); //开显示
delay_xus(1);
w_shuzu(0x00,tab1); //显示字符串
w_shuzu(0x04,tab2);
delay(500);
w_com(0x01); //清屏
delay_xus(1);
delay(2); //忙碌
w_shuzu(0x00,tab3);
w_shuzu(0x40,tab4);
delay(1000);
w_com(0x01); //清屏
delay_xus(1);
delay(2); //忙碌
w_shuzu(0x00,tab5);
w_shuzu(0x40,tab6);
disp();
ENA=0;
TMOD=0X01;
TH0=0XFC;
TL0=0X18;
ET0=1;
TR0=0;
EX1=1;
IP=0X02;
EA=1;
}
void keyscan() //按键处理程序
{
if(k1==0)
{
delay(120);
if(k1==0)
{
TR0=~TR0;
ENA=~ENA;
rate=1;
}
if(k2==0&&model==0) //减速
{
delay(120);
if(k2==0&&model==0)
{
rate-=2;
if(rate<=1) rate=1;
}
}
if(k3==0&&model==0) //加速
{
delay(120);
if(k3==0&&model==0)
{
rate+=2;
if(rate>=29) rate=29;
}
}
if(k4==0&&model==0) //转向
{
delay(120);
if(k4==0&&model==0)
{
direc=~direc;
}
}
if(k5==0&&model==0) //模式选择
{
model=~model;
}
}
disp(); //状态改变 及时更新数据
}
void main() //主程序
{
init();
while(1);
}
void extern1() interrupt 2
{
keyscan();
}
void timer0() interrupt 1
{
num++;
if(num>=31) num=0;
if(direc==1)
{
if(num<=rate)
{
IN1=1;
IN2=0;
}
else
IN1=IN2=0;
}
else
{
if(num<=rate)
{
IN1=0;
IN2=1;
}
else
IN1=IN2=0;
}
if(model==1)
{
count++;
if(count==1500)
{
rate+=2;
if(rate>=29) rate=29;
count=0;
disp();
}
}
TH0=0XFC;
TL0=0X18;
}
帮忙看看啊!
解决了没啊?
小编
解决了没啊?