找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8122|回復(fù): 12
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)智能窗簾代碼仿真資料分享

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
電路原理圖如下:


10UF電解電容    C2
47UF電解電容    C6
光敏電阻    R10
限位開關(guān)    K1, K2
微動(dòng)開關(guān)    KEY1, KEY2, KEY3, KEY4, KEY5
步進(jìn)電機(jī)    P1
DC-002電源插座    P2
LCD1602液晶    Q1
紅外一體接頭    Q5
10K色環(huán)電阻    R1, R4, R5, R6, R8, R9
10K電位器    R2
10k排阻    R3
雙擲開關(guān)    SW1
2Pi插針    U2
STC89C52單片機(jī)    U3
ADC0832模數(shù)轉(zhuǎn)換芯片    U4
ULN2003電機(jī)驅(qū)動(dòng)芯片    U5
DS1302時(shí)鐘芯片    U6
12MHZ晶振    Y1
32.768KHZ晶振    Y2

單片機(jī)源程序如下:
  1. /*************************************************************
  2.                       智能窗簾

  3. 補(bǔ)充說明:
  4. ***************************************************************/
  5. #include<reg52.h>                   //頭文件
  6. #include<LCD1602.h>
  7. #include<DS1302.h>
  8. #include<28BYJ48.h>
  9. #include<EEPROM.h>
  10. #include<ADC0832.h>
  11. #include<HW.h>

  12. #define uchar unsigned char//宏定義
  13. #define uint unsigned int

  14. /*******************引腳定義*********************/
  15. sbit key_mode = P1^0;         //設(shè)置鍵
  16. sbit key_jia  = P1^1;         //加值鍵
  17. sbit key_jian = P1^2;         //減值鍵
  18. sbit key_ok   = P1^3;         //確定鍵

  19. sbit sw1=P3^7;           //全開 限位開關(guān)
  20. sbit sw2=P3^6;           //全關(guān) 限位開關(guān)
  21. /*******************變量定義*********************/
  22. uchar light_up,light_down;//存儲(chǔ)光強(qiáng)上、下限值
  23. uchar set_f=0;                //設(shè)置選擇標(biāo)記,=0非設(shè)置,=1設(shè)置年,=2設(shè)置月,=3設(shè)置日,=4設(shè)置時(shí),=5設(shè)置分,=6設(shè)置秒
  24.                                         //              =7設(shè)置定時(shí)-時(shí),=8設(shè)置定時(shí)-分,=9設(shè)置定時(shí)-開關(guān),=10設(shè)置窗簾打開/關(guān)閉
  25.                                         //                                =11設(shè)置光強(qiáng)上限,=12設(shè)置光強(qiáng)下限,=13設(shè)置校準(zhǔn)窗簾位置

  26. uchar num;                        //計(jì)數(shù)變量
  27. uchar ds[4];            //定時(shí)控制開時(shí)、分、控制關(guān)時(shí)、分

  28. uchar mode=0;                //模式標(biāo)記。=0手動(dòng),=1定時(shí),=2光控
  29. uchar light;        //存儲(chǔ)光強(qiáng)

  30. uint moto_num=0;  //記錄窗簾位置
  31. uchar moto_state=0;//窗簾狀態(tài),=0已經(jīng)關(guān)閉,=1處于運(yùn)轉(zhuǎn)過程中,=2已經(jīng)打開
  32. bit moto_f=0;           //標(biāo)記當(dāng)前控制狀態(tài),=0控制關(guān),=1控制開
  33. uchar code display_mode[3][3]={"SD\0","DS\0","GK\0"};//顯示模式
  34. /********************************************************
  35. 函數(shù)名稱:void delayms(uint ms)
  36. 函數(shù)作用:毫秒延時(shí)函數(shù)
  37. 參數(shù)說明:
  38. ********************************************************/
  39. void delayms(uint ms)
  40. {
  41.         unsigned char i=100,j;
  42.         for(;ms;ms--)
  43.         {
  44.                 while(--i)
  45.                 {
  46.                         j=10;
  47.                         while(--j);
  48.                 }
  49.         }
  50. }

  51. /********************************************************
  52. 函數(shù)名稱:void display(void)
  53. 函數(shù)作用:正常顯示日期、時(shí)間、光強(qiáng)等函數(shù)
  54. 參數(shù)說明:
  55. ********************************************************/
  56. void display(void)
  57. {
  58.         uint t[3];        

  59.         //顯示時(shí)間
  60.         LCD_disp_char(0,2,ASCII[time[2]/10]);//顯示時(shí)【0:表示第1列,2:表示第2行,所有關(guān)于顯示都一樣】
  61.         LCD_disp_char(1,2,ASCII[time[2]%10]);
  62.         LCD_disp_char(2,2,':');
  63.         LCD_disp_char(3,2,ASCII[time[1]/10]);//顯示分【3:表示第4列,2:表示第2行,所有關(guān)于顯示都一樣】
  64.         LCD_disp_char(4,2,ASCII[time[1]%10]);
  65.         LCD_disp_char(5,2,':');
  66.         LCD_disp_char(6,2,ASCII[time[0]/10]);//顯示秒
  67.         LCD_disp_char(7,2,ASCII[time[0]%10]);

  68.         //顯示日期
  69.         LCD_disp_char(0,1,ASCII[time[6]/10]);//顯示年
  70.         LCD_disp_char(1,1,ASCII[time[6]%10]);
  71.         LCD_disp_char(2,1,'/');
  72.         LCD_disp_char(3,1,ASCII[time[4]/10]);//顯示月
  73.         LCD_disp_char(4,1,ASCII[time[4]%10]);
  74.         LCD_disp_char(5,1,'/');
  75.         LCD_disp_char(6,1,ASCII[time[3]/10]);//顯示日
  76.         LCD_disp_char(7,1,ASCII[time[3]%10]);

  77.         //顯示模式
  78.         lcd1602_write_character(9,1,display_mode[mode]);
  79.        
  80.         //顯示光強(qiáng)
  81.         if(light>99)
  82.                 LCD_disp_char(12,1,ASCII[light/100]);
  83.         else
  84.                 LCD_disp_char(12,1,' ');
  85.         LCD_disp_char(13,1,ASCII[light%100/10]);
  86.         LCD_disp_char(14,1,ASCII[light%10]);
  87.         LCD_disp_char(15,1,'%');

  88.         //光強(qiáng)控制
  89.         if(mode==2)//光控模式
  90.         {         
  91.                 if((light>=light_up||light<light_down))//判斷實(shí)際光強(qiáng)是否【大于等于上限 或 小于下限值】、當(dāng)前處于打開狀態(tài)
  92.                 {       
  93.                         moto_f=0;         //標(biāo)記當(dāng)前控制窗簾關(guān)閉  
  94.                         moto_state=1;//標(biāo)記窗簾處于運(yùn)轉(zhuǎn)過程中
  95.                 }
  96.                 else
  97.                         if((light<light_up&&light>=light_down))//判斷實(shí)際光強(qiáng)是否【大于等于下限值 并且 小于上限】、當(dāng)前處于關(guān)閉狀態(tài)
  98.                         {
  99.                                 moto_f=1;         //標(biāo)記當(dāng)前控制窗簾打開  
  100.                                 moto_state=1;//標(biāo)記窗簾處于運(yùn)轉(zhuǎn)過程中
  101.                         }
  102.         }
  103.         else
  104.                 if(mode==1)//定時(shí)模式
  105.                 {
  106.                         t[0]=time[2]*60+time[1];//當(dāng)前時(shí)間
  107.                         t[1]=ds[0]*60+ds[1];        //窗簾開啟時(shí)間點(diǎn)
  108.                         t[2]=ds[2]*60+ds[3];        //窗簾關(guān)閉時(shí)間點(diǎn)
  109.                        
  110.                         if(t[1]<t[2])                         //0時(shí) --> t[1] --> t[2] --> 24時(shí)
  111.                         {
  112.                                 if(t[0]>=t[1]&&t[0]<=t[2])
  113.                                         moto_f=1;            //標(biāo)記當(dāng)前需要打開窗簾
  114.                                 else
  115.                                         moto_f=0;                //標(biāo)記當(dāng)前需要關(guān)閉窗簾
  116.                         }
  117.                         else                                        //0時(shí) --> t[2] --> t[1] --> 24時(shí)
  118.                         {
  119.                                 if(t[0]>=t[1]||t[0]<=t[2])
  120.                                         moto_f=1;                //標(biāo)記當(dāng)前需要打開窗簾
  121.                                 else
  122.                                         moto_f=0;                //標(biāo)記當(dāng)前需要關(guān)閉窗簾
  123.                         }
  124.                         moto_state=1;          //標(biāo)記窗簾處于運(yùn)轉(zhuǎn)過程中
  125.                 }
  126.         if(moto_f==0&&moto_state!=0&&sw2!=0)//控制關(guān)閉窗簾
  127.         {
  128.                 if(moto_num==0)                          //控制次數(shù)減到0時(shí),表示窗戶已經(jīng)關(guān)閉完成
  129.                 {
  130.                         BYJ48=P2&0xf0;                  //關(guān)閉步進(jìn)電機(jī)
  131.                         moto_state=0;                  //標(biāo)記窗簾處于關(guān)閉狀態(tài)
  132.                         lcd1602_write_character(10,2,"ZT:OFF");
  133.                 }
  134.                 else
  135.                 {
  136.                         motor_z();                                  //步進(jìn)電機(jī)正轉(zhuǎn)
  137.                         moto_num--;                                  //控制次數(shù)-1
  138.                         lcd1602_write_character(10,2,"-->OFF");
  139.                 }               
  140.         }
  141.         else                  
  142.                 if(moto_f==1&&moto_state!=2&&sw1!=0)//控制打開窗簾
  143.                 {
  144.                         if(moto_num>=192)          //控制次數(shù)加到128時(shí),表示窗戶已經(jīng)打開完成
  145.                         {
  146.                                 BYJ48=P2&0xf0;                  //關(guān)閉步進(jìn)電機(jī)
  147.                                 moto_state=2;          //標(biāo)記窗簾處于打開狀態(tài)
  148.                                 lcd1602_write_character(10,2,"ZT:ON ");
  149.                         }
  150.                         else
  151.                         {
  152.                                 motor_f();                          //步進(jìn)電機(jī)反轉(zhuǎn)
  153.                                 moto_num++;                          //控制次數(shù)+1
  154.                                 lcd1602_write_character(10,2,"-->ON ");
  155.                         }               
  156.                 }
  157.                 else                                          //窗戶處于停止?fàn)顟B(tài)
  158.                 {
  159.                         BYJ48=P2&0xf0;                  //關(guān)閉步進(jìn)電機(jī)
  160.                         if(moto_state==0||sw2==0)
  161.                                 lcd1602_write_character(10,2,"ZT:OFF");
  162.                         else
  163.                                 if(moto_state==2||sw1==0)
  164.                                         lcd1602_write_character(10,2,"ZT:ON ");       
  165.                 }         
  166. }
  167. /********************************************************
  168. 函數(shù)名稱:void display2(void)
  169. 函數(shù)作用:顯示調(diào)整日期、時(shí)間函數(shù)
  170. 參數(shù)說明:
  171. ********************************************************/
  172. void display2()
  173. {
  174.         num++;

  175.         lcd1602_write_character(1,1,"Date:");
  176.         lcd1602_write_character(1,2,"Time:");
  177.        
  178.         if(num%2==0)        //偶數(shù)次顯示,奇數(shù)次不顯示。這樣就會(huì)有閃爍效果,可以清楚看到當(dāng)前設(shè)置的是哪個(gè)值
  179.         {
  180.                 LCD_disp_char(6,1,ASCII[time[6]/10]); //顯示年
  181.                 LCD_disp_char(7,1,ASCII[time[6]%10]);
  182.                 LCD_disp_char(8,1,'/');  
  183.                 LCD_disp_char(9,1,ASCII[time[4]/10]); //顯示月
  184.                 LCD_disp_char(10,1,ASCII[time[4]%10]);          
  185.                 LCD_disp_char(11,1,'/');
  186.                 LCD_disp_char(12,1,ASCII[time[3]/10]);//顯示日
  187.                 LCD_disp_char(13,1,ASCII[time[3]%10]);
  188.        
  189.                 LCD_disp_char(6,2,ASCII[time[2]/10]); //顯示時(shí)
  190.                 LCD_disp_char(7,2,ASCII[time[2]%10]);
  191.                 LCD_disp_char(8,2,':');  
  192.                 LCD_disp_char(9,2,ASCII[time[1]/10]); //顯示分
  193.                 LCD_disp_char(10,2,ASCII[time[1]%10]);          
  194.                 LCD_disp_char(11,2,':');
  195.                 LCD_disp_char(12,2,ASCII[time[0]/10]);//顯示秒
  196.                 LCD_disp_char(13,2,ASCII[time[0]%10]);
  197.         }       
  198.         else                        //奇數(shù)次不顯示
  199.         {
  200.                 switch(set_f)//根據(jù)當(dāng)前設(shè)置的內(nèi)容,對應(yīng)位置閃爍
  201.                 {
  202.                         case 1: lcd1602_write_character(6,1,"  "); break;
  203.                         case 2: lcd1602_write_character(9,1,"  "); break;
  204.                         case 3: lcd1602_write_character(12,1,"  "); break;
  205.                         case 4: lcd1602_write_character(6,2,"  "); break;
  206.                         case 5: lcd1602_write_character(9,2,"  "); break;
  207.                         case 6: lcd1602_write_character(12,2,"  "); break;
  208.                         default: break;
  209.                 }
  210.         }       
  211. }
  212. /********************************************************
  213. 函數(shù)名稱:void display3(void)
  214. 函數(shù)作用:顯示調(diào)整定時(shí)時(shí)間函數(shù)
  215. 參數(shù)說明:
  216. ********************************************************/
  217. void display3()
  218. {
  219.         num++;
  220.         lcd1602_write_character(0, 1, "Sets timer time:");
  221.         lcd1602_write_character(7, 2, "--");
  222.         if(num%2==0)        //偶數(shù)次顯示,奇數(shù)次不顯示。這樣就會(huì)有閃爍效果,可以清楚看到當(dāng)前設(shè)置的是哪個(gè)值
  223.         {            
  224.                 LCD_disp_char(1, 2, ASCII[ds[0]/10]);  //顯示定時(shí)開-時(shí)
  225.                 LCD_disp_char(2, 2, ASCII[ds[0]%10]);   
  226.                 LCD_disp_char(3, 2, ':');
  227.                 LCD_disp_char(4, 2, ASCII[ds[1]/10]);  //顯示定時(shí)開-分
  228.                 LCD_disp_char(5, 2, ASCII[ds[1]%10]);

  229.                 LCD_disp_char(10, 2, ASCII[ds[2]/10]); //顯示定時(shí)關(guān)-時(shí)
  230.                 LCD_disp_char(11, 2, ASCII[ds[2]%10]);   
  231.                 LCD_disp_char(12, 2, ':');
  232.                 LCD_disp_char(13, 2, ASCII[ds[3]/10]); //顯示定時(shí)關(guān)-分
  233.                 LCD_disp_char(14, 2, ASCII[ds[3]%10]);
  234.         }
  235.         else                         //奇數(shù)次不顯示
  236.         {
  237.                 switch(set_f)//根據(jù)當(dāng)前設(shè)置的內(nèi)容,對應(yīng)位置閃爍
  238.                 {
  239.                         case 7: lcd1602_write_character(1,2,"  "); break;
  240.                         case 8: lcd1602_write_character(4,2,"  "); break;
  241.                         case 9: lcd1602_write_character(10,2,"  "); break;
  242.                         case 10: lcd1602_write_character(13,2,"  "); break;
  243.                         default: break;
  244.                 }
  245.         }
  246. }
  247. /********************************************************
  248. 函數(shù)名稱:void display4(void)
  249. 函數(shù)作用:顯示調(diào)整光強(qiáng)控制函數(shù)
  250. 參數(shù)說明:
  251. ********************************************************/
  252. void display4(void)
  253. {
  254.         num++;

  255.         lcd1602_write_character(0, 1, "Light_Up  :");
  256.         lcd1602_write_character(0, 2, "Light_Down:");
  257.         LCD_disp_char(15,1,'%');
  258.         LCD_disp_char(15,2,'%');
  259.         if(num%2==0)        //偶數(shù)次顯示,奇數(shù)次不顯示。這樣就會(huì)有閃爍效果,可以清楚看到當(dāng)前設(shè)置的是哪個(gè)值
  260.         {
  261.                 LCD_disp_char(12, 1, ASCII[light_up/100]);           //顯示光強(qiáng)上限值
  262.                 LCD_disp_char(13, 1, ASCII[light_up%100/10]);
  263.                 LCD_disp_char(14, 1, ASCII[light_up%10]);   
  264.        
  265.                 LCD_disp_char(12, 2, ASCII[light_down/100]);   //顯示光強(qiáng)下限值
  266.                 LCD_disp_char(13, 2, ASCII[light_down%100/10]);       
  267.                 LCD_disp_char(14, 2, ASCII[light_down%10]);
  268.         }
  269.         else                           //奇數(shù)次不顯示
  270.         {
  271.                 switch(set_f)//根據(jù)當(dāng)前設(shè)置的內(nèi)容,對應(yīng)位置閃爍
  272.                 {
  273.                         case 11: lcd1602_write_character(12,1,"   "); break;
  274.                         case 12: lcd1602_write_character(12,2,"   "); break;
  275.                         default: break;
  276.                 }
  277.         }
  278. }
  279. /********************************************************
  280. 函數(shù)名稱:void scan(void)
  281. 函數(shù)作用:按鍵查詢處理函數(shù)
  282. 參數(shù)說明:
  283. ********************************************************/
  284. void scan(void)
  285. {
  286.         //設(shè)置鍵
  287.         if(hw_data=='B'||key_mode==0)      //按鍵按下
  288.         {  
  289.                 delayms(7);                                            //延時(shí)消抖
  290.                 if(hw_data=='B'||key_mode==0)  //再次確認(rèn)按鍵按下       
  291.                 {
  292.                         BYJ48=P2&0xf0;                            //關(guān)閉步進(jìn)電機(jī)
  293.                         if(set_f==6)                                //日期、時(shí)間校準(zhǔn)完
  294.                         {
  295.                                 LCD_write_command(0x01);//清除屏幕顯示
  296.                                 delay_n40us(100);                //延時(shí)等待全部清除完畢
  297.                                 set_f=13;                                //跳到校準(zhǔn)窗簾狀態(tài)
  298.                         }
  299.                         else
  300.                                 if(set_f==0)            //進(jìn)入設(shè)置先清除屏幕,顯示設(shè)置部分
  301.                                 {
  302.                                         Writeds1302 (WRITE_PROTECT,0X00);//禁止DS1302寫保護(hù)
  303.                                         LCD_write_command(0x01);         //清除屏幕顯示
  304.                                         delay_n40us(100);                         //延時(shí)等待全部清除完畢
  305.                                         switch(mode)//根據(jù)對應(yīng)的模式,設(shè)置對應(yīng)的參數(shù)
  306.                                         {
  307.                                                 case 0: set_f=1; break;                 //手動(dòng)模式
  308.                                                 case 1: set_f=7; break;                 //定時(shí)模式
  309.                                                 case 2: set_f=11; break;         //光控模式
  310.                                                 default: break;
  311.                                         }       
  312.                                 }
  313.                                 else
  314.                                         if(set_f==10||set_f==12)//進(jìn)入設(shè)置日期時(shí)間
  315.                                         {
  316.                                                 LCD_write_command(0x01);     //清除屏幕顯示
  317.                                                 delay_n40us(100);                     //延時(shí)等待全部清除完畢
  318.                                                 set_f=1;                                         //進(jìn)入校準(zhǔn)時(shí)間
  319.                                         }
  320.                                          else
  321.                                                 set_f++;                                         //設(shè)置變量+1
  322.                         if(set_f>12)
  323.                         {
  324.                                 set_f=0;                                                         //重置設(shè)置變量

  325.                                 Writeds1302 (WRITE_MINUTE,(time[1]/10)*16+time[1]%10);//將設(shè)置好的時(shí)間寫入DS1302
  326.                                 Writeds1302 (WRITE_SECOND,(time[0]/10)*16+time[0]%10);

  327.                                 EEPROM_delete(0x2200);                                  //擦除扇區(qū)
  328.                                 EEPROM_write(0x2200,ds[0]);     //寫入【定時(shí)時(shí)間】數(shù)據(jù)保存
  329.                                 EEPROM_write(0x2210,ds[1]);     //寫入【定時(shí)時(shí)間】數(shù)據(jù)保存存
  330.                                 EEPROM_write(0x2220,ds[2]);     //寫入【定時(shí)時(shí)間】數(shù)據(jù)保存存
  331.                                 EEPROM_write(0x2230,ds[3]);     //寫入【定時(shí)時(shí)間】數(shù)據(jù)保存存
  332.                                 EEPROM_write(0x2240,light_up);  //寫入【光強(qiáng)上限值】數(shù)據(jù)保存
  333.                                 EEPROM_write(0x2250,light_down);//寫入【光強(qiáng)下限值】數(shù)據(jù)保存

  334.                                 LCD_write_command(0x01);             //清除屏幕顯示
  335.                                 delay_n40us(100);                             //延時(shí)等待全部清除完畢
  336.                         }                        
  337.                 }
  338.                 while(!key_mode);                            //等待按鍵松開       
  339.         }
  340.         //確定
  341.         if(hw_data=='Q'||key_ok==0)                                //按鍵按下
  342.         {
  343.                 delayms(7);                                                                //延時(shí)消抖
  344.                 if((hw_data=='Q'||key_ok==0)&&set_f!=0)//再次確認(rèn)按鍵按下
  345.                 {
  346.                         if(set_f<7)
  347.                         {
  348.                                 Writeds1302 (WRITE_MINUTE,(time[1]/10)*16+time[1]%10);//將設(shè)置好的時(shí)間寫入DS1302
  349.                                 Writeds1302 (WRITE_SECOND,(time[0]/10)*16+time[0]%10);
  350.                         }
  351.                         set_f=0;                                                        //重置設(shè)置變量
  352.        
  353.                         EEPROM_delete(0x2200);                                  //擦除扇區(qū)
  354.                         EEPROM_write(0x2200,ds[0]);     //寫入【定時(shí)時(shí)間】數(shù)據(jù)保存
  355.                         EEPROM_write(0x2210,ds[1]);     //寫入【定時(shí)時(shí)間】數(shù)據(jù)保存存
  356.                         EEPROM_write(0x2220,ds[2]);     //寫入【定時(shí)時(shí)間】數(shù)據(jù)保存存
  357.                         EEPROM_write(0x2230,ds[3]);     //寫入【定時(shí)時(shí)間】數(shù)據(jù)保存存
  358.                         EEPROM_write(0x2240,light_up);  //寫入【光強(qiáng)上限值】數(shù)據(jù)保存
  359.                         EEPROM_write(0x2250,light_down);//寫入【光強(qiáng)下限值】數(shù)據(jù)保存

  360.                         LCD_write_command(0x01);            //清除屏幕顯示
  361.                         delay_n40us(100);                            //延時(shí)等待全部清除完畢
  362.                 }
  363.                 else
  364.                         if(key_ok==0&&set_f==0)                            //切換模式
  365.                         {
  366.                                 mode++;                                                        //模式變量+1
  367.                                 if(mode>=3)                                                //最大3個(gè)模式
  368.                                         mode=0;                                                //重新回到第1個(gè)模式
  369.                                 if(moto_state==1)                                //如果處于運(yùn)轉(zhuǎn)過程中
  370.                                 {
  371.                                         if(moto_f==0)                                //控制步進(jìn)電機(jī)關(guān)閉
  372.                                                 moto_state=0;
  373.                                         else                                                //控制步進(jìn)電機(jī)打開
  374.                                                 moto_state=2;               
  375.                                 }
  376.                                 EEPROM_delete(0x2400);                    //擦除扇區(qū)
  377.                                 EEPROM_write(0x2400,mode);      //寫入【模式】數(shù)據(jù)保存               
  378.                         }
  379.                 while(!key_ok);                                //等待按鍵松開
  380.         }
  381.         //加鍵        ,下面減鍵內(nèi)容一樣       
  382.         if(hw_data=='+'||key_jia==0)
  383.         {
  384.                 delayms(7);
  385.                 if((hw_data=='+'||key_jia==0)&&set_f!=0)
  386.                 {
  387.                         if(set_f==1)           //設(shè)置年
  388.                         {
  389.                                 time[6]++;                                                        //年份+1
  390.                                 time[6]=(time[6]/10)*16+time[6]%10;        //將年份轉(zhuǎn)換成16進(jìn)制,例如:16年-->0x16
  391.                                 if(time[6]>0x79)                                        //判斷是否達(dá)到最大年份79年
  392.                                         time[6]=0x00;                                        //重新回到00年
  393.                                 Writeds1302 (WRITE_YEA,time[6]);        //將設(shè)置好的年份寫入到DS1302存儲(chǔ)起來
  394.                         }
  395.                
  396.                         if(set_f==2)           //設(shè)置月
  397.                         {
  398.                                 time[4]++;                                                        //月份+1
  399.                                 time[4]=(time[4]/10)*16+time[4]%10;        //將月份轉(zhuǎn)換成16進(jìn)制,例如:08月-->0x08
  400.                                 if(time[4]>0x12)                                        //判斷是否達(dá)到最大月份12月
  401.                                         time[4]=0x01;                                        //重新回到01月
  402.                                 Writeds1302 (WRITE_MONTH,time[4]);        //將設(shè)置好的月份寫入到DS1302存儲(chǔ)起來
  403.                         }
  404.                
  405.                         if(set_f==3)         //設(shè)置日
  406.                         {
  407.                                 time[3]++;                                                        //日份+1
  408.                                 time[3]=(time[3]/10)*16+time[3]%10;        //將日份轉(zhuǎn)換成16進(jìn)制,例如:15日-->0x15
  409.                                 if(time[4]==1||time[4]==3||time[4]==5||time[4]==7||time[4]==8||time[4]==10||time[4]==12)//1,3,5,7,8,10,12為大月,每月31天
  410.                                 {
  411.                                         if(time[3]>0x31)                                //判斷是否達(dá)到最大日份31日
  412.                                                 time[3]=0x01;                                //重新回到01日
  413.                                 }
  414.                                 else                                                                //否者2,4,6,9,11為小月
  415.                                 {
  416.                                         if(time[4]==0x02)                                //如果是2月,需要區(qū)分閏、平年
  417.                                         {
  418.                                                 if(((!(time[6]%4) && (time[6]%100)) || !(time[6]%400))==0)//如果閏年
  419.                                                 {
  420.                                                         if(time[3]>0x28)                //判斷是否達(dá)到最大日份28日
  421.                                                                 time[3]=0x01;                //重新回到01日
  422.                                                 }
  423.                                                 else                                                //否者平年
  424.                                                 {
  425.                                                         if(time[3]>0x29)                //判斷是否達(dá)到最大日份29日
  426.                                                                 time[3]=0x01;                //重新回到01日
  427.                                                 }
  428.                                         }
  429.                                         else                                                        //否者為剩下的月份
  430.                                         {
  431.                                                 if(time[3]>0x30)                        //判斷是否達(dá)到最大日份30日
  432.                                                         time[3]=0x01;                        //重新回到01日
  433.                                         }
  434.                                 }       
  435.                                 Writeds1302 (WRITE_DAY,time[3]);        //將設(shè)置好的日份寫入到DS1302存儲(chǔ)起來
  436.                         }
  437.                
  438.                         if(set_f==4)          //設(shè)置時(shí),同上
  439.                         {                       
  440.                                 time[2]++;
  441.                                 time[2]=(time[2]/10)*16+time[2]%10;
  442.                                 if(time[2]>0x23)
  443.                                         time[2]=0x00;
  444.                                 Writeds1302 (WRITE_HOUR,time[2]);       
  445.                         }
  446.                
  447.                         if(set_f==5)          //設(shè)置分,同上
  448.                         {
  449.                                 time[1]++;
  450.                                 time[1]=(time[1]/10)*16+time[1]%10;
  451.                                 if(time[1]>0x59)
  452.                                         time[1]=0x00;
  453.                                 Writeds1302 (WRITE_MINUTE,time[1]);       
  454.                         }
  455.                
  456.                         if(set_f==6)         //設(shè)置秒,同上
  457.                         {
  458.                                 time[0]++;
  459.                                 time[0]=(time[0]/10)*16+time[0]%10;
  460.                                 if(time[0]>0x59)
  461.                                         time[0]=0x00;
  462.                                 Writeds1302 (WRITE_SECOND,time[0]);       
  463.                         }
  464.                        
  465.                         if(set_f==7)     //設(shè)置定時(shí)起始時(shí)間——時(shí)      
  466.                         {
  467.                                 if(ds[0]<23)
  468.                                         ds[0]++;  
  469.                                 else
  470.                                         ds[0]=0;                       
  471.                         }
  472.        
  473.                         if(set_f==8)    //設(shè)置定時(shí)起始時(shí)間——分        
  474.                         {
  475.                                 if(ds[1]<59)
  476.                                         ds[1]++;  
  477.                                 else
  478.                                         ds[1]=0;                 
  479.                         }

  480.                         if(set_f==9)     //設(shè)置定時(shí)結(jié)束時(shí)間——時(shí)      
  481.                         {
  482.                                 if(ds[2]<23)
  483.                                         ds[2]++;  
  484.                                 else
  485.                                         ds[2]=0;                       
  486.                         }
  487.        
  488.                         if(set_f==10)    //設(shè)置定時(shí)結(jié)束時(shí)間——分        
  489.                         {
  490.                                 if(ds[3]<59)
  491.                                         ds[3]++;  
  492.                                 else
  493.                                         ds[3]=0;                 
  494.                         }
  495.                         if(set_f==11)    //設(shè)置 光強(qiáng)上限值
  496.                         {
  497.                                 if(light_up<99)//最大值可設(shè)置99%
  498.                                         light_up++;//光強(qiáng)上限值+1%
  499.                         }
  500.        
  501.                         if(set_f==12)    //設(shè)置 光強(qiáng)下限值
  502.                         {
  503.                                 if(light_down<99&&light_down+1<light_up)//最大值可設(shè)置99%,并且下限不能超過上限
  504.                                         light_down++;//光強(qiáng)下限值+1%
  505.                         }
  506.                 }
  507.                 else
  508.                         if((hw_data=='+'||key_jia==0)&&set_f==0&&mode==0)//手動(dòng)控制窗簾打開
  509.                         {         
  510.                                 if(moto_state==1&&moto_f==1)//已經(jīng)在控制狀態(tài)。并且控制打開
  511.                                         moto_state=2;    //停止運(yùn)作
  512.                                 else
  513.                                 {
  514.                                         if(moto_num<192)//判斷是否不處于打開狀態(tài)
  515.                                         {
  516.                                                 moto_f=1;         //控制開閉窗
  517.                                                 moto_state=1;    //開啟運(yùn)作
  518.                                         }
  519.                                 }
  520.                                 while(!key_jia);     //等待按鍵松開
  521.                         }       
  522.         }
  523.         //減鍵
  524.         if(hw_data=='-'||key_jian==0)
  525.         {
  526.                 delayms(7);
  527.                 if((hw_data=='-'||key_jian==0)&&set_f!=0)
  528.                 {
  529.                         if(set_f==1)         //設(shè)置年
  530.                         {
  531.                                 if(time[6]==0)                                           //判斷當(dāng)前是否為00年
  532.                                         time[6]=79;                                           //如果是回到最大年份:79年
  533.                                 else
  534.                                         time[6]--;                                           //否者,年份-1
  535.                                 time[6]=(time[6]/10)*16+time[6]%10;//將年份轉(zhuǎn)換成16進(jìn)制,例如:16年-->0x16                       
  536.                                 Writeds1302 (WRITE_YEA,time[6]);   //將設(shè)置好的年份寫入到DS1302存儲(chǔ)起來
  537.                         }
  538.        
  539.                         if(set_f==2)         //設(shè)置月,同上
  540.                         {
  541.                                 if(time[4]==1)
  542.                                         time[4]=12;
  543.                                 else
  544.                                         time[4]--;
  545.                                 time[4]=(time[4]/10)*16+time[4]%10;
  546.                                 Writeds1302 (WRITE_MONTH,time[4]);               
  547.                         }
  548.        
  549.                         if(set_f==3)        //設(shè)置日,同上
  550.                         {
  551.                                 time[3]--;
  552.                                 time[3]=(time[3]/10)*16+time[3]%10;
  553.                                 if(time[4]==1||time[4]==3||time[4]==5||time[4]==7||time[4]==8||time[4]==10||time[4]==12)
  554.                                 {
  555.                                         if(time[3]<0x01)
  556.                                                 time[3]=0x31;
  557.                                 }
  558.                                 else
  559.                                 {
  560.                                         if(time[4]==0x02)
  561.                                         {
  562.                                                 if(((!(time[6]%4) && (time[6]%100)) || !(time[6]%400))==0)
  563.                                                 {
  564.                                                         if(time[3]<0x01)
  565.                                                                 time[3]=0x28;
  566.                                                 }
  567.                                                 else
  568.                                                 {
  569.                                                         if(time[3]<0x01)
  570.                                                                 time[3]=0x29;
  571.                                                 }
  572.                                         }
  573.                                         else
  574.                                         {
  575.                                                 if(time[3]<0x01)
  576.                                                         time[3]=0x30;
  577.                                         }
  578.                                 }       
  579.                                 Writeds1302 (WRITE_DAY,time[3]);               
  580.                         }
  581.        
  582.                         if(set_f==4)        //設(shè)置時(shí),同上
  583.                         {                       
  584.                                 if(time[2]==0)
  585.                                         time[2]=23;
  586.                                 else
  587.                                         time[2]--;
  588.                                 time[2]=(time[2]/10)*16+time[2]%10;
  589.                                 Writeds1302 (WRITE_HOUR,time[2]);               
  590.                         }
  591.        
  592.                         if(set_f==5)        //設(shè)置分,同上
  593.                         {
  594.                                 if(time[1]==0)
  595.                                         time[1]=59;
  596.                                 else
  597.                                         time[1]--;
  598.                                 time[1]=(time[1]/10)*16+time[1]%10;
  599.                                 Writeds1302 (WRITE_MINUTE,time[1]);               
  600.                         }
  601.        
  602.                         if(set_f==6)        //設(shè)置秒,同上
  603.                         {
  604.                                 if(time[0]==0)
  605.                                         time[0]=59;
  606.                                 else
  607.                                         time[0]--;
  608.                                 time[0]=(time[0]/10)*16+time[0]%10;
  609.                                 Writeds1302 (WRITE_SECOND,time[0]);                       
  610.                         }
  611.                         if(set_f==7)     //設(shè)置定時(shí)起始時(shí)間——時(shí)      
  612.                         {
  613.                                 if(ds[0]>0)
  614.                                         ds[0]--;  
  615.                                 else
  616.                                         ds[0]=23;                       
  617.                         }
  618.        
  619.                         if(set_f==8)    //設(shè)置定時(shí)起始時(shí)間——分        
  620.                         {
  621.                                 if(ds[1]>0)
  622.                                         ds[1]--;  
  623.                                 else
  624.                                         ds[1]=59;                 
  625.                         }

  626.                         if(set_f==9)     //設(shè)置定時(shí)結(jié)束時(shí)間——時(shí)      
  627.                         {
  628.                                 if(ds[2]>0)
  629.                                         ds[2]--;  
  630.                                 else
  631.                                         ds[2]=23;                       
  632.                         }
  633.        
  634.                         if(set_f==10)    //設(shè)置定時(shí)結(jié)束時(shí)間——分        
  635.                         {
  636.                                 if(ds[3]>0)
  637.                                         ds[3]--;  
  638.                                 else
  639.                                         ds[3]=59;                 
  640.                         }

  641.                         if(set_f==11)    //設(shè)置 光強(qiáng)上限值
  642.                         {
  643.                                 if(light_up!=0&&light_up>light_down+1)//最小值可設(shè)置成0,并且上限值要大于下限值
  644.                                         light_up--;  //光強(qiáng)上限值-1%
  645.                         }
  646.        
  647.                         if(set_f==12)    //設(shè)置 光強(qiáng)下限值
  648.                         {
  649.                                 if(light_down!=0)//最小值可設(shè)置成0
  650.                                         light_down--;//光強(qiáng)下限值-1%
  651.                         }
  652.                 }
  653.                 else
  654.                         if((hw_data=='-'||key_jian==0)&&set_f==0&&mode==0)//手動(dòng)控制窗戶關(guān)閉
  655.                         {
  656.                                 if(moto_state==1&&moto_f==0)//已經(jīng)在控制狀態(tài)。并且控制打開
  657.                                         moto_state=0;    //停止運(yùn)作
  658.                                 else
  659.                                 {
  660.                                         if(moto_num>0)//判斷是否不處于打開狀態(tài)
  661.                                         {
  662.                                                 moto_f=0;         //控制開閉窗
  663.                                                 moto_state=1;    //開啟運(yùn)作
  664.                                         }
  665.                                 }
  666.                                 while(!key_jian);    //等待按鍵松開       
  667.                         }
  668.         }
  669.         //紅外遙控切換模式
  670.         if(hw_data=='|'&&set_f==0)
  671.         {
  672.                 mode++;                                                        //模式變量+1
  673.                 if(mode>=3)                                                //最大3個(gè)模式
  674.                         mode=0;                                                //重新回到第1個(gè)模式
  675.                 if(moto_state==1)                                //如果處于運(yùn)轉(zhuǎn)過程中
  676.                 {
  677.                         if(moto_f==0)                                //控制步進(jìn)電機(jī)關(guān)閉
  678.                                 moto_state=0;
  679.                         else                                                //控制步進(jìn)電機(jī)打開
  680.                                 moto_state=2;               
  681.                 }
  682.                 EEPROM_delete(0x2400);                    //擦除扇區(qū)
  683.                 EEPROM_write(0x2400,mode);      //寫入【模式】數(shù)據(jù)保存
  684.         }

  685.         //紅外遙控切換設(shè)置上一個(gè)參數(shù)
  686.         if(hw_data=='<'&&set_f!=0)
  687.         {
  688.                 if(set_f==7||set_f==11)
  689.                 {
  690.                         LCD_write_command(0x01);    //清除屏幕顯示
  691.                         delay_n40us(100);                    //延時(shí)等待全部清除完畢
  692.                         set_f=6;
  693.                 }
  694.                 else
  695.                         if(set_f==1)
  696.                         {
  697.                                 LCD_write_command(0x01);//清除屏幕顯示
  698.                                 delay_n40us(100);                //延時(shí)等待全部清除完畢
  699.                                 switch(mode)//根據(jù)對應(yīng)的模式,設(shè)置對應(yīng)的參數(shù)
  700.                                 {
  701.                                         case 0: set_f=6; break;        //手動(dòng)模式
  702.                                         case 1: set_f=10; break;//定時(shí)模式
  703.                                         case 2: set_f=12; break;//光控模式
  704.                                         default: break;
  705.                                 }
  706.                         }
  707.                         else
  708.                                 set_f--;
  709.         }

  710.         //紅外遙控切換設(shè)置下一個(gè)參數(shù)
  711.         if(hw_data=='>'&&set_f!=0)
  712.         {
  713.                 if(set_f==6)                                //日期、時(shí)間校準(zhǔn)完
  714.                 {
  715.                         LCD_write_command(0x01);//清除屏幕顯示
  716.                         delay_n40us(100);                //延時(shí)等待全部清除完畢
  717.                         set_f=13;                                //跳到校準(zhǔn)窗簾狀態(tài)
  718.                 }
  719.                 else
  720.                         if(set_f==10||set_f==12)
  721.                         {
  722.                                 LCD_write_command(0x01);     //清除屏幕顯示
  723.                                 delay_n40us(100);                     //延時(shí)等待全部清除完畢
  724.                                 set_f=1;                                         //進(jìn)入校準(zhǔn)時(shí)間
  725.                         }
  726.                          else
  727.                                 set_f++;                                         //設(shè)置變量+1
  728.                 if(set_f>12)
  729.                 {
  730.                         Writeds1302 (WRITE_PROTECT,0X00);//禁止DS1302寫保護(hù)
  731.                         LCD_write_command(0x01);         //清除屏幕顯示
  732.                         delay_n40us(100);                         //延時(shí)等待全部清除完畢
  733.                         switch(mode)//根據(jù)對應(yīng)的模式,設(shè)置對應(yīng)的參數(shù)
  734.                         {
  735.                                 case 0: set_f=1; break;                 //手動(dòng)模式
  736.                                 case 1: set_f=7; break;                 //定時(shí)模式
  737.                                 case 2: set_f=11; break;         //光控模式
  738.                                 default: break;
  739.                         }
  740.                 }
  741.         }
  742.         hw_data=0xff;//清除紅外接收的數(shù)據(jù)
  743. }
  744. /********************************************************
  745. 函數(shù)名稱:void mian()
  746. 函數(shù)作用:主函數(shù)
  747. 參數(shù)說明:
  748. ********************************************************/
  749. void main()
  750. {
  751.         uchar lowtime;         //記錄上次采集光強(qiáng)的時(shí)間
  752.         uchar nums;                 //循環(huán)計(jì)數(shù)變量

  753.         if(key_ok==0)
  754.         {
  755.                 delayms(100);
  756.                 if(key_ok==0)
  757.                 {
  758.                         EEPROM_delete(0x2200);                                  //擦除扇區(qū)
  759.                         EEPROM_write(0x2200,8); //寫入【定時(shí)時(shí)間】數(shù)據(jù)保存
  760.                         EEPROM_write(0x2210,30);//寫入【定時(shí)時(shí)間】數(shù)據(jù)保存存
  761.                         EEPROM_write(0x2220,16);//寫入【定時(shí)時(shí)間】數(shù)據(jù)保存存
  762.                         EEPROM_write(0x2230,20);//寫入【定時(shí)時(shí)間】數(shù)據(jù)保存存
  763.                         EEPROM_write(0x2240,80);//寫入【光強(qiáng)上限值】數(shù)據(jù)保存
  764.                         EEPROM_write(0x2250,30);//寫入【光強(qiáng)下限值】數(shù)據(jù)保存

  765.                         EEPROM_delete(0x2400);  //擦除扇區(qū)
  766.                         EEPROM_write(0x2400,0); //寫入【模式】數(shù)據(jù)保存
  767.                 }
  768.         }

  769.         ds[0]=EEPROM_read(0x2200);                  //讀取存儲(chǔ)的【定時(shí)時(shí)間】數(shù)據(jù)
  770.         ds[1]=EEPROM_read(0x2210);                  //讀取存儲(chǔ)的【定時(shí)時(shí)間】數(shù)據(jù)
  771.         ds[2]=EEPROM_read(0x2220);                  //讀取存儲(chǔ)的【定時(shí)時(shí)間】數(shù)據(jù)
  772.         ds[3]=EEPROM_read(0x2230);                  //讀取存儲(chǔ)的【定時(shí)時(shí)間】數(shù)據(jù)
  773.         light_up=EEPROM_read(0x2240);          //讀取存儲(chǔ)的【光強(qiáng)上限值】數(shù)據(jù)
  774.         light_down=EEPROM_read(0x2250);   //讀取存儲(chǔ)的【光強(qiáng)下限值】數(shù)據(jù)
  775.         mode=EEPROM_read(0x2400);         //讀取存儲(chǔ)的【模式】數(shù)據(jù)

  776.         HW_init();                                                //紅外接收初始化
  777.         LCD_init();                                    //LCD1602初始化
  778.         ADC0832_read(0);
  779.         ADC0832_read(0);
  780.         while(1)                                                //死循環(huán)
  781.         {               
  782.                 scan();                                //按鍵檢測處理

  783.                 if(set_f==0)                        //正常顯示
  784.                 {
  785.                         nums++;                                //循環(huán)次數(shù)+1
  786.                         if(nums==10)                        //每循環(huán)10次,讀取一次日期、時(shí)間
  787.                         {
  788.                                 nums=0;                                //重置循環(huán)次數(shù)
  789.                                 Read_time();        //讀取日期、時(shí)間
  790.                         }
  791.                         if(time[0]!=lowtime)        //時(shí)間過去一秒
  792.                         {
  793.                                 lowtime=time[0];        //重新記錄時(shí)間
  794.                                 light=ADC0832_read(0);//讀取AD值
  795.                                 light=light*100/255;//轉(zhuǎn)換為光強(qiáng)
  796.                         }
  797.                         display();                                //更新顯示數(shù)據(jù)
  798.                 }
  799.                 else
  800.                         if(set_f<7)                       //校準(zhǔn)日期、時(shí)間       
  801.                         {       
  802.                                 Read_time();       //讀取日期、時(shí)間       
  803.                                 display2();
  804.                         }
  805.                         else
  806.                                 if(set_f<11)       //設(shè)置定時(shí)
  807.                                         display3();
  808.                                 else
  809.                                         if(set_f<13)   //設(shè)置光強(qiáng)控制值
  810.                                                 display4();         
  811.         }
  812. }
