专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

洗衣机正反转、定时、加速减速模拟源代码(实物制作通过)

作者:佚名   来源:本站原创   点击数:  更新时间:2011年09月29日   【字体:

 
 


 


 

由于篇幅有限以下只有部分代码,本程序的完整版本成从 http://www.51hei.com/f/xjjd.rar  下载.

/*===========================================================================
                                CopyLeft(CL) FORVERE Wjj
                             All rights NOT reserved
                      版权所无,翻版不究,但请保留此处信息
                           http://blog.sina.com.cn/u/2150397142   
                  any problem or suggestion mail to:  15258297408@163.com
******************************************************************************
*文件名:Motor_simulation
*文件说明:洗衣机正反转、定时、加速减速模拟源代码
*版本:  The final version
*芯片:  STC89C52RC
*晶振:  (外)内部12MHz晶振
*作者:  Wang Jian Jun
*日期:  2010年6月4日  
*编译环境: keil4 & proteus7 
*结果:  软件测试通过,实物测试通过

*说明:  洗衣机正反转、定时、加速减速模拟,由LCD1602显示定时时长,并倒计时显示,
            转速(转速由0-9数字表征),转动由数码管段位交替显示来体现
=============================================================================*/
#include<reg52.h>               //加载C51核心库文件
#include<intrins.h>             //加载应用型库文件
#define nop() _nop_()
#define N 15536
#define uint unsigned int
#define uchar unsigned char    //宏定义,方便写程序

sbit key0 = P0^0;
sbit key1 = P0^1;
sbit key2 = P0^2;
sbit key3 = P0^3;              //定时选择、启动(再次启动)按键定义
sbit pp = P2^7;                 //定时到报警输出口

sbit SpeAdd = P0^5;         //速度加
sbit SpeSub = P0^4;         //速度减

sbit lcden=P2^2;
sbit lcdrw=P2^1;
sbit lcdrs=P2^0;               //LCD控制端口定义

uint count = 0;
uint count1 = 0;
uint count2 = 0;
uint count3 = 0;               //计数变量定义

uint time = 0;
uint time1 = 0;                 //定时时间存储变量

uint Speed = 4;               //速度选择 值越大速度越慢
uint Direction = 0;            //方向标志
uint LedPa = 0;                //数码管参数

uchar LedCode1[] = {0Xfe, 0Xfd, 0Xfb, 0Xf7, 0Xef, 0Xdf};      //正时针显示
uchar LedCode2[] = {0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe};        //逆时针显示

uchar idata table[]={"Set Time:"};                                         //第一行提示语"Set Time:"
uchar idata table1[]={"Real Speed:"};                                  //第一行提示语"Real Speed:"

/***********************************
***      延时子程序          ***
***          无返回值          ***
***********************************/
void  DelayNS(uint dly)   
{  
    uint i;
    for(; dly>0; dly--) 
       for(i=0; i<100; i++);
}

/***********************************
***         LCD忙检测       ***
***        返回忙标志    ***
************************************/
bit lcd_busy()
{
 bit result;
 lcdrw = 1;
 lcdrs = 0;
 lcden = 1;
 nop();nop();nop();nop();
 result = (bit)(P1&0x80);
 lcden = 0;
 return(result);
}


/***********************************
***       LCD写命令子程序   ***
***          无返回值          ***
************************************/
void write_com(uchar com)
{
    while(lcd_busy());      //LCD忙等待
 lcdrs = 0;
 lcdrw = 0;
 P1 = com;
 DelayNS(5);
 lcden = 1;
 DelayNS(5);
 lcden = 0;
}
/***********************************
***      LCD写数据子程序   ***
***        无返回值              ***
************************************/
void write_data(uchar date)
{
    while(lcd_busy());      //LCD忙等待
 lcdrs = 1;
 lcdrw = 0;
 P1 = date;
 DelayNS(5);
 lcden = 1;
 DelayNS(5);
 lcden = 0;
}

/***********************************
***         LCD初始化       ***
***         无返回值             ***
************************************/
void lcd_init()
{
 lcden = 0;
 write_com(0x38);
 DelayNS(5);
 write_com(0x0c);
 DelayNS(5);
 write_com(0x06);
 DelayNS(5);
 write_com(0x01);
 DelayNS(5);
 write_com(0x80);
 DelayNS(5);
 write_com(0x01);
} 

