找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

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

一款單片機(jī)+三極管驅(qū)動(dòng)的溫控小風(fēng)扇代碼與Proteus仿真原理圖

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
系統(tǒng)主要設(shè)計(jì)了一個(gè)基于單片機(jī)的風(fēng)扇溫控儀,以單片機(jī)和DS18B20傳感器為核心,具有溫度顯示和控制風(fēng)扇轉(zhuǎn)速功能DS18B20傳感器,將檢測(cè)到的溫度轉(zhuǎn)化為數(shù)字信號(hào),單片機(jī)對(duì)輸入的數(shù)字信號(hào)進(jìn)行分析處理,當(dāng)溫度高于上限值時(shí),風(fēng)扇全速旋轉(zhuǎn);當(dāng)溫度低于下限時(shí),風(fēng)扇停轉(zhuǎn);當(dāng)溫度處于上限值與下限之間時(shí),風(fēng)扇轉(zhuǎn)速越慢,。圖1所示為系統(tǒng)設(shè)計(jì)結(jié)構(gòu)框圖。

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


電路原理圖如下:


單片機(jī)源程序如下:
  1. #include <reg52.h>
  2. #include <stdio.h>
  3. #include<intrins.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. sbit dq=P3^6;

  7. sbit w4=P2^6;
  8. sbit w3=P2^4;
  9. sbit w2=P2^2;
  10. sbit w1=P2^0;
  11. sbit dp=P0^7;
  12. sbit fs=P3^7;//風(fēng)扇接口
  13. sbit key_shezhi=P1^5;
  14. sbit key_jia=P1^6;
  15. sbit key_jian=P1^7;
  16. uchar flag_0;
  17. uint t_max=250,t_max_1=300;
  18. uint count=0;
  19. int wendu,t;
  20. uchar speed;                        //速度變量
  21. void delay(uint z)                                                  //延時(shí)函數(shù)
  22. {
  23.         uint x,y;
  24.         for(x=z;x>0;x--)
  25.                 for(y=110;y>0;y--);
  26. }
  27. /********************************/
  28. void pro()//按鍵處理函數(shù)
  29. {
  30.         if(key_shezhi==0)
  31.         {
  32.                 delay(10);
  33.                 if(key_shezhi==0)
  34.                 {
  35.                         flag_0++;
  36.                         if(flag_0>=3)
  37.                                 flag_0=0;
  38.                         while(!key_shezhi)        ;
  39.                 }
  40.         }
  41. }
  42. /**********************************/
  43. uchar code table[]={
  44. 0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8, 0x80,0x90,0xbf//0  1  2  3......7  8  9 的字形碼
  45. };
  46. uchar code table1[]={
  47. 0xc7,0x89                                                                //  L    H   的字形碼
  48. };
  49. uint temp,mm;uchar i;float f_temp;


  50. /***********************小延時(shí)函數(shù)*****************************/
  51. void delay_uint(uint q)
  52. {
  53.         while(q--);
  54. }
  55. /*******************************************************

  56. /***********************18b20初始化函數(shù)*****************************/
  57. void init_18b20()
  58. {
  59.         bit q;
  60.         dq = 1;                                //把總線拿高
  61.         delay_uint(1);            //15us
  62.         dq = 0;                                //給復(fù)位脈沖
  63.         delay_uint(80);                //750us
  64.         dq = 1;                                //把總線拿高 等待
  65.         delay_uint(10);                //110us
  66.         q = dq;                                //讀取18b20初始化信號(hào)
  67.         delay_uint(20);                //200us
  68.         dq = 1;                                //把總線拿高 釋放總線
  69. }

  70. /*************寫(xiě)18b20內(nèi)的數(shù)據(jù)***************/
  71. void write_18b20(uchar dat)
  72. {
  73.         uchar i;
  74.         for(i=0;i<8;i++)
  75.         {                                         //寫(xiě)數(shù)據(jù)是低位開(kāi)始
  76.                 dq = 0;                         //把總線拿低寫(xiě)時(shí)間隙開(kāi)始
  77.                 dq = dat & 0x01; //向18b20總線寫(xiě)數(shù)據(jù)了
  78.                 delay_uint(5);         // 60us
  79.                 dq = 1;                         //釋放總線
  80.                 dat >>= 1;
  81.         }        
  82. }

  83. /*************讀取18b20內(nèi)的數(shù)據(jù)***************/
  84. uchar read_18b20()
  85. {
  86.         uchar i,wendu;
  87.         for(i=0;i<8;i++)
  88.         {
  89.                 dq = 0;                         //把總線拿低讀時(shí)間隙開(kāi)始
  90.                 wendu >>= 1;         //讀數(shù)據(jù)是低位開(kāi)始
  91.                 dq = 1;                         //釋放總線
  92.                 if(dq == 1)                 //開(kāi)始讀寫(xiě)數(shù)據(jù)
  93.                         wendu |= 0x80;
  94.                 delay_uint(5);         //60us        讀一個(gè)時(shí)間隙最少要保持60us的時(shí)間
  95.         }
  96.         return wendu;                 //返回?cái)?shù)據(jù)
  97. }

  98. /*************讀取溫度的值 讀出來(lái)的是小數(shù)***************/
  99. uint read_temp()
  100. {
  101.         uint wendu;
  102.         uchar low;                           //在讀取溫度的時(shí)候如果中斷的太頻繁了,就應(yīng)該把中斷給關(guān)了,否則會(huì)影響到18b20的時(shí)序
  103.         init_18b20();                   //初始化18b20
  104.         write_18b20(0xcc);           //跳過(guò)64位ROM
  105.         write_18b20(0x44);           //啟動(dòng)一次溫度轉(zhuǎn)換命令
  106.         delay_uint(50);                   //500us

  107.         init_18b20();                   //初始化18b20
  108.         
  109.         write_18b20(0xcc);           //跳過(guò)64位ROM
  110.         write_18b20(0xbe);           //發(fā)出讀取暫存器命令
  111.         
  112.         EA = 0;
  113.         low = read_18b20();           //讀溫度低字節(jié)
  114.         wendu = read_18b20();  //讀溫度高字節(jié)
  115.         EA = 1;
  116.         wendu <<= 8;                   //把溫度的高位左移8位
  117.         wendu |= low;                   //把讀出的溫度低位放到value的低八位中
  118.         wendu *= 0.625;               //轉(zhuǎn)換到溫度值 小數(shù)
  119.         return wendu;                   //返回讀出的溫度 帶小數(shù)
  120. }
  121. void display0()
  122. {
  123.         P0=0xff;//消隱
  124.         w1=0;                                //選通第一位數(shù)碼管
  125.         if(speed>5)                        //如果speed的值>5則檔位顯示speed-5,比如speed=6,則顯示1檔
  126.         P0=table[speed-5];//顯示檔位
  127.         else                                //否則speed的值如果小于5,則顯示0檔
  128.         P0=table[0];//顯示檔位        
  129.         delay(2);//延遲一會(huì)
  130.         w1=1;//關(guān)閉第一位數(shù)碼管
  131.                         
  132.         P0=0xff;//第二位數(shù)碼管的顯示原理及方法同上
  133.         w2=0;
  134.         P0=0xbf;//顯示-
  135.         delay(2);
  136.         w2=1;
  137.         
  138.         P0=0xff;
  139.         w3=0;
  140.         P0=table[wendu/100];//顯示溫度十位

  141.         delay(2);
  142.         w3=1;
  143.         
  144.         P0=0xff;
  145.         w4=0;
  146.         P0=table[wendu%100/10];//顯示溫度各位
  147.         delay(2);
  148.         w4=1;        
  149. }
  150. void zi_dong()//自動(dòng)溫控模式
  151. {
  152. //        此函數(shù)的目的是將上限和下限的差值平均為5份,每一份對(duì)應(yīng)一個(gè)速度值                14-25
  153.         if(wendu<t_max)                                                                                                                   //溫度小于下限
  154.         speed=0;                                                                                                                           //速度0檔
  155.         else if(wendu>=t_max&&(wendu<(uint)((t_max_1-t_max)/4+t_max)))                                           //溫度大于下限并且小于(上限減去下限)除以4加下限
  156.         speed=6;                                                                                                                           //6檔                14-16.75          14-15
  157.         else if((wendu>=(uint)((float)(t_max_1-t_max)/4+t_max))&&(wendu<(uint)((float)(t_max_1-t_max)/2+t_max)))           //溫度大于 (上限減去下限)除以4加下限  并且小于(上限減去下限)除以2加下限
  158.         speed=7;                                                                                                                           //7檔                16-19.5                  16-18
  159.         else if((wendu>=(uint)(t_max_1-t_max)/2+t_max)&&(wendu<(uint)((float)((float)(t_max_1-t_max)/4)*3+t_max)))   //溫度大于 (上限減去下限)除以2加下限  并且小于(上限減去下限)除以4乘以3加下限
  160.         speed=8;                                                                                                                           //8檔                19-22.25          19-21
  161.         else if((wendu>=(uint)((float)((float)(t_max_1-t_max)/4)*3+t_max))&&wendu<t_max_1)                                   //溫度大于 (上限減去下限)除以4乘以3加下限  并且小于上限
  162.         speed=9;                                                                                                                           //9檔                22-24                  22-24
  163.         else if(wendu>=t_max_1)                                                                                                   //大于上限
  164.         speed=10;                                                                                                                           //10檔                >25
  165. }
  166. /***************************************/
  167. void fengshan()
  168. {
  169.                 uchar m;
  170.         if(m<speed)                          //m值小于speed
  171.         fs=0;                                  //打開(kāi)風(fēng)扇
  172.         else if(m>=speed)          //否則
  173.         fs=1;                                  //關(guān)閉風(fēng)扇

  174.         m++;                                  //m加
  175.         if(m>=10)                          //m極愛(ài)到10,也就是2ms
  176.         m=0;
  177. }

  178. /**************************************/
  179. /**************************************/
  180. void display1()
  181. {
  182.         P0=0xff;//消隱
  183.         w1=0;//選通第一位數(shù)碼管
  184.         P0=table1[0];//顯示   L
  185.         delay(2);//延遲一會(huì)
  186.         w1=1;//關(guān)閉第一位數(shù)碼管
  187.         
  188.         P0=0xff;//第二位數(shù)碼管顯示方法及原理同上
  189.         w2=0;
  190.         P0=0xbf;//顯示  -
  191.         delay(2);
  192.         w2=1;
  193.         
  194.         P0=0xff;
  195.         w3=0;
  196.         P0=table[t_max/100];//顯示設(shè)置下限值的十位

  197.         delay(2);
  198.         w3=1;
  199.         
  200.         P0=0xff;
  201.         w4=0;
  202.         P0=table[t_max%100/10];//顯示設(shè)置下限值的個(gè)位
  203.         delay(2);
  204.         w4=1;               
  205. }
  206. /**************************************/
  207. void display2()
  208. {
  209.         P0=0xff;
  210.         w1=0;
  211.         P0=table1[1];//顯示  H
  212.         delay(2);
  213.         w1=1;
  214.         
  215.         P0=0xff;
  216.         w2=0;
  217.         P0=0xbf;//顯示  -
  218.         delay(2);
  219.         w2=1;
  220.         
  221.         P0=0xff;
  222.         w3=0;
  223.         P0=table[t_max_1/100];//顯示設(shè)置上限值得十位

  224.         delay(2);
  225.         w3=1;
  226.         
  227.         P0=0xff;
  228.         w4=0;
  229.         P0=table[t_max_1%100/10];//顯示設(shè)置上限值得個(gè)位
  230.         delay(2);
  231.         w4=1;               
  232. }

  233. /***************************************/
  234. void shezhi()
  235. {
  236.         if(flag_0==1)//flag_0==0時(shí),為正常顯示。等于1時(shí),為設(shè)置下限位值。等2時(shí)為設(shè)置上限為置
  237.         {
  238.                 if(key_jia==0)//當(dāng)設(shè)置下限位值時(shí),按下加鍵
  239.                 {
  240.                         delay(10);//延遲消抖
  241.                         if(key_jia==0)//確認(rèn)加鍵已按下
  242.                         {
  243.                                 t_max=t_max+10;//對(duì)下限位值每次加10
  244.                                 if(t_max>=t_max_1)                                //防止低溫度高于高溫度//如果下限位值設(shè)置時(shí)超過(guò)了上限位置
  245.                                         t_max=t_max_1-10;                                 //則讓下限位值-10
  246.                                 while(!key_jia);//松手檢測(cè)
  247.                         }
  248.                 }
  249.                 if(key_jian==0)//如果鍵鍵按下了,同上
  250.                 {
  251.                         delay(10);
  252.                         if(key_jian==0)
  253.                         {
  254.                                 t_max=t_max-10;
  255.                                 while(!key_jian);
  256.                         }
  257.                 }
  258.         }
  259.         if(flag_0==2)//對(duì)上限位設(shè)置時(shí)
  260.         {
  261.                 if(key_jia==0)
  262.                 {
  263.                         delay(10);
  264.                         if(key_jia==0)
  265.                         {
  266.                                 t_max_1=t_max_1+10;
  267.                                 while(!key_jia);
  268.                         }
  269.                 }
  270.                 if(key_jian==0)
  271.                 {
  272.                         delay(10);
  273.                         if(key_jian==0)
  274.                         {
  275.                                 t_max_1=t_max_1-10;
  276.                                 if(t_max_1<=t_max)                         //防止高溫度小于低溫度
  277.                                         t_max_1=t_max+10;
  278.                                 while(!key_jian);
  279.                         }
  280.                 }
  281.         }
  282. }
  283. void display()
  284. {
  285.                 if(flag_0==0)//flag_0==0時(shí),為正常顯示。等于1時(shí),為設(shè)置下限位值。等2時(shí)為設(shè)置上限為置
  286.                         display0();//正常顯示
  287.                 else if(flag_0==1)
  288.                         display1();//設(shè)置下限時(shí)的顯示
  289.                 else if(flag_0==2)
  290.                         display2();        //設(shè)置上限時(shí)的顯示
  291. }
  292. void main()
  293. {
  294.         while(1)
  295.         {

  296.         
  297.                 read_18b20();//讀取溫度傳感器中的數(shù)據(jù)
  298.                
  299.                 t=read_temp();//把讀出的數(shù)據(jù)賦給t
  300.                 if(t>=0&&t<=1250)  //溫度合法范圍,不在這個(gè)范圍就是沒(méi)有獲取到合適的值
  301.                 {
  302.                         wendu=t;
  303.                 }
  304.                 pro();//按鍵處理
  305.                 display();//顯示處理
  306.                 shezhi();//設(shè)置按鍵處理
  307.                 fengshan();//風(fēng)扇處理
  308.                 zi_dong();//自動(dòng)擋風(fēng)扇處理
  309.         }
  310. }
復(fù)制代碼

全部資料51hei下載地址:
小風(fēng)扇.7z (269.68 KB, 下載次數(shù): 36)

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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