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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 11290|回復: 10
收起左側

51單片機光照和溫度控制步進電機正反轉程序+仿真

  [復制鏈接]
ID:472654 發表于 2019-1-24 21:36 | 顯示全部樓層 |閱讀模式
51單片機光照和溫度控制步進電機正反轉,有手動和自動控制模式。

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png

單片機源程序如下:
  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^0;                         // 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 ds=P3^1;
  21. bit closeflag,openflag;
  22. uchar gMode=1;                                                                // 1是手動模式,2是時間自動模式,3是亮度自動模式
  23. uchar gLight      = 40;                                // 窗簾開關的閾值
  24. uchar wDu=35;
  25. uint wd=13,t;
  26. uchar xsflag;

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

  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. void delay(uint z)                                                  //延時函數
  47. {
  48.         uint x,y;
  49.         for(x=z;x>0;x--)
  50.                 for(y=110;y>0;y--);
  51. }

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


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


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


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


  102. /*********************************************************/
  103. // 液晶輸出字符串函數
  104. /*********************************************************/
  105. void LcdPrintStr(uchar *str)
  106. {
  107.         while(*str!='\0')
  108.                         LcdWriteData(*str++);
  109. }


  110. /*********************************************************/
  111. // 液晶輸出數字(0-99)
  112. /*********************************************************/
  113. void LcdPrintNum(uchar num)
  114. {
  115.         LcdWriteData(num/10+48);                // 十位
  116.         LcdWriteData(num%10+48);                 // 個位
  117. }


  118. /*********************************************************/
  119. // 顯示模式
  120. /*********************************************************/
  121. void LcdPrintMode(uchar num)
  122. {
  123.         switch(num)                        
  124.         {
  125.                 case 1: LcdPrintStr("Manual");        break;
  126.         /*        case 2: LcdPrintStr("Timing");        break;*/
  127.                 case 2: LcdPrintStr("Liging");        break;
  128.                 case 3: LcdPrintStr(" Wendu");        break;
  129.                 default:                                                                                                break;
  130.         }
  131. }


  132. /*********************************************************/
  133. // 液晶顯示內容的初始化
  134. /*********************************************************/
  135. void LcdShowInit()
  136. {
  137.         LcdGotoXY(0,0);
  138.         LcdPrintStr("20du   -     :  ");
  139.         LcdGotoXY(1,0);
  140.         LcdPrintStr("           gz:  ");
  141.         LcdGotoXY(1,0);
  142.         LcdPrintMode(gMode);
  143. }



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


  165. /*********************************************************/
  166. // 初始化DS1302
  167. /*********************************************************/
  168. void DS1302_Init(void)
  169. {
  170.         RST_P=0;                        // RST腳置低
  171.         SCK_P=0;                        // SCK腳置低
  172.         SDA_P=0;                        // SDA腳置低                                
  173. }


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


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

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


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



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

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

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


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


  314. /*********************************************************/
  315. // 獲取指定通道的A/D轉換結果
  316. /*********************************************************/
  317. uchar Get_ADC0832()
  318. {
  319.         uchar i;
  320.         uchar dat1=0;
  321.         uchar dat2=0;
  322.         
  323.         ADC_CLK = 0;                                // 電平初始化
  324.         ADC_DAT = 1;
  325.         _nop_();
  326.         ADC_CS = 0;
  327.         WavePlus();                                        // 起始信號
  328.         ADC_DAT = 1;
  329.         WavePlus();                                        // 通道選擇的第一位
  330.         ADC_DAT = 0;      
  331.         WavePlus();                                        // 通道選擇的第二位
  332.         ADC_DAT = 1;
  333.         
  334.         for(i=0;i<8;i++)                // 第一次讀取
  335.         {
  336.                 dat1<<=1;
  337.                 WavePlus();
  338.                 if(ADC_DAT)
  339.                         dat1=dat1|0x01;
  340.                 else
  341.                         dat1=dat1|0x00;
  342.         }
  343.         
  344.         for(i=0;i<8;i++)                // 第二次讀取
  345.         {
  346.                 dat2>>= 1;
  347.                 if(ADC_DAT)
  348.                         dat2=dat2|0x80;
  349.                 else
  350.                         dat2=dat2|0x00;
  351.                 WavePlus();
  352.         }
  353.         
  354.         _nop_();                                                // 結束此次傳輸
  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,6);                                        // 定位光標到年份閃爍
  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. uint temp,mm;uchar i;float f_temp;
  551. /*******************************************************
  552. 溫度函數
  553. *******************************************************/
  554. void dsreset(void)                                           //下邊是溫度獲取子程衼E
  555. {
  556.         uint i;
  557.         ds=0;
  558.         i=103;
  559.         while(i>0)i--;
  560.         ds=1;
  561.         i=4;
  562.         while(i>0)i--;
  563. }
  564. bit tempreadbit(void)                                   //讀一位
  565. {
  566.         uint i;
  567.         bit dat;
  568.         ds=0;i++;
  569.         ds=1;i++;i++;
  570.         dat=ds;
  571.         i=8;while(i>0)i--;
  572.         return(dat);
  573. }
  574. uchar tempread(void)                                         //獲取溫度
  575. {
  576.         uchar i,j,dat;
  577.         dat=0;
  578.         for(i=1;i<=8;i++)
  579.         {
  580.                 j=tempreadbit();
  581.                 dat=(j<<7)|(dat>>1);
  582.         }
  583.         return(dat);
  584. }
  585. void tempwritebyte(uchar dat)                           //寫一個字節
  586. {
  587.         uint i;
  588.         uchar j;
  589.         bit testb;
  590.         for(j=1;j<=8;j++)
  591.         {
  592.                 testb=dat&0x01;
  593.                 dat=dat>>1;
  594.                 if(testb)
  595.                 {
  596.                         ds=0;
  597.                         i++;i++;
  598.                         ds=1;
  599.                         i=8;while(i>0)i--;
  600.                 }
  601.                 else
  602.                 {
  603.                         ds=0;
  604.                         i=8;while(i>0)i--;
  605.                         ds=1;
  606.                         i++;i++;
  607.                 }
  608.         }
  609. }
  610. void tempchange(void)                                           //溫度轉換
  611. {
  612.         dsreset();
  613.         delay(1);
  614.         tempwritebyte(0xcc);
  615.         tempwritebyte(0x44);
  616. }
  617. uint get_temp()                                                        //獲取溫度
  618. {
  619.         uchar a,b;
  620.         dsreset();
  621.         delay(1);
  622.         tempwritebyte(0xcc);
  623.         tempwritebyte(0xbe);
  624.         a=tempread();
  625.         b=tempread();
  626.         temp=b;
  627.         temp<<=8;
  628.         temp=temp|a;
  629.         f_temp=temp*0.0625;
  630.         temp=f_temp*10+0.5;
  631.         f_temp=f_temp+0.05;
  632.         return temp;
  633. }
  634. /***********************************/

  635. /*********************************************************/
  636. // 按鍵掃描(設置窗簾的動作)
  637. /*********************************************************/
  638. void KeyScanf2()
  639. {
  640.         if(KeySet2_P==0)
  641.         {
  642.                 xsflag++;
  643.                 if(xsflag>=2)
  644.                         xsflag=0;
  645.                 while(!KeySet2_P);
  646.         }
  647.         if(xsflag==1)
  648.         {
  649.                 //                 /* 光照強度的設置 */
  650.                 LcdWriteCmd(0x0C);                                                                // 關閉光眮E了?
  651.                 LcdGotoXY(0,0);                                                                                // 光眮Eㄎ?
  652.                 LcdPrintStr("   Light Set    ");        // 顯示第1行內容
  653.                 LcdGotoXY(1,0);                                                                                // 光眮Eㄎ?
  654.                 LcdPrintStr("                ");        // 顯示第2行內容
  655.                 LcdGotoXY(1,7);                                                                                // 光眮Eㄎ?
  656.                 LcdPrintNum(gLight);                                                        // 顯示窗簾的光線控制強度閾值
  657.                
  658.                 while(1)
  659.                 {
  660.                         if(KeySet2_P==0)
  661.                         {
  662.                                 xsflag++;
  663.                                 if(xsflag>=3)
  664.                                         xsflag=0;
  665.                                 while(!KeySet2_P);
  666.                         }
  667.                         if(xsflag==1)
  668.                         {
  669.                                 if(KeyDown_P==0)                                                        // 如果減按紒E幌氯?
  670.                                 {
  671.                                         if(gLight>0)                                                                // 判斷光線閾值是否大于0
  672.                                                 gLight--;                                                                        // 是的話就減去1
  673.                                         LcdGotoXY(1,7);                                                        // 光眮Eㄎ?
  674.                                         LcdPrintNum(gLight);                                // 刷新顯示改變后的光線閾值
  675.                                         DelayMs(300);                                                                // 延時0.3脕E笥?
  676.                                 }
  677.                                 
  678.                                 if(KeyUp_P==0)                                                                // 如果加按紒E幌氯?
  679.                                 {
  680.                                         if(gLight<99)                                                                // 判斷光線閾值是否小于59
  681.                                                 gLight++;                                                                        // 是的話就加上1
  682.                                         LcdGotoXY(1,7);                                                        // 光眮Eㄎ?
  683.                                         LcdPrintNum(gLight);                                // 刷新顯示改變后的光線閾值
  684.                                         DelayMs(300);                                                                // 延時0.3脕E笥?
  685.                                 }
  686.                         }
  687.                         if(xsflag==2)
  688.                         {
  689.                                 //                 設置溫度
  690.                                 LcdWriteCmd(0x0C);                                                                // 關閉光眮E了?
  691.                                 LcdGotoXY(0,0);                                                                                // 光眮Eㄎ?
  692.                                 LcdPrintStr("   Wendu Set    ");        // 顯示第1行內容
  693.                                 LcdGotoXY(1,0);                                                                                // 光眮Eㄎ?
  694.                                 LcdPrintStr("                ");        // 顯示第2行內容
  695.                                 LcdGotoXY(1,7);                                                                                // 光眮Eㄎ?
  696.                                 LcdPrintNum(wDu);                                                        // 顯示窗簾的光線控制強度閾值        
  697.                                 while(!KeySet2_P);
  698.                                 while(1)
  699.                                 {
  700.                                         LcdGotoXY(1,7);                                                                                // 光眮Eㄎ?
  701.                                         LcdPrintNum(wDu);                                                        // 顯示窗簾的光線控制強度閾值
  702.                                         if(KeyDown_P==0)                                                        // 如果減按紒E幌氯?
  703.                                         {
  704.                                                 if(wDu>0)                                                                // 判斷光線閾值是否大于0
  705.                                                         wDu--;                                                                        // 是的話就減去1
  706.                                                 DelayMs(300);                                                                // 延時0.3脕E笥?
  707.                                         }
  708.                                        
  709.                                         if(KeyUp_P==0)                                                                // 如果加按紒E幌氯?
  710.                                         {
  711.                                                 if(wDu<99)                                                                // 判斷光線閾值是否小于59
  712.                                                         wDu++;                                                                        // 是的話就加上1
  713.                                                 DelayMs(300);                                                                // 延時0.3脕E笥?
  714.                                         }
  715.                                         if(KeySet2_P==0)
  716.                                         {
  717.                                                 break;
  718.                                         }
  719.                                 }
  720.                         }
  721.                         if(xsflag==0)
  722.                         {
  723.                                 break;
  724.                         }
  725.                 }
  726.                         //                 /* 退出前的設置 */
  727.                 LcdShowInit();                                        // 液晶顯示內容初始化
  728.                 DelayMs(10);                                                // 延時等待,消除按紒E聰碌畝抖?
  729.                 while(!KeySet2_P);                        // 等待按紒E頭?
  730.                 DelayMs(10);
  731.         }
  732. }


  733. /*********************************************************/
  734. // 按鍵掃描(模式切換)
  735. /*********************************************************/
  736. void KeyScanf3()
  737. {
  738.         if(KeyMode_P==0)
  739.         {
  740.                 DelayMs(10);
  741.                 if(KeyMode_P==0)
  742.                 {
  743.                 gMode++;                                                        // 切換到下一模式
  744.                 if(gMode==4)                                        // 如果到盡頭了
  745.                         gMode=1;                                                // 回到第一種模式
  746.                 LcdGotoXY(1,0);                                // 光標定位
  747.                 LcdPrintMode(gMode);        // 顯示模式
  748.                                                         
  749.                 while(!KeyMode_P);                // 等待按鍵是否
  750.                 }
  751.         }
  752. }


  753. /*********************************************************/
  754. // 開窗
  755. /*********************************************************/
  756. void Open()
  757. {
  758.         uint i,j;
  759.         for(j=0;j<255;j++)                // 控制步進電機正轉
  760.         {
  761.                 for(i=0;i<4;i++)
  762.                 {
  763.                         P2=Clock[i];
  764.                         DelayMs(3);
  765.                 }
  766.         }
  767.         Led_P=0;
  768. }



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



  785. /*********************************************************/
  786. // 主函數
  787. /*********************************************************/
  788. void main()
  789. {
  790.         uchar light;
  791.         
  792.         LcdInit();                        // 執行液晶初始化        
  793.         DS1302_Init();        // 時鐘芯片的初始化
  794.         LcdShowInit();        // 液晶顯示內容的初始化
  795.         if(DS1302_Read_Byte(0x81)>=128)                        // 判斷時鐘芯片是否正在運行
  796.         {
  797.                 DS1302_Write_Time();                                                        // 如果沒有,則初始化一個時間
  798.         }
  799.         while(1)
  800.         {
  801.                 tempchange();
  802.                 t=get_temp();
  803.                 if(t>=0&&t<=1250)  //溫度合法范圍,不在這個范圍就是沒有獲取到合適的值
  804.                 {
  805.                         wd=t/10;
  806.                 }
  807.                 DS1302_Read_Time();                                // 獲取當前時鐘芯片的時間,存在數組time_buf中
  808.                 FlashTime();                                                        // 刷新時間顯示

  809.                 light=Get_ADC0832();                        // 讀取光照強度
  810.                 light=light/2.5;                                        // 縮小光照檢測結果(在0-99)
  811.                 if(light>99)                                                        // 如果大于99
  812.                         light=99;                                                                // 則依然保持99
  813.                 LcdGotoXY(1,14);                                        // 光標定位
  814.                 LcdPrintNum(light);                                // 顯示光照強度
  815.                
  816.                 KeyScanf1();                                                        // 按鍵掃描(時間的設置)
  817.                 KeyScanf2();                                                        // 按鍵掃描(閾值的設置)
  818.                 KeyScanf3();                                                        // 按鍵掃描(模式切換)
  819.         
  820.                 /*手動控制模式*/
  821.                 if(gMode==1)
  822.                 {
  823.                         if(closeflag==1)
  824.                         {
  825.                                 if(Led_P==0)                        // 如果窗簾當前是打開的
  826.                                 {
  827.                                         closeflag=0;
  828.                                         Close();                                // 則光標窗簾
  829.                                 }else
  830.                                 closeflag=0;
  831.                         }
  832.                         if(KeyDown_P==0)                // 如果關窗簾鍵按下了        
  833.                         {
  834.                                 if(Led_P==0)                        // 如果窗簾當前是打開的
  835.                                 {
  836.                                         Close();                                // 則光標窗簾
  837.                                 }
  838.                         }
  839.                         if(openflag==1)
  840.                         {
  841.                                 if(Led_P==1)                        // 如果窗簾當前是關閉的
  842.                                 {
  843.                                         openflag=0;
  844.                                         Open();                                        // 則打開窗簾
  845.                                 }else{
  846.                                         openflag=0;
  847.                                 }
  848.                                 
  849.                         }
  850.                         if(KeyUp_P==0)                        // 如果開窗簾鍵按下了
  851.                         {
  852.                                 if(Led_P==1)                        // 如果窗簾當前是關閉的
  853.                                 {
  854.                                         Open();                                        // 則打開窗簾
  855.                                 }
  856.                         }        
  857.                 }
  858.                

  859.                
  860.                 /*光線控制模式*/
  861.                 if(gMode==2)
  862.                 {
  863.                         if(light<gLight)                // 當前光線小于設置的閾值
  864.                         {
  865.                                 if(Led_P==0)                        // 如果窗簾當前是打開的
  866.                                 {
  867.                                         Close();                                // 則光標窗簾
  868.                                 }
  869.                         }
  870.                         else                                                                // 當前光線大于或等于設置的閾值
  871.                         {
  872.                                 if(Led_P==1)                        // 如果窗簾當前是關閉的
  873.                                 {
  874.                                         Open();                                        // 則打開窗簾
  875.                                 }
  876.                         }        
  877.                 }
  878.                
  879.                 if(gMode==3)
  880.                 {
  881.                         if(wd<wDu)                // 當前溫度小于設置的閾值
  882.                         {
  883.                                 if(Led_P==0)                        // 如果窗簾當前是打開的
  884.                                 {
  885.                                         Close();                                // 則關閉窗簾
  886.                                 }
  887.                         }
  888.                         else                                                                // 當前溫度大于或等于設置的閾值
  889.                         {
  890.                                 if(Led_P==1)                        // 如果窗簾當前是關閉的
  891.                                 {
  892.                                         Open();                                        // 則打開窗簾
  893.                                 }
  894.                         }        
  895.                 }
  896.                
  897.                 DelayMs(100);                                                        // 延時0.1秒
  898.         }
  899. }  
