由于篇幅有限以下只有部分代碼,本程序的完整版本成從 http://m.raoushi.com/f/xjjd.rar 下載.
/*===========================================================================
CopyLeft(CL) FORVERE Wjj
All rights NOT reserved
版權(quán)所無,翻版不究,但請保留此處信息
http://blog.sina.com.cn/u/2150397142
any problem or suggestion mail to: 15258297408@163.com
******************************************************************************
*文件名:Motor_simulation
*文件說明:洗衣機正反轉(zhuǎn)、定時、加速減速模擬源代碼
*版本: The final version
*芯片: STC89C52RC
*晶振: (外)內(nèi)部12MHz晶振
*作者: Wang Jian Jun
*日期: 2010年6月4日
*編譯環(huán)境: keil4 & proteus7
*結(jié)果: 軟件測試通過,實物測試通過
*說明: 洗衣機正反轉(zhuǎn)、定時、加速減速模擬,由LCD1602顯示定時時長,并倒計時顯示,
轉(zhuǎn)速(轉(zhuǎn)速由0-9數(shù)字表征),轉(zhuǎn)動由數(shù)碼管段位交替顯示來體現(xiàn)
=============================================================================*/
#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; //計數(shù)變量定義
uint time = 0;
uint time1 = 0; //定時時間存儲變量
uint Speed = 4; //速度選擇 值越大速度越慢
uint Direction = 0; //方向標志
uint LedPa = 0; //數(shù)碼管參數(shù)
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寫數(shù)據(jù)子程序 ***
*** 無返回值 ***
************************************/
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() //主函數(shù)
{
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) //主循環(huán)
{
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);
}
} //以上顯示定時時間,轉(zhuǎn)速
}
/***********************************
*** 定時器0中斷服務程序 ***
*** 無返回值 ***
************************************/
void timer_0() interrupt 1
{
count++;
if(count==(6800/Speed))
{
count=0;
Direction=~Direction; //10s轉(zhuǎn)向取反
}
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;
} //數(shù)碼管段位交替顯示
TH0 = (65536 - (Speed*1000))/256;
TL0 = (65536 - (Speed*1000))%256; //重裝初值
}
/***********************************
*** 定時器1中斷服務程序 ***
*** 返回time1 ***
************************************/
void timer_1() interrupt 3
{
count3++;
if(count3 == 20) //定時1s
{
time1--; //實現(xiàn)倒計時
if(time1 == 0)
{
TR0 = ~TR0; //時間到關timer0
TR1 = ~TR1; //時間到關timer2
time1 = 0;
pp=0; //時間到報警
}
count3 = 0;
}
TH1=0x3c;
TL1=0xb0; //重裝初值
}



