/********************************************/ /* 空调控制系统 /* 张颂 陈丹升 /* v1.9 /* 2007.9.14 /*********************************************/ #include"reg51.h" #include #define uchar unsigned char #define uint unsigned int #define compressor_delay_s 30 //定义压缩机延时时间(0-255s) #define dis_en_delay_set 6 //定义按键按下时 led显示时间 #define AD_CH0 XBYTE[0xBf00] //P2.6=0 in0 sbit fan_h = P1^0; sbit fan_m = P1^1; sbit fan_l = P1^2; sbit compressor_on = P1^3; sbit ext_room_fan = P1^4; sbit valve = P1^5; sbit t_inc = P3^5; sbit t_dec = P3^4; sbit fan_k = P2^7; sbit mod_k = P1^7; sbit on_off= P1^6; sbit P3_2 = P3^2; bit on_off_flag=0 , key_dispose_wait , dis_en_flag=1; uchar tempr_set=27 , work_mode=0 , fan_mode=0 , compressor_delay=0 , dis_en_delay=dis_en_delay_set; uchar temperature_get=0 , work_mode_fact=1,compressor_block=0; uint timer0_extend=1000; uchar code dis_code[30]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71, // 0 1 2 3 4 5 6 7 8 9 a b c d e f 0x36,0x49,0x48,0x08,0x36,0x38,0x71,0x76,0x00}; // || 三 二 一 || L F H OFF uchar dis_buf[6] = {0X36,0X36,0X5b,0X07,0X00,0X00}; //段码 uchar code dis_dig[6]= {0xA0,0x90,0x88,0x84,0x82,0x81}; //位码 P2.7 connect to key --> p2.7=1 uchar code tempr_transform[165]= // transform AD sample to temperature {99,97,95,94,93,91,89,88,87,85,84,83,81,80,79,78,77,76,75, //24 25 26 27 28 ... ... 74,73,72,71,70,69,68,67,67,66,65,64,64,63,62,61,61,60,59, 58,57,57,56,55,55,54,53,53,52,51,51,50,50,49,48,48,47,47, 46,46,45,45,44,44,43,43,42,42,41,41,40,40,39,39,38,38,37, 37,36,36,35,35,34,34,34,33,33,32,32,31,31,30,30,29,29,28, 28,28,27,27,26,26,25,25,24,24,24,23,23,23,22,22,21,21,20, 20,20,19,19,18,18,17,17,16,16,16,15,15,15,14,14,13,13,12, 12,11,11,11,10,10,9,9,8,8,8,7,7,6,6,5,5,5,4,4,3,3,2,2,1, 1,0,0 //... ... 183 184 }; void s_delay(uchar aaa) //short delay { while (aaa>0) { aaa--; aaa=aaa;} } /* timer0 initialization */ void timer0_init() { TMOD= 0X01; TH0 = 0XFC; //1MS TL0 = 0X66; ET0 = 1; TR0 = 1; EA = 1; } /************* 显示子程序 **************/ void display(uchar dis_bit) { P0 = 0X00; //此句防止LED动态显示时,下一位LED将短暂的显示前一位的数值 if(dis_en_flag==1||on_off_flag==1) P2 = dis_dig[dis_bit]; else P2 = 0x80; //显示使能关闭时 led不显示 P0 = dis_buf[dis_bit]; } /**************** 风扇处理 ************/ /* 执行相应的动作 */ void fan_lsub() { fan_h=fan_m=1; fan_l=0; } void fan_msub() { fan_h=fan_l=1; fan_m=0; } void fan_hsub() { fan_m=fan_l=1; fan_h=0; } void fan_auto() { if(work_mode_fact==1) //cold { if((temperature_get-tempr_set)>5) fan_hsub(); else if((temperature_get-tempr_set)<=2) fan_lsub(); else fan_msub(); } else if(work_mode_fact==3) //hot { if((tempr_set-5)>temperature_get) fan_hsub(); else if(tempr_set<=(temperature_get+2)) fan_lsub(); else fan_msub(); } if(work_mode_fact==2) //fan { if(temperature_get>25) fan_hsub(); else if(temperature_get<20) fan_lsub(); else fan_msub(); } } /*************************************************/ /********* 工作模式 ******************/ /********* 执行相应的动作 *****************/ void work_csub() //制冷子程序 { if(compressor_delay==0&&compressor_on==1) { compressor_on=0; compressor_delay=compressor_delay_s; } else if(compressor_delay!=0&&compressor_on==1) compressor_block=1; //3 min protect ext_room_fan =0; valve =1; work_mode_fact=1; } void work_hsub() { if(compressor_delay==0&&compressor_on==1) { compressor_on=0; compressor_delay=compressor_delay_s; } else if(compressor_delay!=0&&compressor_on==1) compressor_block=1; ext_room_fan =0; valve =0; work_mode_fact=3; } void work_fsub() { /* if(compressor_delay==0&&compressor_on==0) { */compressor_on=1; /* compressor_delay=compressor_delay_s; } else if(compressor_delay!=0&&compressor_on==0) compressor_block=2; //3 min protect */ ext_room_fan =1; valve =1; work_mode_fact=2; } void work_auto() { if((tempr_set-5)>temperature_get) work_hsub(); else if((temperature_get>tempr_set)) work_csub(); else work_fsub(); } void work_on_off() { if(on_off_flag==0) { fan_h = 1; fan_m = 1; fan_l = 1; ext_room_fan = 1; valve = 1; /* if(compressor_delay==0&&compressor_on==0) {*/ compressor_on=1; /* compressor_delay=compressor_delay_s; } else if(compressor_delay!=0&&compressor_on==0) compressor_block=2; //3 min protect */ } } /*************************************************/ /************* 温度限制子程序 ******************/ /**** 功能 用于模式改变适应温度设定范围的变化*****/ void mode_tempr_limit() { switch (work_mode) { case(0): if((tempr_set!=25)&&(tempr_set!=27)&&(tempr_set!=29)) {tempr_set=27; //检查温度设置 dis_buf[3]=dis_code[tempr_set%10]; dis_buf[2]=dis_code[tempr_set/10]; } break; case(1): if(tempr_set>32) //检查温度设置是否超出范围 { tempr_set=32; dis_buf[3]=dis_code[tempr_set%10]; dis_buf[2]=dis_code[tempr_set/10]; } if(tempr_set<20) { tempr_set=20; dis_buf[3]=dis_code[tempr_set%10]; dis_buf[2]=dis_code[tempr_set/10]; } break; case(2): dis_buf[2]=dis_buf[3]=0x40; break; case(3): if(tempr_set>30) { tempr_set=30; dis_buf[3]=dis_code[tempr_set%10]; dis_buf[2]=dis_code[tempr_set/10]; } if(tempr_set<14) { tempr_set=14; dis_buf[3]=dis_code[tempr_set%10]; dis_buf[2]=dis_code[tempr_set/10]; } break; } } /****************** key_get ******************/ /****************** 键码获取 ******************/ uchar key_code_get() { uchar key_code_kcg=0; if(t_inc==0) key_code_kcg =0x01; if(t_dec==0) key_code_kcg =0x02; if(fan_k==0) key_code_kcg =0x04; if(mod_k==0) key_code_kcg =0x08; if(on_off==0)key_code_kcg =0x10; return(key_code_kcg); } /******************** 键码处理 ********************/ /* 根据得到的按键码,修改相应的寄存器 */ /* 显示相应的设置 但是不执行动作 */ void key_dispose(uchar temp_kds) { if(dis_en_flag==1||on_off_flag==1) { switch(temp_kds) { case 0x01: if(work_mode!=2) tempr_set++; //温度设置++ if(((work_mode==1)||(work_mode==2))&&(tempr_set>32)) tempr_set=32; if((work_mode==3)&&(tempr_set>30)) tempr_set=30; if(work_mode==0) { tempr_set++; if(tempr_set>=29) tempr_set=29; //各种限制 } if(work_mode!=2) { dis_buf[3]=dis_code[tempr_set%10]; dis_buf[2]=dis_code[tempr_set/10]; } //显示 break; case 0x02: if(work_mode!=2) tempr_set--; //温度设置-- if((work_mode==1)&&(tempr_set<20)) tempr_set=20; if(((work_mode==3)||(work_mode==2))&&(tempr_set<14)) tempr_set=14; if(work_mode==0) { tempr_set--; if(tempr_set<=25) tempr_set=25; //各种限制 } if(work_mode!=2) { dis_buf[3]=dis_code[tempr_set%10]; dis_buf[2]=dis_code[tempr_set/10]; } break; case 0x04: fan_mode++; //风扇模式设置 fan_mode%=4; dis_buf[1]=dis_code[0x10+fan_mode]; //模式显示 break; case 0x08: work_mode++; //工作模式设置 work_mode%=4; dis_buf[0]=dis_code[0x14+work_mode]; //显示 mode_tempr_limit(); break; case 0x10: on_off_flag=!on_off_flag; //开关标志设置 break; } key_dispose_wait = 1; } dis_en_delay = dis_en_delay_set; dis_en_flag = 1; //设置按键等待处理标志位(主程序执行) } /***************************************************/ /******** 按键执行程序 *********/ /* 根据与按键相关的寄存执行相应的动作 */ /* 并显示 */ void key_exe() { if(on_off_flag==1) { switch (work_mode) { case(0): work_auto(); break; case(1): work_csub(); break; case(2): work_fsub(); break; case(3): work_hsub(); break; } switch (fan_mode) { case(0): fan_auto(); break; case(1): fan_hsub(); break; case(2): fan_msub(); break; case(3): fan_lsub(); break; } } if(work_mode==2) //风扇模式时 温度设显示为 “-- dis_buf[2]=dis_buf[3]=0x40; else { dis_buf[3]=dis_code[tempr_set%10]; dis_buf[2]=dis_code[tempr_set/10]; } } /* AD采集 */ /* 输出是上一次转换值 */ /* 并且启动一次采样 供下一次读取*/ uchar ad_sample() { uchar ad_sample1; P2=0X80; //消除显示干扰 ad_sample1=AD_CH0; //读取 AD_CH0=0X00; //启动一次次采样 return(ad_sample1); } /***************** 温度处理 ************************/ /******功能: 把ad得到的温度值转换成温度值***************/ /*********** 并且把显示代码放入dis_buf中***************/ void tempr_dispose(uchar sample_temp) { if(sample_temp>184||sample_temp<23) { dis_buf[4]=dis_code[14]; if(sample_temp>184) //如果温度 <0 或者温度传感器断路 dis_buf[5]=dis_code[1]; // 显示 "E1" else //如果温度>100 或者温度传感器短路 dis_buf[5]=dis_code[2]; // 显示 "E2" } else { temperature_get=tempr_transform[sample_temp-24]; dis_buf[5]=dis_code[temperature_get%10]; //否则正常显示 dis_buf[4]=dis_code[temperature_get/10]; } } /*************** 工作模式调整 *******************/ /** 用于根据实际情况和设定情况调整实际工作模式 */ void work_adjust() { if(work_mode==1) { if(tempr_set>=temperature_get) work_fsub(); else work_csub(); } if(work_mode==3) { if(tempr_set<=temperature_get) work_fsub(); else work_hsub(); } if(fan_mode==0) fan_auto(); //自动调整风速 if(work_mode==0) work_auto(); // 自动调整工作模式 work_on_off(); } void main() { PT0=1; // t0高优先级 timer0_init(); EX0=1; AD_CH0=0X00; //启动一次 s_delay(250); tempr_dispose(ad_sample()); while(1) { if(key_dispose_wait==1) //如果有按键等待执行 { key_exe(); //执行 key_dispose_wait=0; } if(on_off_flag==1) { work_adjust(); if(compressor_block!=0) //处理压缩机阻塞 { if(compressor_delay==0&&compressor_block==1&&work_mode_fact!=2) { compressor_on=0; // compressor_delay=compressor_delay_s; compressor_block=0; } // if(compressor_delay==0&&compressor_block==2) // { compressor_on=1; // compressor_delay=compressor_delay_s; // compressor_block=0; // } } } } } /**************** 1ms 定时器中断 **********************/ void timer0_1ms() interrupt 1 using 2 { TH0 = 0XFc; TL0 = 0X66; timer0_extend--; display(timer0_extend%6); //display if(timer0_extend==0) //1s { tempr_dispose(ad_sample()); //得到ad值 并处理 if(compressor_delay>0) compressor_delay--; //压缩机保护延时 if(dis_en_delay>0) dis_en_delay--; else dis_en_flag=0; timer0_extend=1000; } } /************ exterior interrupt 0 **************/ /********** key code get and dispose ***********/ void key_code_get_int() interrupt 0 using 3 { uchar key_code1=0 , key_code2=0; EX0=0; //turn off exterior interrupt s_delay(100); key_code1=key_code_get(); if(key_code1!=0) { s_delay(250); key_code2=key_code_get(); if(key_code1==key_code2) key_dispose(key_code1); while(P3_2==0); } EX0=1; }