#include "c.h" #include "math.h" #include "stdlib.h" int room_temp; int copper_temp; /********************ADC设备*/ extern ADC_HandleTypeDef hadc; #define set_filtering_times 50 struct { //ADC_HandleTypeDef *device; int filtering_times; unsigned long adc_filtering[2]; int adc_value[2]; }ADCC; /********************红外线接收设备*/ #define read_infrared HAL_GPIO_ReadPin(INFRARED_GPIO_Port,INFRARED_Pin) //讀取引腳電平 struct { uint8_t buff[5]; uint8_t new_flag:1; }infrared; /*******************按钮*/ struct { uint8_t down:1; uint8_t pow:1; uint8_t up:1; uint8_t down_l:1; uint8_t pow_l:1; uint8_t up_l:1; }button; /*********************压缩机*/ struct { uint32_t last_off_time; uint8_t flag:1; uint8_t flag_:1; uint8_t lock:1; }comper; /*********************设置*/ struct { int temp; int auto_temp; uint8_t mode; uint8_t fan_speed; uint8_t fan_swing; uint32_t times; uint8_t times_hours; uint8_t times_off:1; uint8_t times_on:1; uint8_t sleep:1; uint8_t fan_auto:1; }sett; /*********************风摆*/ struct { int set_step; int now_step; uint32_t delay_time; uint8_t lock:1; }stepp; const uint8_t swing_tab[4]={0x80,0x40,0x20,0x10}; void Sand_Byte_to_swing_595(uint8_t h) { ds_in_or_out(1); hc595_ds(0); hc595_sc_swing(0); hc595_sh(0); for(char a=0;a<8;a++) { if((h<stepp.delay_time) { stepp.delay_time+=10; if(stepp.lock==0) { if(stepp.now_step==stepp.set_step) { Sand_Byte_to_swing_595(0); }else { if(stepp.now_step>stepp.set_step) { stepp.now_step--; }else { stepp.now_step++; } Sand_Byte_to_swing_595(~swing_tab[stepp.now_step%4]); } }else { Sand_Byte_to_swing_595(0); } } } const uint8_t temp_tab[15]={0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0}; const uint8_t time_tab[15]={0x08,0x04,0x0c,0x02,0x0a,0x06,0x0e,0x01,0x09,0x80,0x88,0x84,0x8c,0x82,0x8a}; uint8_t chack_temp(const uint8_t *t,uint8_t i) { i=i&0xf0; for(char a=0;a<15;a++) { if(t[a]==i) { return a; } } return 15; } double adc_to_temp(uint16_t adc) { double val=adc; double fenya=(val/4096)*5; //计算分压,基准电压5V, // 欧姆定律 r/100=fenya/(5-fenya) double r=fenya/(5-fenya)*100000; //通过分压计算热敏电阻阻值,下拉电阻为10k, return ( 1/(log(r/100000) /3950 + 1/(25+273.15))-273.15); //公式法,热敏电阻β值3950,通过热敏电阻阻值计算温度, } void cool() { vr(0); //四通阀关闭 heat(0);//辅助制热关闭 if(room_temp<=sett.temp) { comper.flag=0; }else { if(room_temp>sett.temp+3) { comper.flag=1;//压缩机开启 } } } void dehumi() { vr(0); heat(0); if(copper_temp<=3) //无视设定温度,使铜管保持在3-5度 { comper.flag=0; }else { if(copper_temp>6) { comper.flag=1; } } } void fan() { vr(0); heat(0); comper.flag=0; } void hot() { vr(1); if(room_temp>=sett.temp) { comper.flag=0; heat(0); }else { if(room_temp>5; }else { sett.mode=255; } sett.temp=chack_temp(temp_tab,infrared.buff[1])+16;//设置温度 if((infrared.buff[2]&0xe0)==0) { sett.fan_auto=1; }else { sett.fan_auto=0; sett.fan_speed=(infrared.buff[2]&0xe0); } sett.fan_swing=(infrared.buff[2]&0x10)>>4; sett.sleep=infrared.buff[2]&0x1; if(infrared.buff[2]&0x08) { sett.times_on=0; sett.times_off=1; }else if(infrared.buff[2]&0x04) { sett.times_on=1; sett.times_off=0; sett.times=HAL_GetTick(); }else { sett.times_on=0; sett.times_off=0; sett.times=HAL_GetTick(); } sett.times_hours=chack_temp(time_tab,infrared.buff[3])+1; if(buzzer_busy==0) { add_a_note(1,1,50); } } } //*强制启动按钮被按下*/ if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==0) { comper.lock=0; } //*面板按钮*/ if(button.pow_l==0) { if(panel.flag_s2_t==1) { button.pow=1; button.pow_l=1; add_a_note(1,1,50); sett.sleep=0; } }else { button.pow=0; if(panel.flag_s2_t==0) { button.pow_l=0; } } if(button.down_l==0) { if(panel.flag_s1_t==1) { button.down=1; button.down_l=1; add_a_note(1,1,50); sett.sleep=0; } }else { button.down=0; if(panel.flag_s1_t==0) { button.down_l=0; } } if(button.up_l==0) { if(panel.flag_s3_t==1) { button.up=1; button.up_l=1; add_a_note(1,1,50); sett.sleep=0; } }else { button.up=0; if(panel.flag_s3_t==0) { button.up_l=0; } } if(button.pow==1) { if(sett.mode==255) { sett.mode=1; sett.times_off=0; sett.times_on=0; }else { sett.mode=255; sett.times_off=0; sett.times_on=0; } } /*业务逻辑*/ panel.now_temp=room_temp;//当前温度直接显示到面板 panel.set_temp=sett.temp; //**********************模式控制*/ switch(sett.mode) { case 255: //关机模式 //*************关闭所有继电器 comper.flag=0; heat(0); out_fan(0); vr(0); swing(0); fan_l(0); fan_m(0); fan_h(0); stepp.lock=0; stepp.set_step=400; panel.now_temp=noe;//关闭显示 panel.set_temp=noe; break; case 1: //自动模式 if(button.down==1) { sett.auto_temp--; } if(button.up==1) { sett.auto_temp++; } sett.temp=sett.auto_temp; //设置温度25 if(room_temp>(sett.auto_temp+3)) //房间温度大于28 { cool(); //模式设为制冷 }else if(room_temp<(sett.auto_temp-5)) //房间温度小于20 { hot(); //设为制热 }else { fan(); //房间21-27度吹风模式 } break; case 0: //制冷模式 if(button.down==1) { sett.temp--; } if(button.up==1) { sett.temp++; } cool(); break; case 4: //除湿模式 if(button.down==1) { sett.temp--; } if(button.up==1) { sett.temp++; } dehumi(); break; case 2: //吹风 fan(); panel.set_temp=noe; break; case 6: //制热模式 if(button.down==1) { sett.temp--; } if(button.up==1) { sett.temp++; } hot(); break; } //*********************温度设置范围*/ if(sett.temp>30){sett.temp=30;} if(sett.temp<16){sett.temp=16;} if(sett.auto_temp>30){sett.auto_temp=30;} if(sett.auto_temp<16){sett.auto_temp=16;} //***********************风扇控制*/ if(sett.mode!=255) //非关机状态 { out_fan(1); if(sett.fan_auto==1) { if(((rand()%60000))==0) { sett.fan_speed=0xc0; }else if(((rand()%60000))==0) { sett.fan_speed=0x40; }else if(((rand()%60000))==0) { sett.fan_speed=0x80; } } if(sett.fan_speed==0xc0) { fan_h(0); fan_m(0); fan_l(1); //先关闭无关继电器,最后再开启需要的继电器 } if(sett.fan_speed==0x40) { fan_h(0); fan_l(0); fan_m(1); } if(sett.fan_speed==0x80) { fan_m(0); fan_l(0); fan_h(1); } //*****************风摆控制*/ if(sett.fan_swing==1) { swing(1); stepp.lock=0; if(stepp.now_step==stepp.set_step) { if(stepp.set_step<=0) { stepp.set_step=400; }else if(stepp.set_step>=400) { stepp.set_step=0; } } }else { stepp.lock=1; swing(0); } if(sett.sleep==1) { panel.led_green=0; panel.led_red=0; panel.set_temp=noe; panel.now_temp=noe; } if(sett.times_off) { if(HAL_GetTick()>sett.times+(sett.times_hours*1000*60)) { sett.mode=255; sett.times_off=0; } if(HAL_GetTick()&0x200) { panel.led_red=0; } } }else { if(sett.times_on) { if(HAL_GetTick()>sett.times+(sett.times_hours*1000*60)) { sett.mode=1; sett.times_on=0; } if(HAL_GetTick()&0x200) { panel.led_red=0; } } } /*状态机服务*/ //**********************压缩机保护*/ if((comper.lock==0)&&(comper.flag_==0)&&(comper.flag==1)) //解锁状态压缩机由关闭到打开 { comper.flag_=1; comp(1); //直接启动压缩机 panel.led_green=1; } if((comper.lock==0)&&(comper.flag_==1)&&(comper.flag==0)) //解锁状态压缩机由打开到关闭 { comper.flag_=0; comp(0); //直接启动压缩机 panel.led_green=0; comper.lock=1; //上锁 comper.last_off_time=HAL_GetTick(); //记录关闭的时间 } if((comper.lock==1)&&(HAL_GetTick()>comper.last_off_time+180000)) //上锁状态且时间过去180秒 { comper.lock=0; //解锁 } //*******************/ panel_scan_server(); //面板扫描显示 buzzer_busy=buzzer_play_server(); //蜂鸣器控制 Stepper_Motor_Control(); } } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { uint32_t time_a=0,time_b=0; //time_out=HAL_GetTick()+20; //設置n ms內完成讀取 防止while卡死 #define timeout 50000 switch(GPIO_Pin) { case INFRARED_Pin: Sand_Byte_to_595(0xff,0xff); while(read_infrared==0) { time_a++;if(time_a>timeout){return;} } //第一個數據是模塊的開始傳輸標誌 這個數據直接略過 time_a=0; while(read_infrared==1) { time_a++;if(time_a>timeout){return;} } //第一個數據是模塊的開始傳輸標誌 這個數據直接略過 time_a=0; for(uint8_t a=0;a<5;a++) { for(uint8_t b=0;b<8;b++) { while(read_infrared==0){time_a++;if(time_a>timeout){return;}} //等待總線被拉高,并且对基准计时 while(read_infrared==1){time_b++;if(time_b>timeout){return;}} //總線被拉低,并且计时拉低时间 infrared.buff[a]<<=1; //先高位 所以向左移(就是这里,先左移)動 if(time_b>(time_a*2)) //讀取時間 如果時間大於40us { infrared.buff[a]|=0x01; //說明這一位數據是1 給到最低位(再或操作) } time_a=0; time_b=0; } } infrared.new_flag=1; break; } }