復制代碼

所有資料51hei提供下載:
04、單片機程序(先解壓后查看).rar (311 KB, 下載次數: 204)
回復

使用道具 舉報

ID:472654 發表于 2019-1-26 18:57 | 顯示全部樓層

RE: 51單片機光照和溫度控制步進電機正反轉程序原理圖仿真圖說明書

原理圖仿真圖及說明書與數據手冊
0.png

全部資料51hei下載地址:
原理仿真及說明.7z (2.44 MB, 下載次數: 171)

評分

參與人數 1黑幣 +100 收起 理由
admin + 100 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:739134 發表于 2020-4-28 20:22 | 顯示全部樓層
你好,作者,我下載了您的程序感覺有點小問題,希望能夠和您交流一下
回復

使用道具 舉報

ID:368810 發表于 2020-5-22 16:57 | 顯示全部樓層
光敏元件使用變阻器模擬的嗎
回復

使用道具 舉報

ID:615183 發表于 2020-6-29 10:58 | 顯示全部樓層
樓主的資料很有幫助!非常感謝~
回復

使用道具 舉報

ID:495287 發表于 2020-6-29 12:14 | 顯示全部樓層
良師帶路新求知,
桃李澤眾增學識;
舉手撥開迷途霧;
善行福報不言遲。
回復