復(fù)制代碼

所有資料51hei提供下載:
51智能窗簾.7z (4.32 MB, 下載次數(shù): 173)


評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏8 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:711872 發(fā)表于 2020-3-20 17:49 | 只看該作者
厲害了,努力賺黑幣
回復(fù)

使用道具 舉報(bào)

板凳
ID:711872 發(fā)表于 2020-3-20 17:49 | 只看該作者
厲害了,做下試試
回復(fù)

使用道具 舉報(bào)

地板
ID:366000 發(fā)表于 2020-4-21 00:26 來自手機(jī) | 只看該作者
樓主,可以把整個(gè)文件發(fā)我嗎?包括文檔
回復(fù)

使用道具 舉報(bào)

5#
ID:733618 發(fā)表于 2020-4-21 11:01 來自手機(jī) | 只看該作者
我也是從初學(xué)者過來的,看到論壇上很多問題就像看到當(dāng)初的自己,溫故而知新,幫別人解決問題,自己也能提升,多謝管理員給了一個(gè)這么好的平臺(tái)
回復(fù)

使用道具 舉報(bào)

6#
ID:734207 發(fā)表于 2020-4-21 11:38 來自手機(jī) | 只看該作者
你這個(gè)電路圖有點(diǎn)小問題
回復(fù)

