欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

      標題: 單片機智能溫控風扇控制源碼 [打印本頁]

      作者: wanghao258    時間: 2018-6-24 17:12
      標題: 單片機智能溫控風扇控制源碼
      智能風扇,按鍵調節溫度上下限,根據溫度變化風扇有三個檔位。

      電路原理圖如下:


      單片機源程序如下:
      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. }
      復制代碼


      作者: GKDHBH    時間: 2020-12-9 09:47
      好的一匹,99999
      作者: 已飛的鷹    時間: 2021-5-1 22:05
      程序被閹割掉了一部分。。。
      作者: keywod    時間: 2023-4-3 12:48
      仿真結果不一樣,沒有檔位,按鍵不能進行設置,只能顯示測量溫度。

      5566.png (119.7 KB, 下載次數: 116)

      5566.png





      歡迎光臨 (http://www.raoushi.com/bbs/) Powered by Discuz! X3.1