使用道具 舉報

ID:792879 發表于 2020-6-29 16:27 | 顯示全部樓層
zyy1100 發表于 2020-5-22 16:57
光敏元件使用變阻器模擬的嗎

沒有,沒有用到呢
回復

使用道具 舉報

ID:996515 發表于 2021-12-24 14:09 | 顯示全部樓層
樓主的資料很有幫助!非常感謝~真的很有幫助
回復

使用道具 舉報

ID:699194 發表于 2022-4-13 20:19 | 顯示全部樓層
qwt15116094665 發表于 2020-4-28 20:22
你好,作者,我下載了您的程序感覺有點小問題,希望能夠和您交流一下

你把這塊程序替換了就可以正常使用了,hhhh

uchar DS1302_Read_Byte(uchar addr)
{
        uchar i;
        uchar temp;
       
        RST_P=1;                                                               
       
        /* 寫入目標地址:addr*/
        for(i=0;i<8;i++)
        {     
                if(addr&0x01)
                        SDA_P=1;
                else
                        SDA_P=0;
               
                SCK_P=1;
                _nop_();
                SCK_P=0;
                _nop_();
               
                addr=addr>> 1;
        }
       
        /* 讀出該地址的數據 */
        for(i=0;i<8;i++)
        {
                temp=temp>>1;
               
                if(SDA_P)
                        temp|= 0x80;
                else
                        temp&=0x7F;
               
                SCK_P=1;
                _nop_();
                SCK_P=0;
                _nop_();
        }
       
        RST_P=0;
       
        return temp;
}
回復

