久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2056|回復: 0
打印 上一主題 下一主題
收起左側

基于51單片機的智能窗簾程序Proteus仿真設計 光敏電阻控制步進電機

[復制鏈接]
跳轉到指定樓層
樓主
   系統簡介:
      1.控制芯片使用51單片機+1602液晶+步進電機;
      2.屏幕顯示當前日期和時間、當前控制模式、當前光照強度;
      3.共支持3種模式,通過按鍵切換:手動模式、定時模式、光控模式;
      4.在手動模式下,通過開窗簾和關窗簾鍵對窗簾進行控制;
      5.在定時模式下,通過按鍵設置開窗簾和關窗簾的時間;
      6.在光控模式下,光照強度大于設置值時開啟窗簾,否則關閉,模擬的是白天開窗,晚上關窗;
      7.步進電機正轉半圈,模擬開窗,紅色LED燈點亮;相反的電機反轉半圈,模擬關窗,紅色LED燈熄滅。
      8.可佩戴下載接口(4個排針),用于連接下載器下載程序, 方便進行升級調試
•        
操作說明:
按鍵1:切換模式(在手動模式、定時模式、光控模式循環切換)。
按鍵2:進入當前時間的設置(年、月、日、時、分的設置)。
按鍵3:進入定時時間和光控閾值大小的設置。
按鍵4:減(手動關閉窗簾)。
按鍵5:加(手動開啟窗簾)。

制作出來的實物圖如下:


(1) 可實時顯示年月日、時分秒、光照強度和控制模式;
(2) 可通過手動控制窗簾的開啟和關閉;
(3) 可通過設置開啟和關閉時間來控制窗簾;
(4) 可通過檢測光照強度的亮暗來控制窗簾;
(5) 使用步進電機的正傳和反轉來模擬窗簾的開啟和關閉;

電路原理圖如下:

元件清單:
編號    "注釋
Comment"    "描述
Description"    "數量
Quantity"
1    CR2032    電池座    1
2    紐扣電池    CR2032   
3    10uf    直插電解電容    1
4    30P    直插瓷片電容    2
5    LED3mm    3mm發紅光二極管    1
6    POWER    DC電源插座    1
7    步進電機        1
8    Header 5    排針5-Pin    1
9    LCD1602    LCD1602液晶顯示器    1
10    LCD1602插座    16P排母    1
11    LCD1602引出腳    16P排針    1
12    10K    9腳排阻    1
13    10K    藍白可調電阻    1
14    10K    色環電阻    5
15    1K    色環電阻    1
16    GL5506    光敏電阻5506 5mm    1
17    SW-PB    按鍵6X6X5MM    5
18    SWITCH    自鎖開關    1
19    MCU    51單片機    1
20    DS1302    時鐘芯片    1
21    IC插座    8腳IC座    1
22    ULN2003    達林頓晶體管    1
23    IC插座    16腳IC座    1
24    ADC0832    模數轉換芯片    1
25    IC插座    8腳IC座    1
26    32.768K    晶振    1
27    12M    晶振    1
必備配套器材            
1    導線    XXcm    1
2    焊錫    XXcm    1
3    USB轉DC3.5mm電源線    系統供電    1
4.2    9*15萬用板        1
5    單片機插座    40腳IC座    1

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)用可調電阻帶代替光敏電阻


