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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8061|回復: 3
收起左側

單片機智能溫控風扇控制源碼

[復制鏈接]
ID:237839 發表于 2018-6-24 17:12 | 顯示全部樓層 |閱讀模式
智能風扇,按鍵調節溫度上下限,根據溫度變化風扇有三個檔位。

電路原理圖如下:

proteus仿真圖

proteus仿真圖


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

  5. sbit dq   = P1^5;    //18b20 IO口的定義

  6. uint temperature ;  //
  7. bit flag_200ms ;

  8. bit flag_lj_en;         //按鍵連加使能
  9. bit flag_lj_3_en;     //按鍵連3次連加后使能  加的數就越大了
  10. uchar key_time,key_value;      //用做連加的中間變量
  11. bit key_500ms  ;


  12. uchar code table_num[]="0123456789abcdefg";

  13. sbit rs=P1^0;     //寄存器選擇信號 H:數據寄存器      L:指令寄存器
  14. sbit rw=P1^1;     //寄存器選擇信號 H:數據寄存器      L:指令寄存器
  15. sbit e =P1^2;     //片選信號   下降沿觸發

  16. sbit pwm = P1^4;  
  17. uchar f_pwm_l ;      //

  18. uchar menu_1;        //菜單設計的變量
  19. uint t_high = 300,t_low = 100;


  20. /***********************1ms延時函數*****************************/
  21. void delay_1ms(uint q)
  22. {
  23.     uint i,j;
  24.     for(i=0;i<q;i++)
  25.         for(j=0;j<110;j++);
  26. }

  27. /********************************************************************
  28. * 名稱 : delay_uint()
  29. * 功能 : 小延時。
  30. * 輸入 : 無
  31. * 輸出 : 無
  32. ***********************************************************************/
  33. void delay_uint(uint q)
  34. {
  35.     while(q--);
  36. }

  37. /********************************************************************
  38. * 名稱 : write_com(uchar com)
  39. * 功能 : 1602命令函數
  40. * 輸入 : 輸入的命令值
  41. * 輸出 : 無
  42. ***********************************************************************/
  43. void write_com(uchar com)
  44. {
  45.     e=0;
  46.     rs=0;
  47.     rw=0;
  48.     P0=com;
  49.     delay_uint(25);
  50.     e=1;
  51.     delay_uint(100);
  52.     e=0;
  53. }

  54. /********************************************************************
  55. * 名稱 : write_data(uchar dat)
  56. * 功能 : 1602寫數據函數
  57. * 輸入 : 需要寫入1602的數據
  58. * 輸出 : 無
  59. ***********************************************************************/
  60. void write_data(uchar dat)
  61. {
  62.     e=0;
  63.     rs=1;
  64.     rw=0;
  65.     P0=dat;
  66.     delay_uint(25);
  67.     e=1;
  68.     delay_uint(100);
  69.     e=0;   
  70. }

  71. /********************************************************************
  72. * 名稱 : write_string(uchar hang,uchar add,uchar *p)
  73. * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符開始顯示"ab cd ef" ,調用該函數如下
  74.           write_string(1,5,"ab cd ef;")
  75. * 輸入 : 行,列,需要輸入1602的數據
  76. * 輸出 : 無
  77. ***********************************************************************/
  78. void write_string(uchar hang,uchar add,uchar *p)
  79. {
  80.     if(hang==1)   
  81.         write_com(0x80+add);
  82.     else
  83.         write_com(0x80+0x40+add);
  84.     while(1)
  85.     {
  86.         if(*p == '\0')  break;
  87.         write_data(*p);
  88.         p++;
  89.     }   
  90. }

  91. /***********************lcd1602上顯示特定的字符************************/
  92. void write_zifu(uchar hang,uchar add,uchar date)
  93. {
  94.     if(hang==1)   
  95.         write_com(0x80+add);
  96.     else
  97.         write_com(0x80+0x40+add);
  98.     write_data(date);   
  99. }

  100. /***********************lcd1602上顯示兩位十進制數************************/
  101. void write_sfm3_18B20(uchar hang,uchar add,uint date)
  102. {
  103.     if(hang==1)   
  104.         write_com(0x80+add);
  105.     else
  106.         write_com(0x80+0x40+add);
  107.     write_data(0x30+date/100%10);
  108.     write_data(0x30+date/10%10);
  109.     write_data('.');
  110.     write_data(0x30+date%10);   
  111. }

  112. /***********************lcd1602初始化設置************************/
  113. void init_1602()
  114. {
  115.     write_com(0x38);    //
  116.     write_com(0x0c);
  117.     write_com(0x06);
  118.     delay_uint(1000);
  119.     write_string(1,0,"   temp:  .          ");   
  120.     write_string(2,0,"H:    L:        ");
  121.     write_sfm3_18B20(2,2,t_high);   
  122.     write_sfm3_18B20(2,10,t_low);               
  123.     write_zifu(1,12,0xdf);  //顯示度   
  124. }

  125. /***********************18b20初始化函數*****************************/
  126. void init_18b20()
  127. {
  128.     bit q;
  129.     dq = 1;                //把總線拿高
  130.     delay_uint(1);        //15us
  131.     dq = 0;                //給復位脈沖
  132.     delay_uint(80);        //750us
  133.     dq = 1;                //把總線拿高 等待
  134.     delay_uint(10);        //110us
  135.     q = dq;                //讀取18b20初始化信號
  136.     delay_uint(20);        //200us
  137.     dq = 1;                //把總線拿高 釋放總線
  138. }

  139. /*************寫18b20內的數據***************/
  140. void write_18b20(uchar dat)
  141. {
  142.     uchar i;
  143.     for(i=0;i<8;i++)
  144.     {                     //寫數據是低位開始
  145.         dq = 0;             //把總線拿低寫時間隙開始
  146.         dq = dat & 0x01; //向18b20總線寫數據了
  147.         delay_uint(5);     // 60us
  148.         dq = 1;             //釋放總線
  149.         dat >>= 1;
  150.     }   
  151. }

  152. /*************讀取18b20內的數據***************/
  153. uchar read_18b20()
  154. {
  155.     uchar i,value;
  156.     for(i=0;i<8;i++)
  157.     {
  158.         dq = 0;             //把總線拿低讀時間隙開始
  159.         value >>= 1;     //讀數據是低位開始
  160.         dq = 1;             //釋放總線
  161.         if(dq == 1)         //開始讀寫數據
  162.             value |= 0x80;
  163.         delay_uint(5);     //60us    讀一個時間隙最少要保持60us的時間
  164.     }
  165.     return value;         //返回數據
  166. }


  167. /*************讀取溫度的值 讀出來的是小數***************/
  168. uint read_temp()
  169. {
  170.     uint value;
  171.     uchar low;               //在讀取溫度的時候如果中斷的太頻繁了,就應該把中斷給關了,否則會影響到18b20的時序
  172.     init_18b20();           //初始化18b20

  173.     write_18b20(0xcc);       //跳過64位ROM
  174.     write_18b20(0x44);       //啟動一次溫度轉換命令


  175.     init_18b20();           //初始化18b20

  176.     write_18b20(0xcc);       //跳過64位ROM
  177.     write_18b20(0xbe);       //發出讀取暫存器命令

  178.     low = read_18b20();       //讀溫度低字節
  179.     value = read_18b20();  //讀溫度高字節

  180.     value <<= 8;           //把溫度的高位左移8位
  181.     value |= low;           //把讀出的溫度低位放到value的低八位中
  182.     value *= 0.625;           //轉換到溫度值 小數
  183.     return value;           //返回讀出的溫度 帶小數
  184. }

  185. /*************定時器0初始化程序***************/
  186. void time_init()      
  187. {
  188.     EA   = 1;           //開總中斷
  189.     TMOD = 0X01;      //定時器0、定時器1工作方式1
  190.     ET0  = 1;          //開定時器0中斷
  191.     TR0  = 1;          //允許定時器0定時
  192.     ET1  = 0;          //開定時器0中斷
  193.     TR1  = 0;          //允許定時器0定時
  194. }

  195. /********************獨立按鍵程序*****************/
  196. uchar key_can;     //按鍵值

  197. void key()         //獨立按鍵程序
  198. {
  199.     static uchar key_new;
  200.     key_can = 20;               //按鍵值還原
  201.     if(key_500ms == 1)    //連加
  202.     {
  203.         key_500ms = 0;
  204.         key_new = 1;
  205.     }
  206.     if((P3 & 0xf0) != 0xf0)        //按鍵按下
  207.     {
  208.         delay_1ms(1);             //按鍵消抖動
  209.         if(((P3 & 0xf0) != 0xf0) && (key_new == 1))
  210.         {                        //確認是按鍵按下
  211.             key_new = 0;
  212.             switch(P3 & 0xf0)
  213.             {
  214.                 case 0xe0: key_can = 1; break;       //得到k1鍵值
  215.                 case 0xd0: key_can = 2; break;       //得到K2鍵值
  216.                 case 0xb0: key_can = 3; break;       //得到k3鍵值
  217.             }
  218.             flag_lj_en = 1;     //連加使能
  219.         }            
  220.     }
  221.     else
  222.     {
  223.             key_new = 1;
  224.     }   
  225. }


  226. /****************按鍵顯示函數***************/
  227. void key_with()
  228. {
  229.     if(key_can == 1)       //設置鍵
  230.     {
  231.         menu_1 ++;
  232.         if(menu_1 >= 1)
  233.         {
  234.             menu_1 = 0;
  235.         }
  236.         if(menu_1 == 0)
  237.         {
  238.             write_com(0x0c);                //關閉光標
  239.         }
  240.     }
  241.     if(menu_1 == 1)            //設置高溫報警
  242.     {
  243.         if(key_can == 2)
  244.         {
  245.             if(flag_lj_3_en == 0)
  246.                 t_high ++ ;        //按鍵按下未松開自動加三次   
  247.             else
  248.                 t_high += 10;    //按鍵按下未松開自動加三次之后每次自動加10
  249.             if(t_high > 990)
  250.                 t_high = 990;
  251.         }
  252.         if(key_can == 3)
  253.         {
  254.             if(flag_lj_3_en == 0)
  255.                 t_high -- ;        //按鍵按下未松開自動減三次   
  256.             else
  257.                 t_high -= 10;    //按鍵按下未松開自動減三次之后每次自動減10
  258.             if(t_high <= t_low)
  259.                 t_high = t_low + 1;
  260.         }        
  261.         write_sfm3_18B20(2,2,t_high);
  262.         write_com(0x80+0x40+2);             //將光標移動到秒個位
  263.         write_com(0x0f);                    //顯示光標并且閃爍   
  264.     }   
  265.     if(menu_1 == 2)            //設置低溫報警
  266.     {
  267.         if(key_can == 2)
  268.         {
  269.             if(flag_lj_3_en == 0)
  270.                 t_low ++ ;            //按鍵按下未松開自動加三次   
  271.             else
  272.                 t_low += 10;        //按鍵按下未松開自動加三次之后每次自動加10
  273.             if(t_low >= t_high)
  274.                 t_low = t_high - 1;
  275.         }
  276.         if(key_can == 3)
  277.         {
  278.             if(flag_lj_3_en == 0)
  279.                 t_low -- ;            //按鍵按下未松開自動減三次   
  280.             else
  281.                 t_low -= 10;        //按鍵按下未松開自動加三次之后每次自動加10
  282.             if(t_low <= 10)
  283.                 t_low = 10;
  284.         }
  285.         write_sfm3_18B20(2,10,t_low);
  286.         write_com(0x80+0x40+10);            //將光標移動到秒個位
  287.         write_com(0x0f);                    //顯示光標并且閃爍   
  288.     }   
  289. }

  290. /****************風扇控制函數***************/
  291. void fengshan_kz()
  292. {
  293.     if(temperature >= t_high)      //風扇全開
  294.     {   
  295.         TR1 = 1;
  296.         pwm = 0;
  297.     }
  298.     else if((temperature < t_high)    && (temperature >= t_low))           //風扇緩慢
  299.     {
  300.         f_pwm_l = 60;     
  301.         TR1 = 1;
  302.     }
  303.     else if(temperature < t_low)     //關閉風扇
  304.     {
  305.         TR1 = 0;
  306.         pwm = 1;
  307.     }            
  308. }        

  309. /****************主函數***************/
  310. void main()
  311. {   
  312.     time_init();                    //初始化定時器
  313.     init_1602();                    //1602初始化
  314.     while(1)
  315.     {        
  316.         temperature = read_temp();    //先讀出溫度的值
  317.         write_sfm3_18B20(1,8,temperature);            
  318.         fengshan_kz();        //風扇控制函數

  319.         key();                    //按鍵程序
  320.         if(key_can < 10)
  321.         {
  322.             key_with();                //設置報警溫度   
  323.         }
  324.     }
  325. }

  326. /*************定時器0中斷服務程序***************/
  327. void time0_int() interrupt 1
  328. {   
  329.     static uchar value;
  330.     TH0 = 0x0c;
  331.     TL0 = 0xb0;     // 50ms
  332.     value ++;     
  333.     if(value % 4 == 0)
  334.     {
  335.         flag_200ms = 1;       //300ms
  336.         value = 0;
  337.     }

  338.     if(flag_lj_en == 1)       //按下按鍵使能
  339.     {
  340.         key_time ++;
  341.         if(key_time >= 10) //500ms
  342.         {
  343.             key_time = 0;
  344.             key_500ms = 1; //500ms
  345.             key_value ++;
  346.             if(key_value > 3)
  347.             {
  348.                 key_value = 10;
  349.                 flag_lj_3_en = 1; //3次后1.5秒連加大些
  350.             }                        
  351.         }
  352.     }
  353. }

  354. /*******************定時器1用做單片機模擬PWM 調節***********************/
  355. void Timer1() interrupt 3  //調用定時器1
  356. {
  357.     static uchar value_l;
  358.     TH1=0x3c;    //  
  359.     TL1=0xb0;     //
  360.     if(pwm==1)
  361.     {
  362.         value_l+=1;
  363.         if(value_l > f_pwm_l)   //高電平
  364.         {
  365.         
  366.                 pwm=0;     
  367.         }
  368.     }
  369.     else               
  370.     {
  371.         value_l+=1;
  372.         if(value_l  > f_pwm_l)          //低電平
  373.         {
  374.             pwm=1;
  375.         }
  376.     }
  377. }
