《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 解決方案 > ME300實(shí)例-1602LCD顯示步進(jìn)電機(jī)鍵控正反轉(zhuǎn)實(shí)驗(yàn)-C語言源代碼

ME300實(shí)例-1602LCD顯示步進(jìn)電機(jī)鍵控正反轉(zhuǎn)實(shí)驗(yàn)-C語言源代碼

2008-12-28
關(guān)鍵詞: 步進(jìn)電機(jī) LED


[演示程序(C51):]
 
/*****************************************************************/
/*                                                                *
/* ME300B單片機(jī)開發(fā)系統(tǒng)演示程序-1602LCD顯示步進(jìn)電機(jī)鍵控正反轉(zhuǎn)實(shí)驗(yàn) *
#include <reg51.h>       //51芯片管腳定義頭文件
#include <intrins.h>  //內(nèi)部包含延時(shí)函數(shù) _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   = P1^4;       //運(yùn)行與停止
sbit  K2   = P1^5;       //設(shè)定圈數(shù)
sbit  K3   = P1^6;       //方向轉(zhuǎn)換
sbit  K4   = P1^7;       //速率調(diào)整
sbit  BEEP = P3^7;       //蜂鳴器

sbit  LCD_RS = P2^0;             
sbit  LCD_RW = P2^1;
sbit  LCD_EN = P2^2;

bit  on_off=0;            //運(yùn)行與停止標(biāo)志
bit  direction=1;         //方向標(biāo)志
bit  rate_dr=1;           //速率標(biāo)志
bit  snum_dr=1;           //圈數(shù)標(biāo)志

uchar code  cdis1[ ] = {" STEPPING MOTOR "};
uchar code  cdis2[ ] = {"CONTROL  PROCESS"};
uchar code  cdis3[ ] = {"    STOP        "};
uchar code  cdis4[ ] = {"NUM:    RATE:   "};
uchar code  cdis5[ ] = {"  RUNNING       "};

uchar   m,v=0,q=0;

uchar   number=0,number1=0; 
uchar   snum=5,snum1=5;       //預(yù)設(shè)定圈數(shù)
uchar   rate=8;               //預(yù)設(shè)定速率
uchar   data_temp,data_temp1,data_temp2;   

/********************************************************/
/*                                                  
/* 延時(shí)t毫秒 
/* 11.0592MHz時(shí)鐘,延時(shí)約1ms                                     
/*                                                      
/********************************************************/
void delay(uint t)
{                           
   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++)
     { }
   }
 }

/********************************************************/
void beep()
 {
   uchar j;
   for (j=0;j<100;j++)
    { 
     delayB(4);
     BEEP=!BEEP;                 //BEEP取反
    } 
     BEEP=1;                    //關(guān)閉蜂鳴器
  delay(170);
 }

/********************************************************/
/*                                                                
/*檢查L(zhǎng)CD忙狀態(tài)                                                   
/*lcd_busy為1時(shí),忙,等待。為0時(shí),閑,可寫指令與數(shù)據(jù)。     
/*                                                               
/********************************************************/ 

bit lcd_busy()
 {                          
    bit result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;
    delayNOP();
    result = (bit)(P0&0x80);
    LCD_EN = 0;
    return(result); 
 }

/********************************************************/
/*                                                                 
/*寫指令數(shù)據(jù)到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;  
}

/********************************************************/
/*                                                                
/*寫顯示數(shù)據(jù)到LCD                                                  
/*RS=H,RW=L,E=高脈沖,D0-D7=數(shù)據(jù)。                              
/*                                                               
/********************************************************/

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初始化設(shè)定                                                
/*                                                                
/********************************************************/

void lcd_init()

    delay(30);                   
    lcd_wcmd(0x38);      //16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)
    delay(5);
    lcd_wcmd(0x38);         
    delay(5);
    lcd_wcmd(0x38);         
    delay(5);

    lcd_wcmd(0x0c);      //顯示開,關(guān)光標(biāo)
    delay(5);
    lcd_wcmd(0x06);      //移動(dòng)光標(biāo)
    delay(5);
    lcd_wcmd(0x01);      //清除LCD的顯示內(nèi)容
    delay(5);
}

/********************************************************/
/*                                                                 
/*  設(shè)定顯示位置                                                  
/*                                                                
/********************************************************/

void lcd_pos(uchar pos)
{                          
  lcd_wcmd(pos | 0x80);  //數(shù)據(jù)指針=80+地址變量
}

/********************************************************/
/*                                                       
/* LCD1602初始顯示子程序                                             
/*                                                      
/********************************************************/
void  LCD_init_DIS()
{            
     delay(10);                 //延時(shí)
     lcd_init();                //初始化LCD             
        
     lcd_pos(0);                //設(shè)置顯示位置為第一行的第1個(gè)字符
     m = 0;
     while(cdis1[m] != '\0')
      {                         //顯示字符
        lcd_wdat(cdis1[m]);
        m++;
      }

     lcd_pos(0x40);             //設(shè)置顯示位置為第二行第1個(gè)字符
     m = 0;
     while(cdis2[m] != '\0')
      {
        lcd_wdat(cdis2[m]);      //顯示字符
        m++;
      }

      delay(3000);               //延時(shí)        
        
      lcd_pos(0);                //設(shè)置顯示位置為第一行的第1個(gè)字符
      m = 0;
      while(cdis3[m] != '\0')
        {                        //顯示字符
          lcd_wdat(cdis3[m]);
          m++;
        }

      lcd_pos(0x40);             //設(shè)置顯示位置為第二行第1個(gè)字符
      m = 0;
     while(cdis4[m] != '\0')
        {
          lcd_wdat(cdis4[m]);    //顯示字符
          m++;
        }      

        for(m=0;m<2;m++)
          { 
       lcd_pos(0x0c+m);    //顯示方向符號(hào)
             lcd_wdat(0x3e);
    }

}
/********************************************************/
/*
/*數(shù)據(jù)轉(zhuǎn)換子程序
/*
/********************************************************/
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;
 }