單片機源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. #define uchar unsigned char                // 以后unsigned char就可以用uchar代替
  4. #define uint  unsigned int                // 以后unsigned int 就可以用uint 代替


  5. sbit ADC_CS     = P1^6;                         // ADC0832的CS引腳
  6. sbit ADC_CLK    = P1^7;                         // ADC0832的CLK引腳
  7. sbit ADC_DAT    = P3^2;                         // ADC0832的DI/DO引腳
  8. sbit SCK_P      = P1^0;                                // 時鐘芯片DS1302的SCK管腳
  9. sbit SDA_P      = P1^1;                                // 時鐘芯片DS1302的SDA管腳
  10. sbit RST_P      = P1^2;                                // 時鐘芯片DS1302的RST管腳
  11. sbit LcdRs_P    = P1^3;       // 1602液晶的RS管腳      
  12. sbit LcdRw_P    = P1^4;       // 1602液晶的RW管腳
  13. sbit LcdEn_P    = P1^5;       // 1602液晶的EN管腳
  14. sbit KeyMode_P  = P3^3;                                // 模式切換
  15. sbit KeySet_P   = P3^4;                                // 設置時間按鍵
  16. sbit KeySet2_P  = P3^5;                                // 設置時間模式的開關時間和光照控制強度
  17. sbit KeyDown_P  = P3^6;                                // 減按鍵
  18. sbit KeyUp_P    = P3^7;                                // 加按鍵
  19. sbit Led_P      = P2^0;                                // 指示燈

  20. uchar gMode=1;                                                                // 1是手動模式,2是時間自動模式,3是亮度自動模式
  21. uchar OpenHour    = 18;                                // 開啟窗簾的小時
  22. uchar OpenMinute  = 20;                                // 開啟窗簾的分鐘
  23. uchar CloseHour   = 10;                                // 關閉窗簾的小時
  24. uchar CloseMinute = 30;                                // 關閉窗簾的分鐘
  25. uchar gLight      = 40;                                // 窗簾開關的閾值

  26. uchar code Clock[]={0x10,0x20,0x40,0x80};                         // 步進電機順時針旋轉數組
  27. uchar code AntiClock[]={0x80,0x40,0x20,0x10};                // 步進電機逆時針旋轉數組

  28. uchar TimeBuff[7]={17,9,1,6,18,30,40};                                        // 時間數組,默認2017年9月1日,星期五,18:30:40
  29. // TimeBuff[0] 代表年份,范圍00-99
  30. // TimeBuff[1] 代表月份,范圍1-12
  31. // TimeBuff[2] 代表日期,范圍1-31
  32. // TimeBuff[3] 代表星期,范圍1-7
  33. // TimeBuff[4] 代表小時,范圍00-23
  34. // TimeBuff[5] 代表分鐘,范圍00-59
  35. // TimeBuff[6] 代表秒鐘,范圍00-59



  36. /*********************************************************/
  37. // 毫秒級的延時函數,time是要延時的毫秒數
  38. /*********************************************************/
  39. void DelayMs(uint time)
  40. {
  41.         uint i,j;
  42.         for(i=0;i<time;i++)
  43.                 for(j=0;j<112;j++);
  44. }


  45. /*********************************************************/
  46. // 1602液晶寫命令函數,cmd就是要寫入的命令
  47. /*********************************************************/
  48. void LcdWriteCmd(uchar cmd)
  49. {
  50.         LcdRs_P = 0;
  51.         LcdRw_P = 0;
  52.         LcdEn_P = 0;
  53.         P0=cmd;
  54.         DelayMs(2);
  55.         LcdEn_P = 1;   
  56.         DelayMs(2);
  57.         LcdEn_P = 0;        
  58. }


  59. /*********************************************************/
  60. // 1602液晶寫數據函數,dat就是要寫入的數據
  61. /*********************************************************/
  62. void LcdWriteData(uchar dat)
  63. {
  64.         LcdRs_P = 1;
  65.         LcdRw_P = 0;
  66.         LcdEn_P = 0;
  67.         P0=dat;
  68.         DelayMs(2);
  69.         LcdEn_P = 1;   
  70.         DelayMs(2);
  71.         LcdEn_P = 0;
  72. }


  73. /*********************************************************/
  74. // 1602液晶初始化函數
  75. /*********************************************************/
  76. void LcdInit()
  77. {
  78.         LcdWriteCmd(0x38);        // 16*2顯示,5*7點陣,8位數據口
  79.         LcdWriteCmd(0x0C);        // 開顯示,不顯示光標
  80.         LcdWriteCmd(0x06);        // 地址加1,當寫入數據后光標右移
  81.         LcdWriteCmd(0x01);        // 清屏
  82. }


  83. /*********************************************************/
  84. // 液晶光標定位函數
  85. /*********************************************************/
  86. void LcdGotoXY(uchar line,uchar column)
  87. {
  88.         // 第一行
  89.         if(line==0)        
  90.                 LcdWriteCmd(0x80+column);
  91.         // 第二行
  92.         if(line==1)        
  93.                 LcdWriteCmd(0x80+0x40+column);
  94. }


  95. /*********************************************************/
  96. // 液晶輸出字符串函數
  97. /*********************************************************/
  98. void LcdPrintStr(uchar *str)
  99. {
  100.         while(*str!='\0')
  101.                         LcdWriteData(*str++);
  102. }


  103. /*********************************************************/
  104. // 液晶輸出數字(0-99)
  105. /*********************************************************/
  106. void LcdPrintNum(uchar num)
  107. {
  108.         LcdWriteData(num/10+48);                // 十位
  109.         LcdWriteData(num%10+48);                 // 個位
  110. }


  111. /*********************************************************/
  112. // 顯示模式
  113. /*********************************************************/
  114. void LcdPrintMode(uchar num)
  115. {
  116.         switch(num)                        
  117.         {
  118.                 case 1: LcdPrintStr("Manual");        break;
  119.                 case 2: LcdPrintStr("Timing");        break;
  120.                 case 3: LcdPrintStr("Liging");        break;
  121.                 default:                                                                                                break;
  122.         }
  123. }


  124. /*********************************************************/
  125. // 液晶顯示內容的初始化
  126. /*********************************************************/
  127. void LcdShowInit()
  128. {
  129.         LcdGotoXY(0,0);
  130.         LcdPrintStr("20  -  -     :  ");
  131.         LcdGotoXY(1,0);
  132.         LcdPrintStr("           gz:  ");
  133.         LcdGotoXY(1,0);
  134.         LcdPrintMode(gMode);
  135. }



  136. /*********************************************************/
  137. // 刷新時間顯示
  138. /*********************************************************/
  139. void FlashTime()
  140. {
  141.         LcdGotoXY(0,2);                                                                                // 年份
  142.         LcdPrintNum(TimeBuff[0]);
  143.         LcdGotoXY(0,5);                                                                                // 月份
  144.         LcdPrintNum(TimeBuff[1]);
  145.         LcdGotoXY(0,8);                                                                                // 日期
  146.         LcdPrintNum(TimeBuff[2]);
  147.         LcdGotoXY(0,11);                                                                        // 小時
  148.         LcdPrintNum(TimeBuff[4]);
  149.         LcdGotoXY(0,14);                                                                        // 分鐘
  150.         LcdPrintNum(TimeBuff[5]);
  151.         LcdGotoXY(0,13);                                                                        // 秒鐘
  152.         if(TimeBuff[6]%2==0)                                                        // 秒鐘是偶數顯示冒號
  153.                 LcdWriteData(':');
  154.         else                                                                                                                        // 秒鐘是奇數顯示空格
  155.                 LcdWriteData(' ');
  156. }


  157. /*********************************************************/
  158. // 初始化DS1302
  159. /*********************************************************/
  160. void DS1302_Init(void)
  161. {
  162.         RST_P=0;                        // RST腳置低
  163.         SCK_P=0;                        // SCK腳置低
  164.         SDA_P=0;                        // SDA腳置低                                
  165. }


  166. /*********************************************************/
  167. // 從DS1302讀出一字節數據
  168. /*********************************************************/
  169. uchar DS1302_Read_Byte(uchar addr)
  170. {
  171.         uchar i;
  172.         uchar temp;
  173.         
  174.         RST_P=1;                                                               
  175.         
  176.         /* 寫入目標地址:addr*/
  177.         for(i=0;i<8;i++)
  178.         {     
  179.                 if(addr&0x01)
  180.                         SDA_P=1;
  181.                 else
  182.                         SDA_P=0;
  183.                
  184.                 SCK_P=1;
  185.                 _nop_();
  186.                 SCK_P=0;
  187.                 _nop_();
  188.                
  189.                 addr=addr>> 1;
  190.         }
  191.         
  192.         /* 讀出該地址的數據 */
  193.         for(i=0;i<8;i++)
  194.         {
  195.                 temp=temp>>1;
  196.                
  197.                 if(SDA_P)
  198.                         temp|= 0x80;
  199.                 else
  200.                         temp&=0x7F;
  201.                
  202.                 SCK_P=1;
  203.                 _nop_();
  204.                 SCK_P=0;
  205.                 _nop_();
  206.         }
  207.         
  208.         RST_P=0;
  209.         
  210.         return temp;
  211. }


  212. /*********************************************************/
  213. // 向DS1302寫入一字節數據
  214. /*********************************************************/
  215. void DS1302_Write_Byte(uchar addr, uchar dat)
  216. {
  217.         uchar i;
  218.         
  219.         RST_P = 1;
  220.         
  221.         /* 寫入目標地址:addr*/
  222.         for(i=0;i<8;i++)
  223.         {
  224.                 if(addr&0x01)
  225.                         SDA_P=1;
  226.                 else
  227.                         SDA_P=0;

  228.                 SCK_P=1;
  229.                 _nop_();
  230.                 SCK_P=0;
  231.                 _nop_();
  232.                
  233.                 addr=addr>>1;
  234.         }
  235.         
  236.         /* 寫入數據:dat*/
  237.         for(i=0;i<8;i++)
  238.         {
  239.                 if(dat&0x01)
  240.                         SDA_P=1;
  241.                 else
  242.                         SDA_P=0;
  243.         
  244.                 SCK_P=1;
  245.                 _nop_();
  246.                 SCK_P=0;
  247.                 _nop_();
  248.                
  249.                 dat=dat>>1;
  250.         }
  251.         
  252.         RST_P=0;                                       
  253. }


  254. /*********************************************************/
  255. // 向DS1302寫入時間數據
  256. /*********************************************************/
  257. void DS1302_Write_Time()
  258. {
  259.   uchar i;
  260.         uchar temp1;
  261.         uchar temp2;
  262.         
  263.         for(i=0;i<7;i++)                        // 十進制轉BCD碼
  264.         {
  265.                 temp1=(TimeBuff[i]/10)<<4;
  266.                 temp2=TimeBuff[i]%10;
  267.                 TimeBuff[i]=temp1+temp2;
  268.         }
  269.         
  270.         DS1302_Write_Byte(0x8E,0x00);                                                                // 關閉寫保護
  271.         DS1302_Write_Byte(0x80,0x80);                                                                // 暫停時鐘
  272.         DS1302_Write_Byte(0x8C,TimeBuff[0]);                                // 年
  273.         DS1302_Write_Byte(0x88,TimeBuff[1]);                                // 月
  274.         DS1302_Write_Byte(0x86,TimeBuff[2]);                                // 日
  275.         DS1302_Write_Byte(0x8A,TimeBuff[3]);                                // 星期
  276.         DS1302_Write_Byte(0x84,TimeBuff[4]);                                // 時
  277.         DS1302_Write_Byte(0x82,TimeBuff[5]);                                // 分
  278.         DS1302_Write_Byte(0x80,TimeBuff[6]);                                // 秒
  279.         DS1302_Write_Byte(0x80,TimeBuff[6]&0x7F);                // 運行時鐘
  280.         DS1302_Write_Byte(0x8E,0x80);                                                                // 打開寫保護  
  281. }



  282. /*********************************************************/
  283. // 從DS1302讀出時間數據
  284. /*********************************************************/
  285. void DS1302_Read_Time()  
  286. {
  287.         uchar i;

  288.         TimeBuff[0]=DS1302_Read_Byte(0x8D);                                                // 年
  289.         TimeBuff[1]=DS1302_Read_Byte(0x89);                                                // 月
  290.         TimeBuff[2]=DS1302_Read_Byte(0x87);                                                // 日
  291.         TimeBuff[3]=DS1302_Read_Byte(0x8B);                                                // 星期
  292.         TimeBuff[4]=DS1302_Read_Byte(0x85);                                                // 時
  293.         TimeBuff[5]=DS1302_Read_Byte(0x83);                                                // 分
  294.         TimeBuff[6]=(DS1302_Read_Byte(0x81))&0x7F;                // 秒

  295.         for(i=0;i<7;i++)                // BCD轉十進制
  296.         {           
  297.                 TimeBuff[i]=(TimeBuff[i]/16)*10+TimeBuff[i]%16;
  298.         }
  299. }


  300. /*********************************************************/
  301. // ADC0832的時鐘脈沖
  302. /*********************************************************/
  303. void WavePlus()
  304. {
  305.         _nop_();
  306.         ADC_CLK = 1;
  307.         _nop_();
  308.         ADC_CLK = 0;
  309. }


  310. /*********************************************************/
  311. // 獲取指定通道的A/D轉換結果
  312. /*********************************************************/
  313. uchar Get_ADC0832()
  314. {
  315.         uchar i;
  316.         uchar dat1=0;
  317.         uchar dat2=0;
  318.         
  319.         ADC_CLK = 0;                                // 電平初始化
  320.         ADC_DAT = 1;
  321.         _nop_();
  322.         ADC_CS = 0;
  323.         WavePlus();                                        // 起始信號
  324.         ADC_DAT = 1;
  325.         WavePlus();                                        // 通道選擇的第一位
  326.         ADC_DAT = 0;      
  327.         WavePlus();                                        // 通道選擇的第二位
  328.         ADC_DAT = 1;
  329.         
  330.         for(i=0;i<8;i++)                // 第一次讀取
  331.         {
  332.                 dat1<<=1;
  333.                 WavePlus();
  334.                 if(ADC_DAT)
  335.                         dat1=dat1|0x01;
  336.                 else
  337.                         dat1=dat1|0x00;
  338.         }
  339.         
  340.         for(i=0;i<8;i++)                // 第二次讀取
  341.         {
  342.                 dat2>>= 1;
  343.                 if(ADC_DAT)
  344.                         dat2=dat2|0x80;
  345.                 else
  346.                         dat2=dat2|0x00;
  347.                 WavePlus();
  348.         }
  349.         
  350.         _nop_();                                                // 結束此次傳輸
  351.         ADC_DAT = 1;
  352.         ADC_CLK = 1;
  353.         ADC_CS  = 1;   

  354.         if(dat1==dat2)                        // 返回采集結果
  355.                 return dat1;
  356.         else
  357.                 return 0;
  358. }


  359. /*********************************************************/
  360. // 按鍵掃描(設置當前時間)
  361. /*********************************************************/
  362. void KeyScanf1()
  363. {
  364.         if(KeySet_P==0)
  365.         {
  366.                 LcdGotoXY(0,13);                                // 顯示秒鐘的冒號
  367.                 LcdWriteData(':');
  368.                 LcdWriteCmd(0x0f);                        // 啟動光標閃爍
  369.                 LcdGotoXY(0,3);                                        // 定位光標到年份閃爍
  370.                 DelayMs(10);                                                // 延時等待,消除按鍵按下的抖動
  371.                 while(!KeySet_P);                                // 等待按鍵釋放
  372.                 DelayMs(10);                                                // 延時等待,消除按鍵松開的抖動
  373.                
  374.                 /* 調整年份 */
  375.                 while(1)
  376.                 {
  377.                         if(KeyDown_P==0)                                                        // 如果減按鍵被下去
  378.                         {
  379.                                 if(TimeBuff[0]>0)                                                // 判斷年份是否大于0               
  380.                                         TimeBuff[0]--;                                                // 是的話就減去1
  381.                                 LcdGotoXY(0,2);                                                        // 光標定位到年份的位置
  382.                                 LcdPrintNum(TimeBuff[0]);                // 刷新顯示改變后的年份
  383.                                 LcdGotoXY(0,3);                                                        // 定位光標到年份閃爍
  384.                                 DelayMs(300);                                                                // 延時0.3秒左右
  385.                         }
  386.                         
  387.                         if(KeyUp_P==0)                                                                // 如果加按鍵被下去
  388.                         {
  389.                                 if(TimeBuff[0]<99)                                        // 判斷年份是否小于99
  390.                                         TimeBuff[0]++;                                                // 是的話就加上1
  391.                                 LcdGotoXY(0,2);                                                        // 光標定位到年份的位置
  392.                                 LcdPrintNum(TimeBuff[0]);                // 刷新顯示改變后的年份
  393.                                 LcdGotoXY(0,3);                                                        // 定位光標到年份閃爍
  394.                                 DelayMs(300);                                                                // 延時0.3秒左右
  395.                         }
  396.                         
  397.                         if(KeySet_P==0)
  398.                         {
  399.                                 break;
  400.                         }
  401.                 }
  402.                
  403.                 LcdGotoXY(0,6);                                        // 定位光標到月份閃爍
  404.                 DelayMs(10);                                                // 延時等待,消除按鍵按下的抖動
  405.                 while(!KeySet_P);                                // 等待按鍵釋放
  406.                 DelayMs(10);                                                // 延時等待,消除按鍵松開的抖動
  407.                         
  408.                 /* 調整月份 */
  409.                 while(1)
  410.                 {
  411.                         if(KeyDown_P==0)                                                        // 如果減按鍵被下去
  412.                         {
  413.                                 if(TimeBuff[1]>1)                                                // 判斷月份是否大于1               
  414.                                         TimeBuff[1]--;                                                // 是的話就減去1
  415.                                 LcdGotoXY(0,5);                                                        // 光標定位到月份的位置
  416.                                 LcdPrintNum(TimeBuff[1]);                // 刷新顯示改變后的月份
  417.                                 LcdGotoXY(0,6);                                                        // 定位光標到月份閃爍
  418.                                 DelayMs(300);                                                                // 延時0.3秒左右
  419.                         }
  420.                         
  421.                         if(KeyUp_P==0)                                                                // 如果加按鍵被下去
  422.                         {
  423.                                 if(TimeBuff[1]<12)                                        // 判斷月份是否小于12
  424.                                         TimeBuff[1]++;                                                // 是的話就加上1
  425.                                 LcdGotoXY(0,5);                                                        // 光標定位到月份的位置
  426.                                 LcdPrintNum(TimeBuff[1]);                // 刷新顯示改變后的月份
  427.                                 LcdGotoXY(0,6);                                                        // 定位光標到月份閃爍
  428.                                 DelayMs(300);                                                                // 延時0.3秒左右
  429.                         }
  430.                         
  431.                         if(KeySet_P==0)
  432.                         {
  433.                                 break;
  434.                         }
  435.                 }
  436.                
  437.                 LcdGotoXY(0,9);                                        // 定位光標到日期閃爍
  438.                 DelayMs(10);                                                // 延時等待,消除按鍵按下的抖動
  439.                 while(!KeySet_P);                                // 等待按鍵釋放
  440.                 DelayMs(10);                                                // 延時等待,消除按鍵松開的抖動
  441.                
  442.                 /* 調整日期 */
  443.                 while(1)
  444.                 {
  445.                         if(KeyDown_P==0)                                                        // 如果減按鍵被下去
  446.                         {
  447.                                 if(TimeBuff[2]>1)                                                // 判斷日期是否大于1               
  448.                                         TimeBuff[2]--;                                                // 是的話就減去1
  449.                                 LcdGotoXY(0,8);                                                        // 光標定位到日期的位置
  450.                                 LcdPrintNum(TimeBuff[2]);                // 刷新顯示改變后的日期
  451.                                 LcdGotoXY(0,9);                                                        // 定位光標到日期閃爍
  452.                                 DelayMs(300);                                                                // 延時0.3秒左右
  453.                         }
  454.                         
  455.                         if(KeyUp_P==0)                                                                // 如果加按鍵被下去
  456.                         {
  457.                                 if(TimeBuff[2]<31)                                        // 判斷日期是否小于31
  458.                                         TimeBuff[2]++;                                                // 是的話就加上1
  459.                                 LcdGotoXY(0,8);                                                        // 光標定位到日期的位置
  460.                                 LcdPrintNum(TimeBuff[2]);                // 刷新顯示改變后的日期
  461.                                 LcdGotoXY(0,9);                                                        // 定位光標到日期閃爍
  462.                                 DelayMs(300);                                                                // 延時0.3秒左右
  463.                         }
  464.                         
  465.                         if(KeySet_P==0)
  466.                         {
  467.                                 break;
  468.                         }
  469.                 }
  470.                
  471.                 LcdGotoXY(0,12);                                // 定位光標到小時閃爍
  472.                 DelayMs(10);                                                // 延時等待,消除按鍵按下的抖動
  473.                 while(!KeySet_P);                                // 等待按鍵釋放
  474.                 DelayMs(10);                                                // 延時等待,消除按鍵松開的抖動
  475.                
  476.                
  477.                 /* 調整小時 */
  478.                 while(1)
  479.                 {
  480.                         if(KeyDown_P==0)                                                        // 如果減按鍵被下去
  481.                         {
  482.                                 if(TimeBuff[4]>0)                                                // 判斷小時是否大于0
  483.                                         TimeBuff[4]--;                                                // 是的話就減去1
  484.                                 LcdGotoXY(0,11);                                                // 光標定位到小時的位置
  485.                                 LcdPrintNum(TimeBuff[4]);                // 刷新顯示改變后的小時
  486.                                 LcdGotoXY(0,12);                                                // 定位光標到小時閃爍
  487.                                 DelayMs(300);                                                                // 延時0.3秒左右
  488.                         }
  489.                         
  490.                         if(KeyUp_P==0)                                                                // 如果加按鍵被下去
  491.                         {
  492.                                 if(TimeBuff[4]<23)                                        // 判斷小時是否小于23
  493.                                         TimeBuff[4]++;                                                // 是的話就加上1
  494.                                 LcdGotoXY(0,11);                                                // 光標定位到小時的位置
  495.                                 LcdPrintNum(TimeBuff[4]);                // 刷新顯示改變后的小時
  496.                                 LcdGotoXY(0,12);                                                // 定位光標到小時閃爍
  497.                                 DelayMs(300);                                                                // 延時0.3秒左右
  498.                         }
  499.                         
  500.                         if(KeySet_P==0)
  501.                         {
  502.                                 break;
  503.                         }
  504.                 }
  505.                
  506.                 LcdGotoXY(0,15);                                // 定位光標到分鐘閃爍
  507.                 DelayMs(10);                                                // 延時等待,消除按鍵按下的抖動
  508.                 while(!KeySet_P);                                // 等待按鍵釋放
  509.                 DelayMs(10);                                                // 延時等待,消除按鍵松開的抖動
  510.                
  511.                 /* 調整分鐘 */
  512.                 while(1)
  513.                 {
  514.                         if(KeyDown_P==0)                                                        // 如果減按鍵被下去
  515.                         {
  516.                                 if(TimeBuff[5]>0)                                                // 判斷分鐘是否大于0
  517.                                         TimeBuff[5]--;                                                // 是的話就減去1
  518.                                 LcdGotoXY(0,14);                                                // 光標定位到分鐘的位置
  519.                                 LcdPrintNum(TimeBuff[5]);                // 刷新顯示改變后的分鐘
  520.                                 LcdGotoXY(0,15);                                                // 定位光標到分鐘閃爍
  521.                                 DelayMs(300);                                                                // 延時0.3秒左右
  522.                         }
  523.                         
  524.                         if(KeyUp_P==0)                                                                // 如果加按鍵被下去
  525.                         {
  526.                                 if(TimeBuff[5]<59)                                        // 判斷分鐘是否小于59
  527.                                         TimeBuff[5]++;                                                // 是的話就加上1
  528.                                 LcdGotoXY(0,14);                                                // 光標定位到分鐘的位置
  529.                                 LcdPrintNum(TimeBuff[5]);                // 刷新顯示改變后的分鐘
  530.                                 LcdGotoXY(0,15);                                                // 定位光標到分鐘閃爍
  531.                                 DelayMs(300);                                                                // 延時0.3秒左右
  532.                         }
  533.                         
  534.                         if(KeySet_P==0)
  535.                         {
  536.                                 break;
  537.                         }
  538.                 }
  539.                
  540.                 /* 退出前的設置 */
  541.                 LcdWriteCmd(0x0C);                        // 關閉光標閃爍
  542.                 DS1302_Write_Time();                // 把新設置的時間值存入DS1302芯片
  543.                 DelayMs(10);                                                // 延時等待,消除按鍵按下的抖動
  544.                 while(!KeySet_P);                                // 等待按鍵釋放
  545.                 DelayMs(10);                                                // 延時等待,消除按鍵松開的抖動
  546.         }
  547. }


  548. /*********************************************************/
  549. // 按鍵掃描(設置窗簾的動作)
  550. /*********************************************************/
  551. void KeyScanf2()
  552. {
  553.         if(KeySet2_P==0)
  554.         {
  555.                 LcdGotoXY(0,0);                                                                                // 光標定位
  556.                 LcdPrintStr(" OpenTime   :   ");        // 顯示第1行內容
  557.                 LcdGotoXY(1,0);                                                                                // 光標定位
  558.                 LcdPrintStr("CloseTime   :   ");        // 顯示第2行內容
  559.                 LcdGotoXY(0,10);                                                                        // 光標定位
  560.                 LcdPrintNum(OpenHour);                                                // 顯示開啟窗簾的小時
  561.                 LcdGotoXY(0,13);                                                                        // 光標定位
  562.                 LcdPrintNum(OpenMinute);                                        // 顯示開啟窗簾的分鐘
  563.                 LcdGotoXY(1,10);                                                                        // 光標定位
  564.                 LcdPrintNum(CloseHour);                                                // 顯示關閉窗簾的小時
  565.                 LcdGotoXY(1,13);                                                                        // 光標定位
  566.                 LcdPrintNum(CloseMinute);                                        // 顯示關閉窗簾的分鐘               
  567.                
  568.                 LcdWriteCmd(0x0f);                                                        // 啟動光標閃爍
  569.                 LcdGotoXY(0,11);                                                                // 定位光標
  570.                 DelayMs(10);                                                                                // 延時等待,消除按鍵按下的抖動
  571.                 while(!KeySet2_P);                                                        // 等待按鍵釋放
  572.                 DelayMs(10);                                                                                // 延時等待,消除按鍵松開的抖動
  573.                
  574.                 /* 調整開啟的小時 */
  575.                 while(1)
  576.                 {
  577.                         if(KeyDown_P==0)                                                        // 如果減按鍵被下去
  578.                         {
  579.                                 if(OpenHour>0)                                                        // 判斷小時是否大于0               
  580.                                         OpenHour--;                                                                // 是的話就減去1
  581.                                 LcdGotoXY(0,10);                                                // 光標定位
  582.                                 LcdPrintNum(OpenHour);                        // 刷新顯示改變后的小時
  583.                                 LcdGotoXY(0,11);                                                // 定位光標
  584.                                 DelayMs(300);                                                                // 延時0.3秒左右
  585.                         }
  586.                         
  587.                         if(KeyUp_P==0)                                                                // 如果加按鍵被下去
  588.                         {
  589.                                 if(OpenHour<23)                                                        // 判斷小時是否小于23
  590.                                         OpenHour++;                                                                // 是的話就加上1
  591.                                 LcdGotoXY(0,10);                                                // 光標定位
  592.                                 LcdPrintNum(OpenHour);                        // 刷新顯示改變后的小時
  593.                                 LcdGotoXY(0,11);                                                // 定位光標
  594.                                 DelayMs(300);                                                                // 延時0.3秒左右
  595.                         }
  596.                         
  597.                         if(KeySet2_P==0)
  598.                         {
  599.                                 break;
  600.                         }
  601.                 }
  602.                
  603.                 LcdGotoXY(0,14);                                                                // 定位光標
  604.                 DelayMs(10);                                                                                // 延時等待,消除按鍵按下的抖動
  605.                 while(!KeySet2_P);                                                        // 等待按鍵釋放
  606.                 DelayMs(10);                                                                                // 延時等待,消除按鍵松開的抖動
  607.                
  608.                 /* 調整開啟的分鐘 */
  609.                 while(1)
  610.                 {
  611.                         if(KeyDown_P==0)                                                        // 如果減按鍵被下去
  612.                         {
  613.                                 if(OpenMinute>0)                                                // 判斷分鐘是否大于0
  614.                                         OpenMinute--;                                                        // 是的話就減去1
  615.                                 LcdGotoXY(0,13);                                                // 光標定位
  616.                                 LcdPrintNum(OpenMinute);                // 刷新顯示改變后的分鐘
  617.                                 LcdGotoXY(0,14);                                                // 定位光標
  618.                                 DelayMs(300);                                                                // 延時0.3秒左右
  619.                         }
  620.                         
  621.                         if(KeyUp_P==0)                                                                // 如果加按鍵被下去
  622.                         {
  623.                                 if(OpenMinute<59)                                                // 判斷分鐘是否小于59
  624.                                         OpenMinute++;                                                        // 是的話就加上1
  625.                                 LcdGotoXY(0,13);                                                // 光標定位
  626.                                 LcdPrintNum(OpenMinute);                // 刷新顯示改變后的分鐘
  627.                                 LcdGotoXY(0,14);                                                // 定位光標
  628.                                 DelayMs(300);                                                                // 延時0.3秒左右
  629.                         }
  630.                         
  631.                         if(KeySet2_P==0)
  632.                         {
  633.                                 break;
  634.                         }
  635.                 }
  636.                
  637.                 LcdGotoXY(1,11);                                                                // 定位光標
  638.                 DelayMs(10);                                                                                // 延時等待,消除按鍵按下的抖動
  639.                 while(!KeySet2_P);                                                        // 等待按鍵釋放
  640.                 DelayMs(10);                                                                                // 延時等待,消除按鍵松開的抖動
  641.                
  642.                 /* 調整關閉的小時 */
  643.                 while(1)
  644.                 {
  645.                         if(KeyDown_P==0)                                                        // 如果減按鍵被下去
  646.                         {
  647.                                 if(CloseHour>0)                                                        // 判斷小時是否大于0               
  648.                                         CloseHour--;                                                        // 是的話就減去1
  649.                                 LcdGotoXY(1,10);                                                // 光標定位
  650.                                 LcdPrintNum(CloseHour);                        // 刷新顯示改變后的小時
  651.                                 LcdGotoXY(1,11);                                                // 定位光標
  652.                                 DelayMs(300);                                                                // 延時0.3秒左右
  653.                         }
  654.                         
  655.                         if(KeyUp_P==0)                                                                // 如果加按鍵被下去
  656.                         {
  657.                                 if(CloseHour<23)                                                // 判斷小時是否小于23
  658.                                         CloseHour++;                                                        // 是的話就加上1
  659.                                 LcdGotoXY(1,10);                                                // 光標定位
  660.                                 LcdPrintNum(CloseHour);                        // 刷新顯示改變后的小時
  661.                                 LcdGotoXY(1,11);                                                // 定位光標
  662.                                 DelayMs(300);                                                                // 延時0.3秒左右
  663.                         }
  664.                         
  665.                         if(KeySet2_P==0)
  666.                         {
  667.                                 break;
  668.                         }
  669.                 }
  670.                
  671.                 LcdGotoXY(1,14);                                                                // 定位光標
  672.                 DelayMs(10);                                                                                // 延時等待,消除按鍵按下的抖動
  673.                 while(!KeySet2_P);                                                        // 等待按鍵釋放
  674.                 DelayMs(10);                                                                                // 延時等待,消除按鍵松開的抖動
  675.                
  676.                 /* 調整關閉的分鐘 */
  677.                 while(1)
  678.                 {
  679.                         if(KeyDown_P==0)                                                        // 如果減按鍵被下去
  680.                         {
  681.                                 if(CloseMinute>0)                                                // 判斷分鐘是否大于0
  682.                                         CloseMinute--;                                                // 是的話就減去1
  683.                                 LcdGotoXY(1,13);                                                // 光標定位
  684.                                 LcdPrintNum(CloseMinute);                // 刷新顯示改變后的分鐘
  685.                                 LcdGotoXY(1,14);                                                // 定位光標
  686.                                 DelayMs(300);                                                                // 延時0.3秒左右
  687.                         }
  688.                         
  689.                         if(KeyUp_P==0)                                                                // 如果加按鍵被下去
  690.                         {
  691.                                 if(CloseMinute<59)                                        // 判斷分鐘是否小于59
  692.                                         CloseMinute++;                                                // 是的話就加上1
  693.                                 LcdGotoXY(1,13);                                                // 光標定位
  694.                                 LcdPrintNum(CloseMinute);                // 刷新顯示改變后的分鐘
  695.                                 LcdGotoXY(1,14);                                                // 定位光標
  696.                                 DelayMs(300);                                                                // 延時0.3秒左右
  697.                         }
  698.                         
  699.                         if(KeySet2_P==0)
  700.                         {
  701.                                 break;
  702.                         }
  703.                 }
  704.                
  705.                 DelayMs(10);                                                                                // 延時等待,消除按鍵按下的抖動
  706.                 while(!KeySet2_P);                                                        // 等待按鍵釋放
  707.                 DelayMs(10);                                                                                // 延時等待,消除按鍵松開的抖動
  708.                
  709.                 /* 光照強度的設置 */
  710.                 LcdWriteCmd(0x0C);                                                                // 關閉光標閃爍
  711.                 LcdGotoXY(0,0);                                                                                // 光標定位
  712.                 LcdPrintStr("   Light Set    ");        // 顯示第1行內容
  713.                 LcdGotoXY(1,0);                                                                                // 光標定位
  714.                 LcdPrintStr("                ");        // 顯示第2行內容
  715.                 LcdGotoXY(1,7);                                                                                // 光標定位
  716.                 LcdPrintNum(gLight);                                                        // 顯示窗簾的光線控制強度閾值
  717.                
  718.                 while(1)
  719.                 {
  720.                         if(KeyDown_P==0)                                                        // 如果減按鍵被下去
  721.                         {
  722.                                 if(gLight>0)                                                                // 判斷光線閾值是否大于0
  723.                                         gLight--;                                                                        // 是的話就減去1
  724.                                 LcdGotoXY(1,7);                                                        // 光標定位
  725.                                 LcdPrintNum(gLight);                                // 刷新顯示改變后的光線閾值
  726.                                 DelayMs(300);                                                                // 延時0.3秒左右
  727.                         }
  728.                         
  729.                         if(KeyUp_P==0)                                                                // 如果加按鍵被下去
  730.                         {
  731.                                 if(gLight<99)                                                                // 判斷光線閾值是否小于59
  732.                                         gLight++;                                                                        // 是的話就加上1
  733.                                 LcdGotoXY(1,7);                                                        // 光標定位
  734.                                 LcdPrintNum(gLight);                                // 刷新顯示改變后的光線閾值
  735.                                 DelayMs(300);                                                                // 延時0.3秒左右
  736.                         }
  737.                         
  738.                         if(KeySet2_P==0)
  739.                         {
  740.                                 break;
  741.                         }
  742.                 }
  743.                
  744.                 /* 退出前的設置 */
  745.                 LcdShowInit();                                        // 液晶顯示內容初始化
  746.                 DelayMs(10);                                                // 延時等待,消除按鍵按下的抖動
  747.                 while(!KeySet2_P);                        // 等待按鍵釋放
  748.                 DelayMs(10);                                                // 延時等待,消除按鍵松開的抖動
  749.         }
  750. }


  751. /*********************************************************/
  752. // 按鍵掃描(模式切換)
  753. /*********************************************************/
  754. void KeyScanf3()
  755. {
  756.         if(KeyMode_P==0)
  757.         {
  758.                 gMode++;                                                        // 切換到下一模式
  759.                 if(gMode==4)                                        // 如果到盡頭了
  760.                         gMode=1;                                                // 回到第一種模式
  761.                 LcdGotoXY(1,0);                                // 光標定位
  762.                 LcdPrintMode(gMode);        // 顯示模式
  763.                 DelayMs(10);                                        // 去除按鍵按下的抖動
  764.                 while(!KeyMode_P);                // 等待按鍵是否
  765.                 DelayMs(10);                                        // 去除按鍵松開的抖動
  766.         }
  767. }


  768. /*********************************************************/
  769. // 開窗
  770. /*********************************************************/
  771. void Open()
  772. {
  773.         uint i,j;
  774.         for(j=0;j<255;j++)                // 控制步進電機正轉
  775.         {
  776.                 for(i=0;i<4;i++)
  777.                 {
  778.                         P2=Clock[i];
  779.                         DelayMs(3);
  780.                 }
  781.         }
  782.         Led_P=0;
  783. }



  784. /*********************************************************/
  785. // 關窗
  786. /*********************************************************/
  787. void Close()
  788. {
  789.         uint i,j;
  790.         for(j=0;j<255;j++)                // 控制步進電機反轉
  791.         {
  792.                 for(i=0;i<4;i++)
  793.                 {
  794.                         P2=AntiClock[i];
  795.                         DelayMs(3);
  796.                 }
  797.         }
  798.         Led_P=1;
  799. }



  800. /*********************************************************/
  801. // 主函數
  802. /*********************************************************/
  803. void main()
  804. {
  805.         uchar light;
  806.         
  807.         LcdInit();                        // 執行液晶初始化        
  808.         DS1302_Init();        // 時鐘芯片的初始化
  809.         LcdShowInit();        // 液晶顯示內容的初始化
  810.         
  811.         if(DS1302_Read_Byte(0x81)>=128)                        // 判斷時鐘芯片是否正在運行
  812.         {
  813.                 DS1302_Write_Time();                                                        // 如果沒有,則初始化一個時間
  814.         }
  815.         
  816.         while(1)
  817.         {
  818.                 DS1302_Read_Time();                                // 獲取當前時鐘芯片的時間,存在數組time_buf中
  819.                 FlashTime();                                                        // 刷新時間顯示

  820.                 light=Get_ADC0832();                        // 讀取光照強度
  821.                 light=light/2.5;                                        // 縮小光照檢測結果(在0-99)
  822.                 if(light>99)                                                        // 如果大于99
  823.                         light=99;                                                                // 則依然保持99
  824.                 LcdGotoXY(1,14);                                        // 光標定位
  825.                 LcdPrintNum(light);                                // 顯示光照強度
  826.                
  827.                 KeyScanf1();                                                        // 按鍵掃描(時間的設置)
  828.                 KeyScanf2();                                                        // 按鍵掃描(閾值的設置)
  829.                 KeyScanf3();                                                        // 按鍵掃描(模式切換)
  830.         
  831.                 /*手動控制模式*/
  832.                 if(gMode==1)
  833.                 {
  834.                         if(KeyDown_P==0)                // 如果關窗簾鍵按下了        
  835.                         {
  836.                                 if(Led_P==0)                        // 如果窗簾當前是打開的
  837.                                 {
  838.                                         Close();                                // 則關閉窗簾
  839.                                 }
  840.                         }
  841.                         if(KeyUp_P==0)                        // 如果開窗簾鍵按下了
  842.                         {
  843.                                 if(Led_P==1)                        // 如果窗簾當前是關閉的
  844.                                 {
  845.                                         Open();                                        // 則打開窗簾
  846.                                 }
  847.                         }        
  848.                 }
  849.                
  850.                 /*時間控制模式*/
  851.                 if(gMode==2)
  852.                 {
  853.                         if((TimeBuff[4]==CloseHour)&&(TimeBuff[5]==CloseMinute)&&(TimeBuff[6]==0))        // 如果到了關窗簾的時間        
  854.                         {
  855.                                 if(Led_P==0)                        // 如果窗簾當前是打開的
  856.                                 {
  857.                                         Close();                                // 則關閉窗簾
  858.                                 }
  859.                         }
  860.                         if((TimeBuff[4]==OpenHour)&&(TimeBuff[5]==OpenMinute)&&(TimeBuff[6]==0))                // 如果到了開窗簾的時間        
  861.                         {
  862.                                 if(Led_P==1)                        // 如果窗簾當前是關閉的
  863.                                 {
  864.                                         Open();                                        // 則打開窗簾
  865.                                 }
  866.                         }        
  867.                 }
  868.                
  869.                 /*光線控制模式*/
  870.                 if(gMode==3)
  871.                 {
  872.                         if(light<gLight)                // 當前光線小于設置的閾值
  873.                         {
  874.                                 if(Led_P==0)                        // 如果窗簾當前是打開的
  875.                                 {
  876.                                         Close();                                // 則關閉窗簾
  877.                                 }
  878.                         }
  879.                         else                                                                // 當前光線大于或等于設置的閾值
  880.                         {
  881.                                 if(Led_P==1)                        // 如果窗簾當前是關閉的
  882.                                 {
復制代碼

仿真和程序51hei附件下載:
基于51單片機的智能窗設計.7z (2.3 MB, 下載次數: 99)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 中文字幕第一页在线 | 亚洲毛片一区二区 | 免费av观看 | 亚洲一区二区电影在线观看 | 成人精品一区二区 | 国产精品久久国产精品 | 亚洲精品免费看 | 91中文字幕在线观看 | a在线视频观看 | 91久久精品国产 | 日韩中文一区二区三区 | av在线一区二区三区 | 天天操妹子 | 亚洲成人免费视频在线观看 | 国产高清视频一区 | 免费黄色录像视频 | 国产欧美精品在线 | 久久免费观看一级毛片 | 成人精品一区二区 | 欧美亚洲综合久久 | 精品久久精品 | 午夜精品一区二区三区免费视频 | 亚洲一区中文字幕在线观看 | 日韩三级在线观看 | 精品欧美一区二区在线观看视频 | 在线中文字幕av | 欧美一级高清片 | 99re在线视频 | 极品国产视频 | 黄网站涩免费蜜桃网站 | 精品久久久久久久久久 | 亚洲最大成人综合 | 国产精品一二三区 | 欧美精品综合 | 国产视频福利 | 亚洲视频在线免费观看 | 国产精品久久久久久影视 | 羞羞视频在线观看免费观看 | 国产精品呻吟久久av凹凸 | 欧美视频一区 | 久久久片|