由于篇幅有限以下只有部分代碼,本程序的完整版本成從 http://www.torrancerestoration.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 *文件說明:洗衣機(jī)正反轉(zhuǎn)、定時(shí)、加速減速模擬源代碼 *版本: The final version *芯片: STC89C52RC *晶振: (外)內(nèi)部12MHz晶振 *作者: Wang Jian Jun *日期: 2010年6月4日 *編譯環(huán)境: keil4 & proteus7 *結(jié)果: 軟件測試通過,實(shí)物測試通過 *說明: 洗衣機(jī)正反轉(zhuǎn)、定時(shí)、加速減速模擬,由LCD1602顯示定時(shí)時(shí)長,并倒計(jì)時(shí)顯示, 轉(zhuǎn)速(轉(zhuǎn)速由0-9數(shù)字表征),轉(zhuǎn)動(dòng)由數(shù)碼管段位交替顯示來體現(xiàn) =============================================================================*/ #include<reg52.h> //加載C51核心庫文件 #include<intrins.h> //加載應(yīng)用型庫文件 #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; //定時(shí)選擇、啟動(dòng)(再次啟動(dòng))按鍵定義 sbit pp = P2^7; //定時(shí)到報(bào)警輸出口 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; //計(jì)數(shù)變量定義 uint time = 0; uint time1 = 0; //定時(shí)時(shí)間存儲變量 uint Speed = 4; //速度選擇 值越大速度越慢 uint Direction = 0; //方向標(biāo)志 uint LedPa = 0; //數(shù)碼管參數(shù) uchar LedCode1[] = {0Xfe, 0Xfd, 0Xfb, 0Xf7, 0Xef, 0Xdf}; //正時(shí)針顯示 uchar LedCode2[] = {0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe}; //逆時(shí)針顯示 uchar idata table[]={"Set Time:"}; //第一行提示語"Set Time:" uchar idata table1[]={"Real Speed:"}; //第一行提示語"Real Speed:" /*********************************** *** 延時(shí)子程序 *** *** 無返回值 *** ***********************************/ void DelayNS(uint dly) { uint i; for(; dly>0; dly--) for(i=0; i<100; i++); } /*********************************** *** LCD忙檢測 *** *** 返回忙標(biāo)志 *** ************************************/ 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); //等待按鍵松開 } //設(shè)置300s if(key1==0) { DelayNS(10); if(key1==0) { time = 200; time1 = time; } while(!key1); //等待按鍵松開 } //設(shè)置200s if(key2==0) { DelayNS(10); if(key2==0) { time = 100; time1 = time; } while(!key2); //等待按鍵松開 } //設(shè)置100s if(key3==0) { DelayNS(10); if(key3==0) { while(!key3); //等待按鍵松開 TR1 = ~TR1; TR0 = ~TR0; time1 = time; pp=1; } } //啟動(dòng)(再次啟動(dòng)) } /*********************************** *** 主程序 *** *** *** ************************************/ void main() //主函數(shù) { uint i; lcd_init(); //LCD初始化 EA = 1; //開總中斷 ET0 = 1; //開定時(shí)器0中斷 ET1 = 1; //開定時(shí)器0中斷 TMOD = 0x11; //定時(shí)器0和1的工作方式都為1 TH0 = 0x00; TL0 = 0x00; TH1=0x3c; TL1=0xb0; //定時(shí)初值 Direction = 0; //方向設(shè)置(順) 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); } } //以上顯示定時(shí)時(shí)間,轉(zhuǎn)速 } /*********************************** *** 定時(shí)器0中斷服務(wù)程序 *** *** 無返回值 *** ************************************/ 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; //重裝初值 } /*********************************** *** 定時(shí)器1中斷服務(wù)程序 *** *** 返回time1 *** ************************************/ void timer_1() interrupt 3 { count3++; if(count3 == 20) //定時(shí)1s { time1--; //實(shí)現(xiàn)倒計(jì)時(shí) if(time1 == 0) { TR0 = ~TR0; //時(shí)間到關(guān)timer0 TR1 = ~TR1; //時(shí)間到關(guān)timer2 time1 = 0; pp=0; //時(shí)間到報(bào)警 } count3 = 0; } TH1=0x3c; TL1=0xb0; //重裝初值 }