找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3062|回复: 0
打印 上一主题 下一主题
收起左侧

51单片机自动窗帘电机控制程序与Proteus仿真图

[复制链接]
跳转到指定楼层
楼主
单片机控制电机转速运用PWM
仿真原理图如下(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,0x90,0x80,0xc0};             // 步进电机顺时针旋转数组
  27. uchar code AntiClock[]={0x80,0x90,0x10,0x30};        // 步进电机逆时针旋转数组


  28. uchar code Clock1[]={0x10,0x90,0x80,0xc0};


  29. uchar TimeBuff[7]={17,9,1,6,18,30,40};                    // 时间数组,默认2017年9月1日,星期五,18:30:40
  30. // TimeBuff[0] 代表年份,范围00-99
  31. // TimeBuff[1] 代表月份,范围1-12
  32. // TimeBuff[2] 代表日期,范围1-31
  33. // TimeBuff[3] 代表星期,范围1-7
  34. // TimeBuff[4] 代表小时,范围00-23
  35. // TimeBuff[5] 代表分钟,范围00-59
  36. // TimeBuff[6] 代表秒钟,范围00-59



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


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


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


  74. /*********************************************************/
  75. // 1602液晶初始化函数
  76. /*********************************************************/
  77. void LcdInit()
  78. {
  79.     LcdWriteCmd(0x38);        // 16*2显示,5*7点阵,8位数据口
  80.     LcdWriteCmd(0x0C);        // 开显示,不显示光标
  81.     LcdWriteCmd(0x06);        // 地址加1,当写入数据后光标右移
  82.     LcdWriteCmd(0x01);        // 清屏
  83. }


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


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


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


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


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


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


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


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


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

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


  255. /*********************************************************/
  256. // 向DS1302写入时间数据
  257. /*********************************************************/
  258. void DS1302_Write_Time()
  259. {
  260.   uchar i;
  261.     uchar temp1;
  262.     uchar temp2;
  263.    
  264.     for(i=0;i<7;i++)            // 十进制转BCD码
  265.     {
  266.         temp1=(TimeBuff[i]/10)<<4;
  267.         temp2=TimeBuff[i]%10;
  268.         TimeBuff[i]=temp1+temp2;
  269.     }
  270.    
  271.     DS1302_Write_Byte(0x8E,0x00);                                // 关闭写保护
  272.     DS1302_Write_Byte(0x80,0x80);                                // 暂停时钟
  273.     DS1302_Write_Byte(0x8C,TimeBuff[0]);                // 年
  274.     DS1302_Write_Byte(0x88,TimeBuff[1]);                // 月
  275.     DS1302_Write_Byte(0x86,TimeBuff[2]);                // 日
  276.     DS1302_Write_Byte(0x8A,TimeBuff[3]);                // 星期
  277.     DS1302_Write_Byte(0x84,TimeBuff[4]);                // 时
  278.     DS1302_Write_Byte(0x82,TimeBuff[5]);                // 分
  279.     DS1302_Write_Byte(0x80,TimeBuff[6]);                // 秒
  280.     DS1302_Write_Byte(0x80,TimeBuff[6]&0x7F);        // 运行时钟
  281.     DS1302_Write_Byte(0x8E,0x80);                                // 打开写保护  
  282. }



  283. /*********************************************************/
  284. // 从DS1302读出时间数据
  285. /*********************************************************/
  286. void DS1302_Read_Time()  
  287. {
  288.     uchar i;

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

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


  301. /*********************************************************/
  302. // ADC0832的时钟脉冲
  303. /*********************************************************/
  304. void WavePlus()
  305. {
  306.     _nop_();
  307.     ADC_CLK = 1;
  308.     _nop_();
  309.     ADC_CLK = 0;
  310. }


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

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


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


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


  752. /*********************************************************/
  753. // 按键扫描(模式切换)
  754. /*********************************************************/
  755. void KeyScanf3()
  756. {
  757.     if(KeyMode_P==0)
  758.     {
  759.         gMode++;                            // 切换到下一模式
  760.         if(gMode==4)                    // 如果到尽头了
  761.             gMode=1;                        // 回到第一种模式
  762.         LcdGotoXY(1,0);                // 光标定位
  763.         LcdPrintMode(gMode);    // 显示模式
  764.         DelayMs(10);                    // 去除按键按下的抖动
  765.         while(!KeyMode_P);        // 等待按键是否
  766.         DelayMs(10);                    // 去除按键松开的抖动
  767.     }
  768. }


  769. /*********************************************************/
  770. // 开窗
  771. /*********************************************************/
  772. void Open()
  773. {
  774.     uint i;
  775.     for(i=0;i<4;i++)
  776.     {
  777.         P2=Clock[i];
  778.         DelayMs(250);
  779.     }
  780.     Led_P=0;
  781. }



  782. /*********************************************************/
  783. // 关窗
  784. /*********************************************************/
  785. void Close()
  786. {
  787.     uint i;
  788.     for(i=0;i<4;i++)
  789.     {
  790.         P2=AntiClock[i];
  791.         DelayMs(250);
  792.     }
  793.     Led_P=1;
  794. }



  795. /*********************************************************/
  796. // 主函数
  797. /*********************************************************/
  798. void main()
  799. {
  800.     uchar light;
  801.    
  802.     LcdInit();            // 执行液晶初始化   
  803.     DS1302_Init();    // 时钟芯片的初始化
  804.     LcdShowInit();    // 液晶显示内容的初始化
  805.    
  806.     if(DS1302_Read_Byte(0x81)>=128)            // 判断时钟芯片是否正在运行
  807.     {
  808.         DS1302_Write_Time();                            // 如果没有,则初始化一个时间
  809.     }
  810.    
  811.     while(1)
  812.     {
  813.         DS1302_Read_Time();                // 获取当前时钟芯片的时间,存在数组time_buf中
  814.         FlashTime();                            // 刷新时间显示

  815.         light=Get_ADC0832();            // 读取光照强度
  816.         light=light/2.5;                    // 缩小光照检测结果(在0-99)
  817.         if(light>99)                            // 如果大于99
  818.             light=99;                                // 则依然保持99
  819.         LcdGotoXY(1,14);                    // 光标定位
  820.         LcdPrintNum(light);                // 显示光照强度
  821.         
  822.         KeyScanf1();                            // 按键扫描(时间的设置)
  823.         KeyScanf2();                            // 按键扫描(阈值的设置)
  824.         KeyScanf3();                            // 按键扫描(模式切换)
  825.    
  826.         /*手动控制模式*/
  827.         if(gMode==1)
  828.         {
  829.             if(KeyDown_P==0)        // 如果关窗帘键按下了   
  830.             {
  831.                 if(Led_P==0)            // 如果窗帘当前是打开的
  832.                 {
  833.                     Close();                // 则关闭窗帘
  834.                 }
  835.             }
  836.             if(KeyUp_P==0)            // 如果开窗帘键按下了
  837.             {
  838.                 if(Led_P==1)            // 如果窗帘当前是关闭的
  839.                 {
  840.                     Open();                    // 则打开窗帘
  841.                 }
  842.             }   
  843.         }
  844.         
  845.         /*时间控制模式*/
  846.         if(gMode==2)
  847.         {
  848.             if((TimeBuff[4]==CloseHour)&&(TimeBuff[5]==CloseMinute)&&(TimeBuff[6]==0))    // 如果到了关窗帘的时间   
  849.             {
  850.                 if(Led_P==0)            // 如果窗帘当前是打开的
  851.                 {
  852.                     Close();                // 则关闭窗帘
  853.                 }
  854.             }
  855.             if((TimeBuff[4]==OpenHour)&&(TimeBuff[5]==OpenMinute)&&(TimeBuff[6]==0))        // 如果到了开窗帘的时间   
  856.             {
  857.                 if(Led_P==1)            // 如果窗帘当前是关闭的
  858.                 {
  859.                     Open();                    // 则打开窗帘
  860.                 }
  861.             }   
  862.         }
  863.         
  864.         /*光线控制模式*/
  865.         if(gMode==3)
  866.         {
  867.             if(light<gLight)        // 当前光线小于设置的阈值
  868.             {
  869.                 if(Led_P==0)            // 如果窗帘当前是打开的
  870.                 {
  871.                     Close();                // 则关闭窗帘
  872.                 }
  873.             }
  874.             else                                // 当前光线大于或等于设置的阈值
  875.             {
  876.                 if(Led_P==1)            // 如果窗帘当前是关闭的
  877.                 {
  878.                     Open();                    // 则打开窗帘
复制代码

所有资料51hei提供下载:
28__proteus仿真 (1).zip (131.83 KB, 下载次数: 74)

评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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