/********************************************************/
/*
/*數(shù)據(jù)顯示子程序
/*
/********************************************************/
void  data_dis()
{
    data_temp = snum;        //顯示圈數(shù)
    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);
}
/********************************************************
/*
/* 顯示運(yùn)行方向符號(hào)
/*
/********************************************************/
void  motor_DR()
  {
       if(direction==1)           //正轉(zhuǎn)方向標(biāo)志
        { for(m=0;m<2;m++)
          { 
      lcd_pos(0x0c+m);      //顯示方向符號(hào)
            lcd_wdat(0x3e);
     }
   }
        else
         { for(m=0;m<2;m++)       //反轉(zhuǎn)方向標(biāo)志
           { 
          lcd_pos(0x0c+m);     //顯示方向符號(hào) 
             lcd_wdat(0x3c);
     }
   }
  }

/********************************************************
/*
/* 顯示運(yùn)行狀態(tài)
/*
/********************************************************/
void  motor_RUN()
 {
      if(on_off==1)
    { TR0=1; 
      lcd_pos(0);     //設(shè)置顯示位置為第一行的第1個(gè)字符
         m = 0;
         while(cdis5[m] != '\0')
          { lcd_wdat(cdis5[m]);      //RUNNING
            m++;   }
            motor_DR();              //
    }  
      else  
    { TR0=0; P1 =0xf0; 
   lcd_pos(0);     //設(shè)置顯示位置為第一行的第1個(gè)字符
         m = 0;
         while(cdis3[m] != '\0')
          { lcd_wdat(cdis3[m]);      //STOP
            m++;   }
            motor_DR();              //
   snum=snum1;             //
   number1=0;              //清圈數(shù)計(jì)數(shù)器
         }
  }

/********************************************************
*                                                       
*  主程序                                               
*                                                      
*********************************************************/

main()
 { 
         LCD_init_DIS();
  
   TMOD = 0x01;       //T0定時(shí)方式1
   TL0  = 0x33;
         TH0  = 0xf5;
   EA   = 1;
   ET0  = 1; 
   P1   = 0xf0; 
  
   while(1)
    {  
       if(K1==0)
    {
         beep();
      while(K1==0);       //等待鍵釋放
      on_off=~on_off;       
         motor_RUN();  
        }   //K1 end
/********************************************************/
      if(K2==0)    
       {
      beep();
   if(snum_dr==1)
    { snum++;
        snum1=snum;
      if(snum==0x14)
            { snum_dr=~snum_dr;}
    }
   else  
     {snum--;
   snum1=snum;
      if(snum==0x01)
   { snum_dr=~snum_dr; }
     }
   
    } //K2  end
/********************************************************/
        if(K3==0)    
      {
      beep();
   direction=~direction; 
         motor_DR();
      }//K3 end

/********************************************************/
        if(K4==0)    
       {
      beep();
   if(rate_dr==1)
    { rate++;
      if(rate==0x10)
            { rate_dr=~rate_dr;}
    }
    else  
     { 
      rate--;
      if(rate==0x01)
   { rate_dr=~rate_dr; }
     }
  } //K4 end
    
/********************************************************/
      if(number1==snum1)   //與設(shè)定圈數(shù)是否相等  
     { number1=0; 
         on_off=0;
         TR0=0;
        snum=snum1;
   P1 =0xf0;
    motor_RUN();
    }         
         data_dis();
 }  // while(1) end
 }  //main end

/********************************************************/
/*
/*  定時(shí)器 0 中斷 
/*
/********************************************************/

void  motor_onoff()  interrupt  1  
 {     
       TL0  = 0x33;
       TH0  = 0xf5; 
       q++;
    if(q < rate)
        { return; }
    else 
       {  q=0;    
       number++;                  //脈沖計(jì)數(shù)
        
      if(number==96)              //96個(gè)脈沖電機(jī)轉(zhuǎn)一圈
       { snum--;
      number=0;
            number1++; }          //電機(jī)轉(zhuǎn)動(dòng)圈數(shù)
    

         if(direction==1)            //方向標(biāo)志
       { if(v<8)  
         {P1 = FFW[v];v++;}       //取數(shù)據(jù),正轉(zhuǎn)
        if(v==8) 
        { v=0; } 
          }
   
      else
       { if(v<8)  
         {P1 = REV[v];v++;}       //取數(shù)據(jù),反轉(zhuǎn)
         if(v==8) 
         { v=0; } 
          }
    }
 } 

/********************************************************/

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問題,請(qǐng)及時(shí)通過電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。