51单片机之lcd1602步进电机控制

发布者:sumig最新更新时间:2015-08-26 来源: eefocus关键字:51单片机  lcd1602  步进电机控制 手机看文章 扫描二维码
随时随地手机看文章
#include       //51芯片管脚定义头文件
#include //内部包含延时函数 _nop_();
 
#define uchar unsigned char
#define uint  unsigned int
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
char code SST516[3] _at_ 0x003b;
 
 
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;       //运行与停止
sbit  K2   = P1^5;       //设定圈数
sbit  K3   = P1^6;       //方向转换
sbit  K4   = P1^7;       //速率调整
sbit  BEEP = P3^7;       //蜂鸣器
 
sbit  LCD_RS = P2^0;             
sbit  LCD_RW = P2^1;
sbit  LCD_EN = P2^2;
 
bit  on_off=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   m,v=0,q=0;
 
uchar   number=0,number1=0; 
uchar   snum=5,snum1=5;       //预设定圈数
uchar   rate=8;               //预设定速率
uchar   data_temp,data_temp1,data_temp2;   
 
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;                    //关闭蜂鸣器
delay(170);
 }
 
 
 
bit lcd_busy()
 {                          
    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)
 
{                          
   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)
{                          
   while(lcd_busy());
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    P0 = dat;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0; 
}
 
 
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+地址变量
}
 
void  LCD_init_DIS()
{            
     delay(10);                 //延时
     lcd_init();                //初始化LCD             
        
     lcd_pos(0);                //设置显示位置为第一行的第1个字符
     m = 0;
     while(cdis1[m] != '')
      {                         //显示字符
        lcd_wdat(cdis1[m]);
        m++;
      }
 
     lcd_pos(0x40);             //设置显示位置为第二行第1个字符
     m = 0;
     while(cdis2[m] != '')
      {
        lcd_wdat(cdis2[m]);      //显示字符
        m++;
      }
 
      delay(3000);               //延时        
        
      lcd_pos(0);                //设置显示位置为第一行的第1个字符
      m = 0;
      while(cdis3[m] != '')
        {                        //显示字符
          lcd_wdat(cdis3[m]);
          m++;
        }
 
      lcd_pos(0x40);             //设置显示位置为第二行第1个字符
      m = 0;
     while(cdis4[m] != '')
        {
          lcd_wdat(cdis4[m]);    //显示字符
          m++;
        }      
 
        for(m=0;m<2;m++)
          { 
    lcd_pos(0x0c+m);    //显示方向符号
             lcd_wdat(0x3e);
 }
 
}[page]
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;       //低位
     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] != '')
          { lcd_wdat(cdis5[m]);      //RUNNING
            m++;   }
            motor_DR();              //
  }  
      else  
  { TR0=0; P1 =0xf0; 
lcd_pos(0);     //设置显示位置为第一行的第1个字符
         m = 0;
         while(cdis3[m] != '')
          { lcd_wdat(cdis3[m]);      //STOP
            m++;   }
            motor_DR();              //
snum=snum1;             //
number1=0;              //清圈数计数器
         }
  }
 
 
main()
 
         LCD_init_DIS();
TMOD = 0x01;       //T0定时方式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)   //与设定圈数是否相等  
    { number1=0; 
         on_off=0;
         TR0=0;
      snum=snum1;
P1 =0xf0;
  motor_RUN();
  }         
         data_dis();
}  // while(1) end
 }  //main end
 
 
void  motor_onoff()  interrupt  1  
 {     
       TL0  = 0x33;
       TH0  = 0xf5; 
       q++;
  if(q < rate)
        { return; }
  else 
       {  q=0;    
     number++;                  //脉冲计数
        
    if(number==96)              //96个脉冲电机转一圈
     { 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; } 
          }
  }
 
关键字:51单片机  lcd1602  步进电机控制 引用地址:51单片机之lcd1602步进电机控制

上一篇:51单片机控制步进电机转动以及用lcd1602显示
下一篇:51单片机的花样彩灯

推荐阅读最新更新时间:2024-03-16 14:30

