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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1805|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

溫控風(fēng)扇的單片機(jī)源碼

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:253484 發(fā)表于 2017-11-25 16:41 | 只看該作者 回帖獎勵 |倒序?yàn)g覽 |閱讀模式

  1. #include <reg52.h>          //調(diào)用單片機(jī)頭文件
  2. #define uchar unsigned char  //無符號字符型 宏定義 變量范圍0~255
  3. #define uint  unsigned int  //無符號整型 宏定義 變量范圍0~65535
  4. #include "eeprom52.h"
  5. //數(shù)碼管段選定義      0     1    2    3    4    5 6  7   8    9
  6. uchar code smg_du[]={0x28,0xee,0x32,0xa2,0xe4,0xa1,0x21,0xea,0x20,0xa0,
  7.         0x60,0x25,0x39,0x26,0x31,0x71,0xff};  //斷碼
  8. //數(shù)碼管位選定義
  9. uchar code smg_we[]={0xef,0xdf,0xbf,0x7f};
  10. uchar dis_smg[8] = {0x28,0xee,0x32,0xa2,0xe4,0x92,0x82,0xf8};
  11. uchar smg_i = 3;    //顯示數(shù)碼管的個位數(shù)
  12. sbit dq   = P2^4; //18b20 IO口的定義
  13. bit flag_lj_en;   //按鍵連加使能
  14. bit flag_lj_3_en;  //按鍵連3次連加后使能  加的數(shù)就越大了
  15. uchar key_time,key_value;      //用做連加的中間變量
  16. bit key_500ms  ;
  17. sbit pwm = P2^3;  
  18. uchar f_pwm_l ;   //越小越暗
  19. uint temperature ;  //
  20. bit flag_300ms ;
  21. uchar menu_1;       //菜單設(shè)計(jì)的變量
  22. uint t_high = 300,t_low = 100;    //溫度上下限報(bào)警值
  23. uint number;
  24. /***********************1ms延時函數(shù)*****************************/
  25. void delay_1ms(uint q)
  26. {
  27. uint i,j;
  28. for(i=0;i<q;i++)
  29.   for(j=0;j<120;j++);
  30. }
  31. /***********************小延時函數(shù)*****************************/
  32. void delay_uint(uint q)
  33. {
  34. while(q--);
  35. }

  36. /***********************數(shù)碼顯示函數(shù)*****************************/
  37. void display()
  38. {
  39. static uchar i;   
  40. i++;
  41. if(i >= smg_i)
  42.   i = 0;
  43. P1 = 0xff;    //消隱
  44. P3 = smg_we[i];     //位選
  45. P1 = dis_smg[i];   //段選         
  46. }
  47. /******************把數(shù)據(jù)保存到單片機(jī)內(nèi)部eepom中******************/
  48. void write_eeprom()
  49. {
  50. SectorErase(0x2000);
  51. byte_write(0x2000, t_high % 256);
  52. byte_write(0x2001, t_high / 256);
  53. byte_write(0x2002, t_low % 256);
  54. byte_write(0x2003, t_low / 256);
  55. byte_write(0x2055, a_a);
  56. }
  57. /******************把數(shù)據(jù)從單片機(jī)內(nèi)部eepom中讀出來*****************/
  58. void read_eeprom()
  59. {
  60. t_high  = byte_read(0x2001);
  61. t_high <<= 8;
  62. t_high  |= byte_read(0x2000);
  63. t_low   = byte_read(0x2003);
  64. t_low <<= 8;
  65. t_low   |= byte_read(0x2002);
  66. a_a      = byte_read(0x2055);
  67. }
  68. /**************開機(jī)初始化保存的數(shù)據(jù)*****************/
  69. void init_eeprom()
  70. {
  71. read_eeprom();  //先讀
  72. if(a_a != 22)  //新的單片機(jī)初始單片機(jī)內(nèi)問eeprom
  73. {
  74.   t_high = 250;
  75.   t_low  = 200;
  76.   a_a = 22;
  77.   write_eeprom();    //保存數(shù)據(jù)
  78. }
  79. }

  80. /***********************18b20初始化函數(shù)*****************************/
  81. void init_18b20()
  82. {
  83. bit q;
  84. dq = 1;    //把總線拿高
  85. delay_uint(1);     //15us
  86. dq = 0;    //給復(fù)位脈沖
  87. delay_uint(80);  //750us
  88. dq = 1;    //把總線拿高 等待
  89. delay_uint(10);  //110us
  90. q = dq;    //讀取18b20初始化信號
  91. delay_uint(20);  //200us
  92. dq = 1;    //把總線拿高 釋放總線
  93. }
  94. /*************寫18b20內(nèi)的數(shù)據(jù)***************/
  95. void write_18b20(uchar dat)
  96. {
  97. uchar i;
  98. for(i=0;i<8;i++)
  99. {      //寫數(shù)據(jù)是低位開始
  100.   dq = 0;    //把總線拿低寫時間隙開始
  101.   dq = dat & 0x01; //向18b20總線寫數(shù)據(jù)了
  102.   delay_uint(5);  // 60us
  103.   dq = 1;    //釋放總線
  104.   dat >>= 1;
  105. }
  106. }
  107. /*************讀取18b20內(nèi)的數(shù)據(jù)***************/
  108. uchar read_18b20()
  109. {
  110. uchar i,value;
  111. for(i=0;i<8;i++)
  112. {
  113.   dq = 0;    //把總線拿低讀時間隙開始
  114.   value >>= 1;  //讀數(shù)據(jù)是低位開始
  115.   dq = 1;    //釋放總線
  116.   if(dq == 1)   //開始讀寫數(shù)據(jù)
  117.    value |= 0x80;
  118.   delay_uint(5);  //60us 讀一個時間隙最少要保持60us的時間
  119. }
  120. return value;   //返回?cái)?shù)據(jù)
  121. }
  122. /*************讀取溫度的值 讀出來的是小數(shù)***************/
  123. uint read_temp()
  124. {
  125. uint value;
  126. uchar low;      //在讀取溫度的時候如果中斷的太頻繁了,就應(yīng)該把中斷給關(guān)了,否則會影響到18b20的時序
  127. init_18b20();     //初始化18b20
  128. EA = 0;
  129. write_18b20(0xcc);    //跳過64位ROM
  130. write_18b20(0x44);    //啟動一次溫度轉(zhuǎn)換命令
  131. EA = 1;
  132. delay_uint(50);     //500us
  133. init_18b20();     //初始化18b20

  134. EA = 0;
  135. write_18b20(0xcc);    //跳過64位ROM
  136. write_18b20(0xbe);    //發(fā)出讀取暫存器命令

  137. low = read_18b20();    //讀溫度低字節(jié)
  138. value = read_18b20();  //讀溫度高字節(jié)
  139. EA = 1;
  140. value <<= 8;     //把溫度的高位左移8位
  141. value |= low;     //把讀出的溫度低位放到value的低八位中
  142. value *= 0.625;        //轉(zhuǎn)換到溫度值 小數(shù)
  143. return value;     //返回讀出的溫度 帶小數(shù)
  144. }
  145. /*************定時器0初始化程序***************/
  146. void time_init()   
  147. {
  148. EA   = 1;     //開總中斷
  149. TMOD = 0X11;   //定時器0、定時器1工作方式1
  150. ET0  = 1;    //開定時器0中斷
  151. TR0  = 1;    //允許定時器0定時
  152. ET1  = 1;    //開定時器0中斷
  153. TR1  = 0;    //允許定時器0定時
  154. }
  155. /********************獨(dú)立按鍵程序*****************/
  156. uchar key_can;  //按鍵值
  157. void key()  //獨(dú)立按鍵程序
  158. {
  159. static uchar key_new;
  160. key_can = 20;                   //按鍵值還原
  161. P2 |= 0x07;
  162. if((P2 & 0x07) != 0x07)  //按鍵按下
  163. {
  164.   if(key_500ms == 1) //連加
  165.   {
  166.    key_500ms = 0;
  167.    key_new = 1;
  168.   }
  169.   delay_1ms(1);       //按鍵消抖動
  170.   if(((P2 & 0x07) != 0x07) && (key_new == 1))
  171.   {      //確認(rèn)是按鍵按下
  172.    key_new = 0;
  173.    switch(P2 & 0x07)
  174.    {
  175.     case 0x06: key_can = 3; break;    //得到k2鍵值
  176.     case 0x05: key_can = 2; break;    //得到k3鍵值
  177.     case 0x03: key_can = 1; break;    //得到k4鍵值
  178.    }
  179.    flag_lj_en = 1;  //連加使能
  180.   }   
  181. }
  182. else
  183. {
  184.   if(key_new == 0)
  185.   {
  186.    key_new = 1;
  187.    write_eeprom();  //保存數(shù)據(jù)
  188.    flag_lj_en = 0;  //關(guān)閉連加使能
  189.    flag_lj_3_en = 0; //關(guān)閉3秒后使能
  190.    key_value = 0;  //清零
  191.    key_time = 0;
  192.    key_500ms = 0;
  193.   }
  194. }
  195. }
  196. /****************按鍵處理數(shù)碼管顯示函數(shù)***************/
  197. void key_with()
  198. {
  199. if(key_can == 1)   //設(shè)置鍵
  200. {
  201.   f_pwm_l = 30;
  202.   menu_1 ++;
  203.   if(menu_1 >= 3)
  204.   {
  205.    menu_1 = 0;
  206.    smg_i = 3;    //數(shù)碼管顯示3位
  207.   }
  208. }
  209. if(menu_1 == 1)   //設(shè)置高溫報(bào)警
  210. {
  211.   smg_i = 4;    //數(shù)碼管顯示4位
  212.   if(key_can == 2)
  213.   {
  214.    if(flag_lj_3_en == 0)
  215.     t_high ++ ;  //按鍵按下未松開自動加三次
  216.    else
  217.     t_high += 10; //按鍵按下未松開自動加三次之后每次自動加10
  218.    if(t_high > 990)
  219.     t_high = 990;
  220.   }
  221.   if(key_can == 3)
  222.   {
  223.    if(flag_lj_3_en == 0)
  224.     t_high -- ;  //按鍵按下未松開自動減三次
  225.    else
  226.     t_high -= 10; //按鍵按下未松開自動減三次之后每次自動減10
  227.    if(t_high <= t_low)
  228.     t_high = t_low + 1;
  229.   }
  230.   dis_smg[0] = smg_du[t_high % 10];            //取小數(shù)顯示
  231.   dis_smg[1] = smg_du[t_high / 10 % 10] & 0xdf;  //取個位顯示
  232.   dis_smg[2] = smg_du[t_high / 100 % 10] ;    //取十位顯示
  233.   dis_smg[3] = 0x64;  //H
  234. }
  235. if(menu_1 == 2)   //設(shè)置低溫報(bào)警
  236. {
  237.   smg_i = 4;    //數(shù)碼管顯示4位
  238.   if(key_can == 2)
  239.   {
  240.    if(flag_lj_3_en == 0)
  241.     t_low ++ ;   //按鍵按下未松開自動加三次
  242.    else
  243.     t_low += 10;  //按鍵按下未松開自動加三次之后每次自動加10
  244.    if(t_low >= t_high)
  245.     t_low = t_high - 1;
  246.   }
  247.   if(key_can == 3)
  248.   {
  249.    if(flag_lj_3_en == 0)
  250.     t_low -- ;   //按鍵按下未松開自動減三次
  251.    else
  252.     t_low -= 10;  //按鍵按下未松開自動加三次之后每次自動加10
  253.    if(t_low <= 10)
  254.     t_low = 10;
  255.   }
  256.   dis_smg[0] = smg_du[t_low % 10];            //取小數(shù)顯示
  257.   dis_smg[1] = smg_du[t_low / 10 % 10] & 0xdf;   //取個位顯示
  258.   dis_smg[2] = smg_du[t_low / 100 % 10] ;        //取十位顯示
  259.   dis_smg[3] = 0x3D;   //L
  260. }
  261. }  
  262. /****************風(fēng)扇控制函數(shù)***************/
  263. void fengshan_kz()
  264. {
  265. if(temperature >= t_high)   //風(fēng)扇全開
  266. {
  267.   TR1 = 1;
  268.   pwm = 0;
  269. }
  270. else if((temperature < t_high) && (temperature >= t_low))     //風(fēng)扇緩慢
  271. {
  272.   f_pwm_l = 60;  
  273.   TR1 = 1;
  274. }
  275. else if(temperature < t_low)  //關(guān)閉風(fēng)扇
  276. {
  277.   TR1 = 0;
  278.   pwm = 1;
  279. }   
  280. }  
  281. /****************主函數(shù)***************/
  282. void main()
  283. {
  284. P0 = P1 = P2 = P3 = 0xff;
  285. time_init();                    //初始化定時器
  286. temperature = read_temp();  //先讀出溫度的值
  287. init_eeprom();  //開始初始化保存的數(shù)據(jù)
  288. delay_1ms(650);   
  289. temperature = read_temp();           //先讀出溫度的值
  290. dis_smg[0] = smg_du[temperature % 10];  //取溫度的小數(shù)顯示
  291. dis_smg[1] = smg_du[temperature / 10 % 10] & 0xdf; //取溫度的個位顯示
  292. dis_smg[2] = smg_du[temperature / 100 % 10] ;    //取溫度的十位顯示
  293. f_pwm_l = 50;
  294. while(1)
  295. {  
  296.   key();     //按鍵程序
  297.   if(key_can < 10)
  298.   {
  299.    key_with();   //設(shè)置報(bào)警溫度
  300.   }
  301.   if(flag_300ms == 1)     //300ms 處理一次溫度程序
  302.   {   
  303.    flag_300ms = 0;
  304.    temperature = read_temp(); //先讀出溫度的值
  305.    if(menu_1 == 0)
  306.    {
  307.     smg_i = 3;
  308.     dis_smg[0] = smg_du[temperature % 10];  //取溫度的小數(shù)顯示
  309.     dis_smg[1] = smg_du[temperature / 10 % 10] & 0xdf; //取溫度的個位顯示
  310.     dis_smg[2] = smg_du[temperature / 100 % 10] ;    //取溫度的十位顯示
  311.    }
  312.   }
  313.   fengshan_kz();        //風(fēng)扇控制函數(shù)
  314. }
  315. }
  316. /*************定時器0中斷服務(wù)程序***************/
  317. void time0_int() interrupt 1
  318. {
  319. static uchar value;    //定時2ms中斷一次
  320. TH0 = 0xf8;
  321. TL0 = 0x30;     //2ms
  322. display();  //數(shù)碼管顯示函數(shù)
  323. value++;   
  324. if(value >= 150)
  325. {
  326.   value = 0;   
  327.   flag_300ms = 1;
  328. }
  329. if(flag_lj_en == 1)    //按下按鍵使能
  330. {
  331.   key_time ++;
  332.   if(key_time >= 250) //500ms
  333.   {
  334.    key_time = 0;
  335.    key_500ms = 1; //500ms
  336.    key_value ++;
  337.    if(key_value > 3)
  338.    {
  339.     key_value = 10;
  340.     flag_lj_3_en = 1; //3次后1.5秒連加大些
  341.    }      
  342.   }
  343. }
  344. }

  345. /*******************定時器1用做單片機(jī)模擬PWM 調(diào)節(jié)***********************/
  346. void Timer1() interrupt 3  //調(diào)用定時器1
  347. {
  348. static uchar value_l;
  349. TH1=0x0f;    //    定時中斷一次
  350. TL1=0xec;  //
  351. if(pwm==1)
  352. {
  353.   value_l+=3;
  354.   if(value_l > f_pwm_l)   //高電平
  355.   {
  356.    value_l=0;
  357.     pwm=0;  
  358.   }
  359. }
  360. else   
  361. {
  362.   value_l+=3;
  363.   if(value_l  > 100 - f_pwm_l)    //低電平
  364.   {
  365.    value_l=0;
  366.    pwm=1;
  367.   }
  368.     }
  369. }
復(fù)制代碼
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表