使用道具 舉報(bào)

7#
ID:566857 發(fā)表于 2020-4-26 14:46 | 只看該作者
一天會(huì) 發(fā)表于 2020-4-21 11:38
你這個(gè)電路圖有點(diǎn)小問題

沒有問題吧?我仿真了一下是可以運(yùn)行的呀
回復(fù)

使用道具 舉報(bào)

8#
ID:368810 發(fā)表于 2020-5-23 09:53 | 只看該作者
宋哈娜 發(fā)表于 2020-4-26 14:46
沒有問題吧?我仿真了一下是可以運(yùn)行的呀

我感覺光強(qiáng)光弱電機(jī)轉(zhuǎn)向都是一樣呢?不應(yīng)該是實(shí)現(xiàn)正轉(zhuǎn)反轉(zhuǎn)的嗎?還是因?yàn)殡姍C(jī)轉(zhuǎn)速太快了看起來是一個(gè)轉(zhuǎn)向?
回復(fù)

使用道具 舉報(bào)

9#
ID:759215 發(fā)表于 2020-5-23 15:57 | 只看該作者
努力賺黑幣,太難了
回復(fù)

使用道具 舉報(bào)

10#
ID:822999 發(fā)表于 2020-10-28 09:34 來自手機(jī) | 只看該作者
樓主運(yùn)行無法生成hex文件
回復(fù)

使用道具 舉報(bào)

11#
ID:440526 發(fā)表于 2020-12-19 16:47 | 只看該作者
一切完美,哈哈
回復(fù)

使用道具 舉報(bào)

12#
ID:1138038 發(fā)表于 2024-11-29 14:53 | 只看該作者
努力回復(fù),感謝作者
回復(fù)

使用道具 舉報(bào)

13#
ID:1139620 發(fā)表于 2024-12-13 09:40 來自手機(jī) | 只看該作者
樓主發(fā)的很有用,已經(jīng)在參考學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表