微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 51单片机控制步进电机运动,LCD上没数据显示,电机不转,

51单片机控制步进电机运动,LCD上没数据显示,电机不转,

时间:10-02 整理:3721RD 点击:
我做的是基于stc51单片机通过按键控制28byj48步进电机运动,在LCD1602上显示。结果电机不转,有震动,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;
}

帮忙看看啊!

解决了没啊?

小编
解决了没啊?

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top