使用道具 舉報

ID:699194 發表于 2022-4-13 20:30 | 顯示全部樓層
作者留了一手,哈哈哈哈哈哈

uchar DS1302_Read_Byte(uchar addr)
{
        uchar i;
        uchar temp;
       
        RST_P=1;                                                               
       
        /* 寫入目標地址:addr*/
        for(i=0;i<8;i++)
        {     
                if(addr&0x01)
                        SDA_P=1;
                else
                        SDA_P=0;
               
                SCK_P=1;
                _nop_();
                SCK_P=0;
                _nop_();
               
                addr=addr>> 1;
        }
       
        /* 讀出該地址的數據 */
        for(i=0;i<8;i++)
        {
                temp=temp>>1;
               
                if(SDA_P)
                        temp|= 0x80;
                else
                        temp&=0x7F;
               
                SCK_P=1;
                _nop_();
                SCK_P=0;
                _nop_();
        }
       
        RST_P=0;
       
        return temp;
}
回復

使用道具 舉報

ID:861681 發表于 2022-5-20 08:26 來自手機 | 顯示全部樓層
真的牛
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 操到爽| 精品亚洲一区二区三区四区五区 | 一级做a| 亭亭五月激情 | 99精品国产一区二区三区 | 日韩成人在线播放 | 美女视频一区二区三区 | 国产伦一区二区三区 | 国产欧美日韩视频 | 一区二区福利视频 | 91精品国产综合久久福利软件 | 午夜精品久久 | 国产精品视频久久 | 日本成人在线观看网站 | 中国一级毛片免费 | 久草成人| 欧美在线亚洲 | 久久综合久 | 九九热免费观看 | 国产精品久久久久久久白浊 | 日韩av在线不卡 | 亚洲精品一| 颜色网站在线观看 | 日韩三级视频 | 国产成人免费视频网站视频社区 | 欧美午夜影院 | 午夜精品福利视频 | 夜久久 | 欧美一区二区三区在线观看视频 | 国内精品视频在线观看 | 99精品在线观看 | 亚洲激情一级片 | 岛国精品 | 亚洲精品在线免费观看视频 | 日韩视频一区二区三区 | 国产精品1区| 国产一区二区三区精品久久久 | 手机在线不卡av | 成人精品系列 | 亚洲视频在线一区 | 精品国产一区二区三区久久久蜜月 |