由于篇幅有限以下只有部分代码,本程序的完整版本成从 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; //重装初值 }