/***********************************
***       键盘扫描子程序   ***
***         无返回值             ***
************************************/
void keyscan()
{
    P1=0xff;
 if(key0==0)
 {
  DelayNS(10);
  if(key0==0)
  {
   time = 300;
   time1 = time;
  }
        while(!key0);       //等待按键松开
 }     //设置300s
 if(key1==0)
 {
  DelayNS(10);
  if(key1==0)
  {
   time = 200;
   time1 = time;
  }
  while(!key1);           //等待按键松开
 }     //设置200s
 if(key2==0)
 {
  DelayNS(10);
  if(key2==0)
  {
   time = 100; 
   time1 = time;
  }
  while(!key2);            //等待按键松开
 }      //设置100s
 if(key3==0)
 {
  DelayNS(10);
  if(key3==0)
  { 
   while(!key3);          //等待按键松开
   TR1 = ~TR1;
   TR0 = ~TR0;
   time1 = time;
   pp=1;
  }
 }       //启动(再次启动)
    
}
/***********************************
***           主程序       ***
***                              ***
************************************/
void main()            //主函数
{
 uint i;
 lcd_init();             //LCD初始化
 EA = 1;                //开总中断 
 ET0 = 1;              //开定时器0中断
 ET1 = 1;             //开定时器0中断
 TMOD = 0x11;            //定时器0和1的工作方式都为1
 TH0 = 0x00;  
 TL0 = 0x00;
  TH1=0x3c;
 TL1=0xb0;                   //定时初值
 Direction = 0;              //方向设置(顺)
 for(i=0;i<9;i++)  
{    
  write_data(table[i]);
  DelayNS(2);
 }                                                    //第一行提示语"Set Time:"显示
 write_com(0x80+0x40);  //LCD第二行起始地址
 for(i=0;i<11;i++)  
    {    
  write_data(table1[i]);
  DelayNS(2);
 }       //第一行提示语"Real Speed:"
 write_com(0x80);
 while(1)        //主循环
 {
  keyscan();    //按键扫描
  table[10]=time1/100+0x30;
  table[11]=time1%100/10+0x30;
  table[12]=time1%100%10+0x30;
  table[13]=0x73;
  write_com(0x80+0x0a);
  for(i=10;i<14;i++)  
        {    
   write_data(table[i]);
   DelayNS(2);
     }
  table1[12]=(10-Speed)+0x30;
  write_com(0x80+0x4c);
  for(i=12;i<13;i++)
  {
   write_data(table1[i]);
   DelayNS(2); 
  }
 }          //以上显示定时时间,转速
}
/***********************************
***     定时器0中断服务程序   ***
***         无返回值             ***
************************************/
void timer_0() interrupt 1    
{
 count++;
 if(count==(6800/Speed))
 {
  count=0;
  Direction=~Direction; //10s转向取反 
 }
 if(!SpeAdd)                 //速度加判断
 {
  DelayNS(10);
  while(!SpeAdd);
  DelayNS(10);
  ++Speed;
  if(Speed == 10)      //档位溢出处理
     {
   Speed = 9;
  }
 }
 if(!SpeSub)                 //速度减判断
 {
  DelayNS(10);
  while(!SpeSub);
  DelayNS(10);
  Speed--;
  if(Speed  == 1)   //档位溢出处理
  {
   Speed = 2;
  }  
 }
 count1++;
 if(count1 == 50)
 { 
  if(Direction)
  {
       P3 = LedCode1[LedPa++];
       if(LedPa == 6)
   {
    LedPa = 0;
   }   
  } 
  if(!Direction)
  {
    P3 = LedCode2[LedPa++];
    if(LedPa == 6)
   {
    LedPa = 0;
   }
  }
   count1 = 0;
  }                //数码管段位交替显示
 TH0 = (65536 - (Speed*1000))/256;
 TL0 = (65536 - (Speed*1000))%256; //重装初值
}
/***********************************
***     定时器1中断服务程序   ***
***         返回time1            ***
************************************/
void timer_1() interrupt 3   
{
 count3++;
 if(count3 == 20)    //定时1s
 {
  time1--;     //实现倒计时
  if(time1 == 0)
  {
   TR0 = ~TR0;    //时间到关timer0
   TR1 = ~TR1;    //时间到关timer2
   time1 = 0;
   pp=0;     //时间到报警
  }
  count3 = 0;
 }
    TH1=0x3c;
 TL1=0xb0;         //重装初值
}

关闭窗口

相关文章