找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 705|回复: 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, 下载次数: 61)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表