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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3473|回復: 1
收起左側

基于51單片機的智能風扇Proteus仿真程序設計

[復制鏈接]
ID:525068 發表于 2020-12-15 20:44 | 顯示全部樓層 |閱讀模式
電路原理圖如下:
51hei.png

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

元件清單:
Comment    Description    Designator
10uF    電容    C1
20    電容    C2, C3
    發光二極管    D1
SMG04_1    數碼管    DS1
紅外熱釋電    人體感應傳感器    P1
Header 2    電源接口    P2, P3
9012    三極管    Q1, Q2, Q3, Q4, Q5
1K    電阻    R1, R2, R3, R8, R9, R10, R11, R12
1K    電阻    R4, R5, R6, R7, R15
1K    電阻    R13
10K    電阻    R14, R16
SW-PB    按鍵    S1, S2, S3, S4
sw-灰色    電源開關    SW1
單片機    單片機    U1
DS18B20    溫度傳感器    U2
12M    晶振     Y1

單片機源程序如下:
  1. #include <reg52.h>                 //調用單片機頭文件
  2. #define uchar unsigned char  //無符號字符型 宏定義        變量范圍0~255
  3. #define uint  unsigned int         //無符號整型 宏定義        變量范圍0~65535

  4. //數碼管段選定義      0     1    2    3    4    5        6         7          8           9        
  5. uchar code smg_du[]={0x28,0xe4,0x42,0x72,0xe5,0xa8,0x41,0x77,0x20,0xa0,
  6.                                            0x60,0x25,0x39,0x26,0x31,0x71,0xff};         //斷碼
  7. //數碼管位選定義
  8. uchar code smg_we[]={0xef,0xdf,0xbf,0x7f};
  9. uchar dis_smg[8] = {0};        
  10. uchar smg_i = 3;    //顯示數碼管的個位數
  11. sbit dq   = P2^4;        //18b20 IO口的定義
  12. sbit hw = P2^5;
  13. uchar miao = 30;
  14. uchar flag_en;

  15. bit flag_lj_en;                 //按鍵連加使能
  16. bit flag_lj_3_en;         //按鍵連3次連加后使能  加的數就越大了
  17. uchar key_time,key_value;      //用做連加的中間變量
  18. bit key_500ms  ;
  19. sbit pwm = P2^3;  
  20. uchar f_pwm_l ;          //越小越慢

  21. uint temperature ;  //
  22. bit flag_200ms ;
  23. uchar menu_1;       //菜單設計的變量
  24. uint t_high = 200,t_low = 100;           //溫度上下限報警值

  25. /***********************1ms延時函數*****************************/
  26. void delay_1ms(uint q)
  27. {
  28.         uint i,j;
  29.         for(i=0;i<q;i++)
  30.                 for(j=0;j<120;j++);
  31. }

  32. /***********************小延時函數*****************************/
  33. void delay_uint(uint q)
  34. {
  35.         while(q--);
  36. }


  37. /***********************數碼顯示函數*****************************/
  38. void display()
  39. {
  40.         static uchar i;   
  41.         i++;
  42.         if(i >= smg_i)
  43.                 i = 0;        
  44.         P1 = 0xff;                         //消隱
  45.         P3 = smg_we[i];                          //位選
  46.         P1 = dis_smg[i];                 //段選               

  47. }

  48. /***********************18b20初始化函數*****************************/
  49. void init_18b20()
  50. {
  51.         bit q;
  52.         dq = 1;                                //把總線拿高
  53.         delay_uint(1);            //15us
  54.         dq = 0;                                //給復位脈沖
  55.         delay_uint(80);                //750us
  56.         dq = 1;                                //把總線拿高 等待
  57.         delay_uint(10);                //110us
  58.         q = dq;                                //讀取18b20初始化信號
  59.         delay_uint(20);                //200us
  60.         dq = 1;                                //把總線拿高 釋放總線
  61. }

  62. /*************寫18b20內的數據***************/
  63. void write_18b20(uchar dat)
  64. {
  65.         uchar i;
  66.         for(i=0;i<8;i++)
  67.         {                                         //寫數據是低位開始
  68.                 dq = 0;                         //把總線拿低寫時間隙開始
  69.                 dq = dat & 0x01; //向18b20總線寫數據了
  70.                 delay_uint(5);         // 60us
  71.                 dq = 1;                         //釋放總線
  72.                 dat >>= 1;
  73.         }        
  74. }

  75. /*************讀取18b20內的數據***************/
  76. uchar read_18b20()
  77. {
  78.         uchar i,value;
  79.         for(i=0;i<8;i++)
  80.         {
  81.                 dq = 0;                         //把總線拿低讀時間隙開始
  82.                 value >>= 1;         //讀數據是低位開始
  83.                 dq = 1;                         //釋放總線
  84.                 if(dq == 1)                 //開始讀寫數據
  85.                         value |= 0x80;
  86.                 delay_uint(5);         //60us        讀一個時間隙最少要保持60us的時間
  87.         }
  88.         return value;                 //返回數據
  89. }

  90. /*************讀取溫度的值 讀出來的是小數***************/
  91. uint read_temp()
  92. {
  93.         uint value;
  94.         uchar low;                           //在讀取溫度的時候如果中斷的太頻繁了,就應該把中斷給關了,否則會影響到18b20的時序
  95.         init_18b20();                   //初始化18b20
  96.         write_18b20(0xcc);           //跳過64位ROM
  97.         write_18b20(0x44);           //啟動一次溫度轉換命令
  98.         delay_uint(50);                   //500us

  99.         init_18b20();                   //初始化18b20
  100.         
  101.         write_18b20(0xcc);           //跳過64位ROM
  102.         write_18b20(0xbe);           //發出讀取暫存器命令
  103.         
  104.         low = read_18b20();           //讀溫度低字節
  105.         value = read_18b20();  //讀溫度高字節
  106.         value <<= 8;                   //把溫度的高位左移8位
  107.         value |= low;                   //把讀出的溫度低位放到value的低八位中
  108.         value *= 0.625;               //轉換到溫度值 小數
  109.         return value;                   //返回讀出的溫度 帶小數
  110. }

  111. /*************定時器0初始化程序***************/
  112. void time_init()         
  113. {
  114.         EA   = 1;                   //開總中斷
  115.         TMOD = 0X21;          //定時器0、定時器1工作方式1
  116.         ET0  = 1;                  //開定時器0中斷
  117.         TR0  = 1;                  //允許定時器0定時

  118.         ET1  = 1;                  //開定時器0中斷
  119.         TR1  = 1;                  //允許定時器0定時
  120. }

  121. /********************獨立按鍵程序*****************/
  122. uchar key_can;         //按鍵值

  123. void key()         //獨立按鍵程序
  124. {
  125.         static uchar key_new;
  126.         key_can = 20;                   //按鍵值還原
  127.         P2 |= 0x07;
  128.         if((P2 & 0x07) != 0x07)                //按鍵按下
  129.         {
  130.                 if(key_500ms == 1)        //連加
  131.                 {
  132.                         key_500ms = 0;
  133.                         key_new = 1;
  134.                 }
  135.                 delay_1ms(1);                     //按鍵消抖動
  136.                 if(((P2 & 0x07) != 0x07) && (key_new == 1))
  137.                 {                                                //確認是按鍵按下
  138.                         key_new = 0;
  139.                         switch(P2 & 0x07)
  140.                         {
  141.                                 case 0x06: key_can = 1; break;           //得到k2鍵值
  142.                                 case 0x04: key_can = 2; break;           //得到k3鍵值
  143.                                 case 0x02: key_can = 3; break;           //得到k4鍵值
  144.                         }
  145.                         flag_lj_en = 1;         //連加使能
  146.                 }                        
  147.         }
  148.         else
  149.         {
  150.                 if(key_new == 0)
  151.                 {
  152.                         key_new = 1;
  153.                         flag_lj_en = 0;                //關閉連加使能
  154.                         flag_lj_3_en = 0;        //關閉3秒后使能
  155.                         key_value = 0;                //清零
  156.                         key_time = 0;
  157.                         key_500ms = 0;
  158.                 }
  159.         }        
  160. }

  161. /****************按鍵處理數碼管顯示函數***************/
  162. void key_with()
  163. {
  164.         if(key_can == 1)          //設置鍵
  165.         {
  166.                 f_pwm_l = 30;
  167.                 menu_1 ++;
  168.                 if(menu_1 >= 3)
  169.                 {
  170.                         menu_1 = 0;
  171.                         smg_i = 3;                  //數碼管顯示3位
  172.                 }
  173.         }
  174.         if(menu_1 == 1)                        //設置高溫報警
  175.         {
  176.                 smg_i = 4;                  //數碼管顯示4位
  177.                 if(key_can == 2)
  178.                 {
  179.                         if(flag_lj_3_en == 0)
  180.                                 t_high ++ ;                //按鍵按下未松開自動加三次        
  181.                         else
  182.                                 t_high += 10;        //按鍵按下未松開自動加三次之后每次自動加10
  183.                         if(t_high > 990)
  184.                                 t_high = 990;
  185.                 }
  186.                 if(key_can == 3)
  187.                 {
  188.                         if(flag_lj_3_en == 0)
  189.                                 t_high -- ;                //按鍵按下未松開自動減三次        
  190.                         else
  191.                                 t_high -= 10;        //按鍵按下未松開自動減三次之后每次自動減10
  192.                         if(t_high <= t_low)
  193.                                 t_high = t_low + 1;
  194.                 }
  195.                 dis_smg[0] = smg_du[t_high % 10];                   //取小數顯示
  196.                 dis_smg[1] = smg_du[t_high / 10 % 10] & 0xdf;  //取個位顯示
  197.                 dis_smg[2] = smg_du[t_high / 100 % 10] ;           //取十位顯示
  198.                 dis_smg[3] = 0x64;         //H
  199.         }        
  200.         if(menu_1 == 2)                        //設置低溫報警
  201.         {
  202.                 smg_i = 4;                  //數碼管顯示4位
  203.                 if(key_can == 2)
  204.                 {
  205.                         if(flag_lj_3_en == 0)
  206.                                 t_low ++ ;                        //按鍵按下未松開自動加三次        
  207.                         else
  208.                                 t_low += 10;                //按鍵按下未松開自動加三次之后每次自動加10
  209.                         if(t_low >= t_high)
  210.                                 t_low = t_high - 1;
  211.                 }
  212.                 if(key_can == 3)
  213.                 {
  214.                         if(flag_lj_3_en == 0)
  215.                                 t_low -- ;                        //按鍵按下未松開自動減三次        
  216.                         else
  217.                                 t_low -= 10;                //按鍵按下未松開自動加三次之后每次自動加10
  218.                         if(t_low <= 10)
  219.                                 t_low = 10;
  220.                 }
  221.                 dis_smg[0] = smg_du[t_low % 10];                   //取小數顯示
  222.                 dis_smg[1] = smg_du[t_low / 10 % 10] & 0xdf;   //取個位顯示
  223.                 dis_smg[2] = smg_du[t_low / 100 % 10] ;               //取十位顯示
  224.                 dis_smg[3] = 0x3D;          //L
  225.         }        
  226. }  

  227. /****************風扇控制函數***************/
  228. void fengshan_kz()
  229. {
  230.         if(flag_en == 1)
  231.         {
  232.                 if(temperature >= t_high)          //風扇全開
  233.                 {        
  234.                         TR1 = 1;
  235.                         pwm = 0;
  236.                 }
  237.                 else if((temperature < t_high)        && (temperature >= t_low))                   //風扇緩慢
  238.                 {
  239.                         f_pwm_l = 60;         
  240.                         TR1 = 1;
  241.                 }
  242.                 else if(temperature < t_low)         //關閉風扇
  243.                 {
  244.                         TR1 = 0;
  245.                         pwm = 1;
  246.                 }        
  247.         }               
  248. }
  249.                

  250. /****************主函數***************/
  251. void main()
  252. {
  253.         static uchar value;
  254.         time_init();                    //初始化定時器
  255.         temperature = read_temp();                //先讀出溫度的值        
  256.         delay_1ms(650);                                
  257.         temperature = read_temp();                         //先讀出溫度的值
  258.         dis_smg[0] = smg_du[temperature % 10];         //取溫度的小數顯示
  259.         dis_smg[1] = smg_du[temperature / 10 % 10] & 0xdf; //取溫度的個位顯示
  260.         dis_smg[2] = smg_du[temperature / 100 % 10] ;           //取溫度的十位顯示
  261.         while(1)
  262.         {               
  263.                 key();                                        //按鍵程序
  264.                 if(key_can < 10)
  265.                 {
  266.                         key_with();                        //設置報警溫度        
  267.                 }
  268.                 if(flag_200ms == 1)            //200ms 處理一次溫度程序
  269.                 {           
  270.                         flag_200ms = 0;        
  271.                         temperature = read_temp();        //先讀出溫度的值
  272.                         if(menu_1 == 0)
  273.                         {        
  274.                                 smg_i = 3;
  275.                                 dis_smg[0] = smg_du[temperature % 10];         //取溫度的小數顯示
  276.                                 dis_smg[1] = smg_du[temperature / 10 % 10] & 0xdf; //取溫度的個位顯示
  277.                                 dis_smg[2] = smg_du[temperature / 100 % 10] ;           //取溫度的十位顯示
  278.                         }
  279.                         fengshan_kz();        //風扇控制函數
  280.                         value ++;
  281.                         if(value >= 4)
  282.                         {
  283.                                 value = 0;
  284.                                 if(miao != 0)
  285.                                 {
  286.                                         miao --;    //時間減1
  287.                                 }
  288.                                 if(miao == 0)
  289.                                         flag_en = 0;
  290.                         }
  291.                         if(hw == 1)  //感應到人
  292.                         {
  293.                                 miao = 30;
  294.                                 flag_en = 1;
  295.                         }
  296.                 }

  297.                 display();                //數碼管顯示函數
  298.         }
  299. }

  300. /*************定時器0中斷服務程序***************/
  301. void time0_int() interrupt 1
  302. {        
  303.         static uchar value;                         //定時2ms中斷一次
  304.         TH0 = 0xf8;
  305.         TL0 = 0x30;     //2ms
  306.         value++;         
  307.         if(value >= 150)
  308.         {
  309.                 value = 0;         
  310.                 flag_200ms = 1;
  311.         }
  312.         if(flag_lj_en == 1)           //按下按鍵使能
  313.         {
  314.                 key_time ++;
  315. ……………………

  316. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
智能溫控風扇設計.7z (2.31 MB, 下載次數: 81)
回復

使用道具 舉報

ID:1064592 發表于 2024-4-18 18:58 | 顯示全部樓層
哥,仿真里面沒有紅外熱釋電部分的吧
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产亚洲一区二区三区 | 在线视频日韩 | 青青久久 | 一道本不卡视频 | 黄色毛片在线观看 | 国产精品揄拍一区二区 | 国产精品久久久亚洲 | 日本精品一区二区三区在线观看视频 | 精品国产99 | 日韩视频精品在线 | 国产一区精品在线 | 成人免费视屏 | 99热99| 国产欧美日韩视频 | 精品国产乱码久久久久久闺蜜 | 久久久激情视频 | 日韩高清中文字幕 | 欧美日韩亚洲国产 | 超碰精品在线观看 | 欧美一区二区三区精品 | 亚洲国产精品一区 | 免费不卡视频 | 亚洲综合一区二区三区 | 2018天天干天天操 | 一级欧美| 亚洲欧美中文日韩在线v日本 | 精品久久久久久久久久久 | 成人做爰9片免费看网站 | 欧美一级免费看 | 福利视频网站 | 日韩精品一二三区 | 国产精品久久国产精品99 | 国产精品一区二区三 | 成人影视网| 亚洲成人毛片 | 伊人色综合久久久天天蜜桃 | 在线午夜 | 在线色网 | 九九热这里只有精品在线观看 | 亚洲精品美女视频 | 九九九久久国产免费 |