国产免费AV|泡泡玛特欧洲总部将设在伦敦|中文天堂网www新版资源在线|一本久道综合在线中文|国精产品一二三产区的使用方法|香蕉鱼在线观看|www.27eee

ELEOK

標題: 51單片機+三極管驅動的溫控小風扇代碼與Proteus仿真原理圖 [打印本頁]

作者: eng    時間: 2021-6-14 02:55
標題: 51單片機+三極管驅動的溫控小風扇代碼與Proteus仿真原理圖
系統主要設計了一個基于單片機的風扇溫控儀,以單片機和DS18B20傳感器為核心,具有溫度顯示和控制風扇轉速功能DS18B20傳感器,將檢測到的溫度轉化為數字信號,單片機對輸入的數字信號進行分析處理,當溫度高于上限值時,風扇全速旋轉;當溫度低于下限時,風扇停轉;當溫度處于上限值與下限之間時,風扇轉速越慢,。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


原理圖:


部分源碼:完整源碼請下載附件
  1. /***********************18b20初始化函數*****************************/
  2. void init_18b20()
  3. {
  4.         bit q;
  5.         dq = 1;                                //把總線拿高
  6.         delay_uint(1);            //15us
  7.         dq = 0;                                //給復位脈沖
  8.         delay_uint(80);                //750us
  9.         dq = 1;                                //把總線拿高 等待
  10.         delay_uint(10);                //110us
  11.         q = dq;                                //讀取18b20初始化信號
  12.         delay_uint(20);                //200us
  13.         dq = 1;                                //把總線拿高 釋放總線
  14. }

  15. /*************寫18b20內的數據***************/
  16. void write_18b20(uchar dat)
  17. {
  18.         uchar i;
  19.         for(i=0;i<8;i++)
  20.         {                                         //寫數據是低位開始
  21.                 dq = 0;                         //把總線拿低寫時間隙開始
  22.                 dq = dat & 0x01; //向18b20總線寫數據了
  23.                 delay_uint(5);         // 60us
  24.                 dq = 1;                         //釋放總線
  25.                 dat >>= 1;
  26.         }        
  27. }

  28. /*************讀取18b20內的數據***************/
  29. uchar read_18b20()
  30. {
  31.         uchar i,wendu;
  32.         for(i=0;i<8;i++)
  33.         {
  34.                 dq = 0;                         //把總線拿低讀時間隙開始
  35.                 wendu >>= 1;         //讀數據是低位開始
  36.                 dq = 1;                         //釋放總線
  37.                 if(dq == 1)                 //開始讀寫數據
  38.                         wendu |= 0x80;
  39.                 delay_uint(5);         //60us        讀一個時間隙最少要保持60us的時間
  40.         }
  41.         return wendu;                 //返回數據
  42. }

  43. /*************讀取溫度的值 讀出來的是小數***************/
  44. uint read_temp()
  45. {
  46.         uint wendu;
  47.         uchar low;                           //在讀取溫度的時候如果中斷的太頻繁了,就應該把中斷給關了,否則會影響到18b20的時序
  48.         init_18b20();                   //初始化18b20
  49.         write_18b20(0xcc);           //跳過64位ROM
  50.         write_18b20(0x44);           //啟動一次溫度轉換命令
  51.         delay_uint(50);                   //500us

  52.         init_18b20();                   //初始化18b20
  53.         
  54.         write_18b20(0xcc);           //跳過64位ROM
  55.         write_18b20(0xbe);           //發出讀取暫存器命令
  56.         
  57.         EA = 0;
  58.         low = read_18b20();           //讀溫度低字節
  59.         wendu = read_18b20();  //讀溫度高字節
  60.         EA = 1;
  61.         wendu <<= 8;                   //把溫度的高位左移8位
  62.         wendu |= low;                   //把讀出的溫度低位放到value的低八位中
  63.         wendu *= 0.625;               //轉換到溫度值 小數
  64.         return wendu;                   //返回讀出的溫度 帶小數
  65. }
  66. void display0()
  67. {
  68.         P0=0xff;//消隱
  69.         w1=0;                                //選通第一位數碼管
  70.         if(speed>5)                        //如果speed的值>5則檔位顯示speed-5,比如speed=6,則顯示1檔
  71.         P0=table[speed-5];//顯示檔位
  72.         else                                //否則speed的值如果小于5,則顯示0檔
  73.         P0=table[0];//顯示檔位        
  74.         delay(2);//延遲一會
  75.         w1=1;//關閉第一位數碼管
  76.                         
  77.         P0=0xff;//第二位數碼管的顯示原理及方法同上
  78.         w2=0;
  79.         P0=0xbf;//顯示-
  80.         delay(2);
  81.         w2=1;
  82.         
  83.         P0=0xff;
  84.         w3=0;
  85.         P0=table[wendu/100];//顯示溫度十位

  86.         delay(2);
  87.         w3=1;
  88.         
  89.         P0=0xff;
  90.         w4=0;
  91.         P0=table[wendu%100/10];//顯示溫度各位
  92.         delay(2);
  93.         w4=1;        
  94. }
  95. void zi_dong()//自動溫控模式
  96. {
  97. //        此函數的目的是將上限和下限的差值平均為5份,每一份對應一個速度值                14-25
  98.         if(wendu<t_max)                                                                                                                   //溫度小于下限
  99.         speed=0;                                                                                                                           //速度0檔
  100.         else if(wendu>=t_max&&(wendu<(uint)((t_max_1-t_max)/4+t_max)))                                           //溫度大于下限并且小于(上限減去下限)除以4加下限
  101.         speed=6;                                                                                                                           //6檔                14-16.75          14-15
  102.         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加下限
  103.         speed=7;                                                                                                                           //7檔                16-19.5                  16-18
  104.         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加下限
  105.         speed=8;                                                                                                                           //8檔                19-22.25          19-21
  106.         else if((wendu>=(uint)((float)((float)(t_max_1-t_max)/4)*3+t_max))&&wendu<t_max_1)                                   //溫度大于 (上限減去下限)除以4乘以3加下限  并且小于上限
  107.         speed=9;                                                                                                                           //9檔                22-24                  22-24
  108.         else if(wendu>=t_max_1)                                                                                                   //大于上限
  109.         speed=10;                                                                                                                           //10檔                >25
  110. }
  111. /***************************************/
  112. void fengshan()
  113. {
  114.                 uchar m;
  115.         if(m<speed)                          //m值小于speed
  116.         fs=0;                                  //打開風扇
  117.         else if(m>=speed)          //否則
  118.         fs=1;                                  //關閉風扇

  119.         m++;                                  //m加
  120.         if(m>=10)                          //m極愛到10,也就是2ms
  121.         m=0;
  122. }

  123. /**************************************/
  124. /**************************************/
  125. void display1()
  126. {
  127.         P0=0xff;//消隱
  128.         w1=0;//選通第一位數碼管
  129.         P0=table1[0];//顯示   L
  130.         delay(2);//延遲一會
  131.         w1=1;//關閉第一位數碼管
  132.         
  133.         P0=0xff;//第二位數碼管顯示方法及原理同上
  134.         w2=0;
  135.         P0=0xbf;//顯示  -
  136.         delay(2);
  137.         w2=1;
  138.         
  139.         P0=0xff;
  140.         w3=0;
  141.         P0=table[t_max/100];//顯示設置下限值的十位

  142.         delay(2);
  143.         w3=1;
  144.         
  145.         P0=0xff;
  146.         w4=0;
  147.         P0=table[t_max%100/10];//顯示設置下限值的個位
  148.         delay(2);
  149.         w4=1;               
  150. }
  151. /**************************************/
  152. void display2()
  153. {
  154.         P0=0xff;
  155.         w1=0;
  156.         P0=table1[1];//顯示  H
  157.         delay(2);
  158.         w1=1;
  159.         
  160.         P0=0xff;
  161.         w2=0;
  162.         P0=0xbf;//顯示  -
  163.         delay(2);
  164.         w2=1;
  165.         
  166.         P0=0xff;
  167.         w3=0;
  168.         P0=table[t_max_1/100];//顯示設置上限值得十位

  169.         delay(2);
  170.         w3=1;
  171.         
  172.         P0=0xff;
  173.         w4=0;
  174.         P0=table[t_max_1%100/10];//顯示設置上限值得個位
  175.         delay(2);
  176.         w4=1;               
  177. }

  178. /***************************************/
  179. void shezhi()
  180. {
  181.         if(flag_0==1)//flag_0==0時,為正常顯示。等于1時,為設置下限位值。等2時為設置上限為置
  182.         {
  183.                 if(key_jia==0)//當設置下限位值時,按下加鍵
  184.                 {
  185.                         delay(10);//延遲消抖
  186.                         if(key_jia==0)//確認加鍵已按下
  187.                         {
  188.                                 t_max=t_max+10;//對下限位值每次加10
  189.                                 if(t_max>=t_max_1)                                //防止低溫度高于高溫度//如果下限位值設置時超過了上限位置
  190.                                         t_max=t_max_1-10;                                 //則讓下限位值-10
  191.                                 while(!key_jia);//松手檢測
  192.                         }
  193.                 }
  194.                 if(key_jian==0)//如果鍵鍵按下了,同上
  195.                 {
  196.                         delay(10);
  197.                         if(key_jian==0)
  198.                         {
  199.                                 t_max=t_max-10;
  200.                                 while(!key_jian);
  201.                         }
  202.                 }
  203.         }
  204.         if(flag_0==2)//對上限位設置時
  205.         {
  206.                 if(key_jia==0)
  207.                 {
  208.                         delay(10);
  209.                         if(key_jia==0)
  210.                         {
  211.                                 t_max_1=t_max_1+10;
  212.                                 while(!key_jia);
  213.                         }
  214.                 }
  215.                 if(key_jian==0)
  216.                 {
  217.                         delay(10);
  218.                         if(key_jian==0)
  219.                         {
  220.                                 t_max_1=t_max_1-10;
  221.                                 if(t_max_1<=t_max)                         //防止高溫度小于低溫度
  222.                                         t_max_1=t_max+10;
  223.                                 while(!key_jian);
  224.                         }
  225.                 }
  226.         }
  227. }
  228. void display()
  229. {
  230.                 if(flag_0==0)//flag_0==0時,為正常顯示。等于1時,為設置下限位值。等2時為設置上限為置
  231.                         display0();//正常顯示
  232.                 else if(flag_0==1)
  233.                         display1();//設置下限時的顯示
  234.                 else if(flag_0==2)
  235.                         display2();        //設置上限時的顯示
  236. }
  237. void main()
  238. {
  239.         while(1)
  240.         {

  241.         
  242.                 read_18b20();//讀取溫度傳感器中的數據
  243.                
  244.                 t=read_temp();//把讀出的數據賦給t
  245.                 if(t>=0&&t<=1250)  //溫度合法范圍,不在這個范圍就是沒有獲取到合適的值
  246.                 {
  247.                         wendu=t;
  248.                 }
  249.                 pro();//按鍵處理
  250.                 display();//顯示處理
  251.                 shezhi();//設置按鍵處理
  252.                 fengshan();//風扇處理
  253.                 zi_dong();//自動擋風扇處理
  254.         }
  255. }
復制代碼
完整源碼和proteus仿真文件: 小風扇.zip (209.04 KB, 售價: 5 E幣)






歡迎光臨 ELEOK (http://m.afoofa.cn/) Powered by Discuz! X5.0