復制代碼

回復

使用道具 舉報

ID:853393 發表于 2020-12-9 09:47 | 顯示全部樓層
好的一匹,99999
回復

使用道具 舉報

ID:321836 發表于 2021-5-1 22:05 | 顯示全部樓層
程序被閹割掉了一部分。。。
回復

使用道具 舉報

ID:81441 發表于 2023-4-3 12:48 | 顯示全部樓層
仿真結果不一樣,沒有檔位,按鍵不能進行設置,只能顯示測量溫度。
5566.png
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 午夜精品久久久久久久久久久久久 | 久久久久国产一区二区三区不卡 | 一区二区三区欧美在线 | 精品久久久久久久久久久 | 国产色婷婷精品综合在线手机播放 | 草久久| 福利片在线 | 久久久国产一区二区三区四区小说 | 午夜精品久久久久久久久久久久久 | 精品国产乱码一区二区三 | 午夜不卡一区二区 | 国产999精品久久久久久 | 国产精品国产a级 | 91av在线影院 | 亚洲国产18 | 九九av| 一区二区三区视频免费观看 | 九九热在线观看视频 | 国产精品福利在线 | 亚洲综合久久精品 | 午夜精品一区二区三区在线观看 | 欧美视频精品 | 亚洲瑟瑟 | 中文字幕av网 | 国产日韩欧美激情 | 日韩一区三区 | 四虎永久免费在线 | 国产精品99久久久久久动医院 | 精品国产乱码一区二区三区 | 影音av| 午夜视频在线 | 在线观看a视频 | 一级二级三级在线观看 | 韩国久久精品 | 日本精品一区 | 免费黄视频网站 | 黄色av网站在线观看 | 久久av网 | 一区二区三区四区在线 | 亚洲免费高清 | 成人精品国产 |