51单片机学习之陆 —— 1.4 数码管的显示
1 数码管的结构和原理      一般而言,数码管都有10个引脚。图上好像只有9个引脚,原因是第三引脚和第8引脚是连接在一起的,所以看上去只有9个。 根据他们的公共端又可分为共阴极和共阳极。 共阴极 和 共阳极   位选:控制那个数码管   段选:控制数码管显示东西(如1 2 3) 数码管静态显示:    stc89c52rc是共阴极的数码管 锁存器:    OE :输出允许端 (由于OE为高电平时输出为高阻态芯片不可控,所以设计电路是必须将OE接低电平。) LE : 锁存允许端 因此,我们将锁存器的LE端与单片机某一引脚相连,再将锁存器的数据输入端(D)与单片机某组I/O 口相
[单片机]
<font color='red'>51单片机</font>学习之陆 —— 1.4 数码管的显示
基于51单片机的ds18B20温度程序
在学习板上正常运行,目前只能简单的检测温度。 温度变化速度有点慢,需要再调试。数码管显示还有点鬼影,暂时没想出来怎么去消鬼影。 没有添加温度上下限报警程序,没有添加按键可调温度程序,暂时不能显示小数部分。 以后还得继续努力把功能添加进去。 测得室温为31度 #include reg51.h /************共阳LED段码表*****************/ unsigned char code tab ={0xc0,0xf9,0xa4, 0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6}; /************端口定义*************/ sbit
[单片机]
基于<font color='red'>51单片机</font>的ds18B20温度程序
基于51单片机+DAC0832的信号发生器
最近帮别人设计一个毕业设计,做一个多种信号发生器(四种波形:方波、三角波、锯齿波、梯形波),现在贴上来给大家参考,如果有错误的地方,望指出~ 下面先贴上仿真的电路图(仿真的软件是Protuse,上传一个大点的图,方便大家看的清楚点): 原件清单:STC89C52单片机X1、DAC0832转换器X1、12M晶振X1、电容22pfX2、10uf的电容X1、1nf陶瓷电容X1、独立按键X4、10千欧排阻X1、10KΩ电阻X5、LM358 单电源运放X1。仿真就需要这些原件,具体的硬件设计大家定好了在制作~ 下面上传一下C程序吧~(使用的IDE环境是Keil 4,语言是C语言) Source文件(.c文件): 1\ma
[单片机]
基于<font color='red'>51单片机</font>+DAC0832的信号发生器
51单片机实现红外编码检测
一直以来就像做个红外线检测,因为我是做空调扇的,我们组专门负责遥控器.前几天在百度文库找到一篇文章,之后就做了一个 #include reg52.h //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 #include lcd.h sbit IR=P3^2; //红外接口标志 /*------------------------------------------------ 全局变量声明 ------------------------------------------------*/ unsigned char irtime;//红外用全局变量 bit irpro
[单片机]
51单片机实验——跑马灯实验
1.题目要求: 编写跑马灯程序,用P0演示跑马灯的效果,效果自定。 2.KEIL代码 #include reg52.h #include intrins.h typedef unsigned int u16; //对数据类型进行声明定义 typedef unsigned char u8; void Delay100ms() //100ms { unsigned char i, j, k; _nop_();_nop_(); i = 5;j = 52;k = 195; do{do{while (--k);} while (--j);} while (--i); } void main(
[单片机]
<font color='red'>51单片机</font>实验——跑马灯实验
51单片机-代码参考
前面的篇章我们都是在普及知识,真正使用好定时器还是需要重新拟定新的书写方案的,我们参考了宋老师的书写方式,在他的代码基础上我们进行小修改成就实用的工程代码。 1.代码解析 void ConfigTimer0(unsigned int ms) { unsigned long tmp; //临时变量 tmp = 11059200 / 12; //定时器计数频率 tmp = (tmp * ms) / 1000; //计算所需的计数值 tmp = 65536 - tmp; //计算定时器重载值 tmp = tmp + 13; //补偿中断响应延时造
[单片机]
采用AT89C2051单片机实现数字电容表的设计
设计任务 设计并制作一个数字电容表,系统实现的功能及要求如下: (1)设计的电容表可测量容量小于2μF的电容。 (2)设计的电容表采用3位半数字显示,最大显示值为1 999。 (3)设计的电容表读数单位统一采用nF,量程分4档,实际电容值为读数乘以相应的倍率。 2 方案论证 2.1 电路方案 (1)方案一:基本电路搭建 用基本电路来实现数字显示的电容表,电路结构复杂,故障系数大,不易调试,误差也较大。 (2)方案二:单片机编程 用单片机设计电路,由于使用软硬件结合的方式,所以电路结构简单、调试也相对方便。与第一种方案比较优点是非常明显的。 2.2 显示方案 (1)方案一:静态显示 静态显示,显示驱动电路具有输出锁存功能,单
[单片机]
采用AT89C20<font color='red'>51单片机</font>实现数字电容表的设计
串口通信详解(51单片机
计算机串行通信基础 随着多微机系统的广泛应用和计算机网络技术的普及,计算机的通信功能愈来愈显得重要。计算机通信是指计算机与外部设备或计算机与计算机之间的信息交换。 通信有并行通信和串行通信两种方式。在多微机系统以及现代测控系统中信息的交换多采用串行通信方式。 串行通信的基本概念 异步通信 异步通信是指通信的发送与接收设备使用各自的时钟控制数据的发送和接收过程。为使双方的收发协调,要求发送和接收设备的时钟尽可能一致。 异步通信是以字符(构成的帧)为单位进行传输,字符与字符之间的间隙(时间间隔)是任意的,但每个字符中的各位是以固定的时间传送的,即字符之间不一定有“位间隔”的整数倍的关系,但同一字符内的各位之间的距离均为“位间隔”
[单片机]
串口通信详解(<font color='red'>51单片机</font>)
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved