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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

基于51單片機的智能窗簾有三個模式 程序及Proteus仿真圖

[復制鏈接]
跳轉到指定樓層
樓主
第一個模式為手動控制加語音控制
第二個模式可以設置定時
第三個模式設置光照閾值來自動控制窗簾

仿真原理圖如下(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. sbit YYOPEN                        =        P3^0;



  21. uchar gMode=1;                                                                // 1是手動模式,2是時間自動模式,3是亮度自動模式
  22. uchar OpenHour    = 18;                                // 開啟窗簾的小時
  23. uchar OpenMinute  = 20;                                // 開啟窗簾的分鐘
  24. uchar CloseHour   = 10;                                // 關閉窗簾的小時
  25. uchar CloseMinute = 30;                                // 關閉窗簾的分鐘
  26. uchar gLight      = 40;                                // 窗簾開關的閾值
  27. uchar gLightmax=80;
  28. uchar code Clock[]={0x80,0x40,0x20,0x10};                         // 步進電機順時針旋轉數組
  29. uchar code AntiClock[]={0x10,0x20,0x40,0x80};                // 步進電機逆時針旋轉數組

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



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


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


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


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


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


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


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


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


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



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


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


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


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

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


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



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

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

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


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


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

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


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


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


  794. /*********************************************************/
  795. // 按鍵掃描(模式切換)
  796. /*********************************************************/
  797. void KeyScanf3()
  798. {
  799.         if(KeyMode_P==0)
  800.         {
  801.                 gMode++;                                                        // 切換到下一模式
  802.                 if(gMode==4)                                        // 如果到盡頭了
  803.                         gMode=1;                                                // 回到第一種模式
  804.                 LcdGotoXY(1,0);                                // 光標定位
  805.                 LcdPrintMode(gMode);        // 顯示模式
  806.                 DelayMs(10);                                        // 去除按鍵按下的抖動
  807.                 while(!KeyMode_P);                // 等待按鍵是否
  808.                 DelayMs(10);                                        // 去除按鍵松開的抖動
  809.         }
  810. }


  811. /*********************************************************/
  812. // 開窗
  813. /*********************************************************/
  814. void Open()
  815. {
  816.         uint i,j;
  817.         for(j=0;j<255;j++)                // 控制步進電機正轉
  818.         {
  819.                 for(i=0;i<4;i++)
  820.                 {
  821.                         P2=Clock[i];
  822.                         DelayMs(3);
  823.                 }
  824.         }
  825.         Led_P=0;
  826. }



  827. /*********************************************************/
  828. // 關窗
  829. /*********************************************************/
  830. void Close()
  831. {
  832.         uint i,j;
  833.         for(j=0;j<255;j++)                // 控制步進電機反轉
  834.         {
  835.                 for(i=0;i<4;i++)
  836.                 {
  837.                         P2=AntiClock[i];
  838.                         DelayMs(3);
  839.                 }
  840.         }
  841.         Led_P=1;
  842. }



  843. /*********************************************************/
  844. // 主函數
  845. /*********************************************************/
  846. void main()
  847. {
  848.         uchar light;
  849.         
  850.         LcdInit();                        // 執行液晶初始化        
  851.         DS1302_Init();        // 時鐘芯片的初始化
  852.         LcdShowInit();        // 液晶顯示內容的初始化
  853.         
  854.         if(DS1302_Read_Byte(0x81)>=128)                        // 判斷時鐘芯片是否正在運行
  855.         {
  856.                 DS1302_Write_Time();                                                        // 如果沒有,則初始化一個時間
  857.         }
  858.         
  859.         while(1)
  860.         {
  861.                 DS1302_Read_Time();                                // 獲取當前時鐘芯片的時間,存在數組time_buf中
  862.                 FlashTime();                                                        // 刷新時間顯示

  863.                 light=Get_ADC0832();                        // 讀取光照強度
  864.                 light=light/2.5;                                        // 縮小光照檢測結果(在0-99)
  865.                 if(light>99)                                                        // 如果大于99
  866.                         light=99;                                                                // 則依然保持99
  867.                 LcdGotoXY(1,14);                                        // 光標定位
  868.                 LcdPrintNum(light);                                // 顯示光照強度
  869.                
  870.                 KeyScanf1();                                                        // 按鍵掃描(時間的設置)
  871.                 KeyScanf2();                                                        // 按鍵掃描(閾值的設置)
  872.                 KeyScanf3();                                                        // 按鍵掃描(模式切換)
  873.         
  874.                 /*手動控制模式*/
  875.                 if(gMode==1||YYOPEN==0)
  876.                 {
  877.                         if(KeyDown_P==0)                // 如果關窗簾鍵按下了        
  878.                         {
  879.                                 if(Led_P==0)                        // 如果窗簾當前是打開的
  880.                                 {
  881.                                         Close();                                // 則光標窗簾
  882.                                 }
  883.                         }
  884.                         if(KeyUp_P==0)                        // 如果開窗簾鍵按下了
  885.                         {
  886.                                 if(Led_P==1)                        // 如果窗簾當前是關閉的
  887.                                 {
  888.                                         Open();                                        // 則打開窗簾
  889.                                 }
  890.                         }        
  891.                 }

  892.                 /*時間控制模式*/
  893.                 if(gMode==2)
  894.                 {
  895.                         if((TimeBuff[4]==CloseHour)&&(TimeBuff[5]==CloseMinute)&&(TimeBuff[6]==0))        // 如果到了關窗簾的時間        
  896.                         {
  897.                                 if(Led_P==0)                        // 如果窗簾當前是打開的
  898.                                 {
  899.                                         Close();                                // 則光標窗簾
  900.                                 }
  901.                         }
  902.                         if((TimeBuff[4]==OpenHour)&&(TimeBuff[5]==OpenMinute)&&(TimeBuff[6]==0))                // 如果到了開窗簾的時間        
  903.                         {
  904.                                 if(Led_P==1)                        // 如果窗簾當前是關閉的
  905.                                 {
  906.                                         Open();                                        // 則打開窗簾
  907.                                 }
  908.                         }        
  909.                 }
  910.                
  911.                 /*光線控制模式*/
  912.                 if(gMode==3)
  913.                 {
  914.                         if(light<gLight || light>gLightmax)                // 當前光線小于設置的閾值
  915.                         {
  916.                                 if(Led_P==0)                        // 如果窗簾當前是打開的
  917.                                 {
  918.                                         Close();                                // 則光標窗簾
  919.                                 }
  920.                         }
  921.                         else                                                                // 當前光線大于或等于設置的閾值
  922.                         {
  923.                                 if(Led_P==1)                        // 如果窗簾當前是關閉的
  924.                                 {
  925.                                         Open();                                        // 則打開窗簾
  926.                                 }
  927.                         }        
  928.                 }
  929.                
  930.                 DelayMs(100);                                                        // 延時0.1秒
  931.         }
  932. }

復制代碼

仿真程序: 智能窗簾.zip (293.27 KB, 下載次數: 50)

評分

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

查看全部評分

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

使用道具 舉報

沙發
ID:34149 發表于 2024-6-8 21:26 | 只看該作者
編寫這么長的代碼,實屬不易,謝謝樓主的分享。
回復

使用道具 舉報

板凳
ID:1122159 發表于 2024-6-9 13:21 | 只看該作者
dyx811 發表于 2024-6-8 21:26
編寫這么長的代碼,實屬不易,謝謝樓主的分享。

哈哈,沒事
回復

使用道具 舉報

地板
ID:496636 發表于 2024-6-10 07:50 | 只看該作者
拷貝到工程里,編譯成功,零錯誤,零警告,注釋也太詳盡了,謝謝樓主
回復

使用道具 舉報

5#
ID:1122580 發表于 2024-6-10 10:25 | 只看該作者
感謝樓主,這么長得代碼,學習了。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 97偷拍视频| 亚洲一区二区在线 | 人碰人操| 丁香久久| 亚洲一区二区 | 欧美日韩视频网站 | 欧美男人亚洲天堂 | 99pao成人国产永久免费视频 | 国产精品久久久久久久久久久久久 | 91精品国产色综合久久不卡98口 | 九九热精品视频 | 成人国产精品久久 | 精品在线一区二区三区 | 91资源在线 | 精精国产xxxx视频在线播放 | 久久最新精品 | 国产精品亚洲成在人线 | 欧一区二区 | 蜜桃精品噜噜噜成人av | 亚洲一区二区三区欧美 | 久久精品女人天堂av | 黄色网址在线免费观看 | 超碰一区二区 | 欧美日韩国产传媒 | 国产免费一区 | 伊人性伊人情综合网 | 免费在线观看av | 日本精品久久久一区二区三区 | 成年免费在线观看 | 手机在线一区二区三区 | 精品国产乱码久久久久久中文 | 中文字幕av一区二区三区 | 欧美激情精品久久久久久 | 最新av中文字幕 | 亚洲国产精品99久久久久久久久 | 国产男人的天堂 | 隔壁老王国产在线精品 | 久久成人免费视频 | 亚洲免费成人 | 激情综合五月天 | 亚洲欧美一区二区三区国产精品 |