找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5385|回复: 1
收起左侧

单片机温控风扇Proteus仿真+代码

[复制链接]
ID:537864 发表于 2019-5-14 12:45 | 显示全部楼层 |阅读模式
温控风扇仿真图
0.png

单片机源程序如下:
  1. #include<reg52.h>                                 //头文件
  2. #include<intrins.h>
  3. #include "DS18b20.H"
  4. #include "eeprom52.h"
  5. #include "Nixie tube.h"

  6. #define uchar unsigned char                 //宏定义
  7. #define uint unsigned int

  8. uchar code ss[]=                             //第一个数码管数组没有带小数点
  9. {
  10.   0xc0,0xf9,0xa4,0xb0,0x99,
  11.   0x92,0x82,0xf8,0x80,0x90
  12. };                           
  13. uchar code ss1[]=                            //这个数码管数组带小数点
  14. {
  15.   0x40,0x79,0x24,0x30,0x19,
  16.   0x12,0x02,0x78,0x00,0x10,
  17.   0xc7,0x89,0xbf               //0xc7=L   0x89=H   0xbf=- 负号
  18. };                            //0-9为带小数点的
  19. uchar ms;                      //定义一个计数变量
  20. sbit key1=P3^4;
  21. sbit key2=P3^5;
  22. sbit key3=P3^3;                             //按键控制 P3^4设置切换  3.5上下限加 3.6上下限减
  23. sbit led_0=P1^0;                            //上限温度报警灯
  24. sbit led_2=P1^2;                            //下限温度报警灯
  25. char H,L,T_ms;                              //用于设置上下限度  上下限度与要比较的数据类型最好相同                T_ms用于PWM调节
  26. uchar flag,PWM_ON;                          //PWM_ON是风扇开关标志位
  27. sbit Fan=P1^6;                              //风扇端口定义
  28. bit voled=0;                                //voled用来判断风扇软启动
  29. int temp;                                   //存储读出来的温度,与H,L上下限度数据类型相同

  30. void delay(uint T)                                    //短延时
  31. {                                          
  32.         while(T--);
  33. }

  34. void display()                                   //显示函数
  35. {   
  36.      if(flag==0&&temp>=0)                  //温度为正数时执行
  37.                 {
  38.          if(temp>999) Nixietube(ss[temp/1000%10],ss[temp/100%10],ss1[temp/10%10],ss[temp%10]);
  39.                  if(temp>99)  Nixietube(0xff,ss[temp/100%10],ss1[temp/10%10],ss[temp%10]);
  40.                  if(temp<99&&temp/100%10<=0)  Nixietube(0xff,0xff,ss1[temp/10%10],ss[temp%10]);

  41.             }
  42.          if(flag==0&&temp<0)                   //温度为负数时
  43.                 {
  44.          if(temp*-1/100%10<=0) Nixietube(0xff,ss1[12],ss1[temp*-1/10%10],ss[temp*-1%10]);
  45.                  if(temp*-1/100%10>0)  Nixietube(ss1[12],ss[temp*-1/100%10],ss1[temp*-1/10%10],ss[temp*-1%10]);
  46.             }
  47.      if(flag==1)                          //flag==0显示温度  =1 显示上限   =2 显示下限
  48.                 {
  49.          if(H>99)          Nixietube(ss1[11],ss[H/100],ss[H%100/10],ss[H%10]);        //温度范围是125~-55 ,当上限值大于99时执行  
  50.                  if(H>=10&&H<=99)  Nixietube(ss1[11],0xff,ss[H/10],ss[H%10]);                 //当上限值大于12小于99时执行  不显示最高位
  51.                  if(H<10&&H>=0)    Nixietube(ss1[11],0xff,0xff,ss[H%10]);                     //不显示百位 十位
  52.                  if(H<0&&H>=-9)    Nixietube(ss1[11],0xff,ss1[12],ss[H*-1%10]);               //设置的为负数且介于0~-9之间时执行  不显示十位
  53.          if(H<0&&H<-9)     Nixietube(ss1[11],ss1[12],ss[H*-1%100/10],ss[H*-1%10]);          //最低可以到55                           
  54.         }
  55.                        
  56.          if(flag==2)   //同上                                                
  57.            {
  58.          if(L>99)          Nixietube(ss1[10],ss[L/100],ss[L%100/10],ss[L%10]);
  59.              if(L>=10&&L<=99)  Nixietube(ss1[10],0xff,ss[L/10],ss[L%10]);
  60.              if(L<10&&L>=0)    Nixietube(ss1[10],0xff,0xff,ss[L%10]);
  61.          if(L<0&&L>=-9)  Nixietube(ss1[10],0xff,ss1[12],ss[L*-1%10]);
  62.          if(L<0&&L<-9)  Nixietube(ss1[10],ss1[12],ss[L*-1%100/10],ss[L*-1%10]);         
  63.                          
  64.        }       
  65.   }
  66. void key()                              //按键处理
  67. {       
  68. if(!key1)                               //设置上限
  69. {
  70.     delay(500);
  71.         if(!key1)
  72.         {
  73.       while(!key1);//display();
  74.       if(flag==1)
  75.                   {
  76.                   if(H<125)H++;
  77.                   SectorErase(0x2000);          //每修改一次上下限数据就写进EEROM
  78.                   byte_write(0x2000,H);
  79.         }
  80.           else if(flag==2)
  81.                 {
  82.           if(L<H-1) L++;                //原则是下限不超过上限
  83.                   SectorErase(0x2200);
  84.                   byte_write(0x2200,L);
  85.         }       
  86.     }
  87. }

  88. if(!key2)                              //设置下限
  89. {
  90.     delay(500);
  91.         if(!key2)
  92.          {
  93.         while(!key2);//display();
  94.                 if(flag==1)
  95.                     {
  96.                     if(H>L+1)  H--;             //原则上限不低于下限
  97.                 SectorErase(0x2000);        //每修改一次上下限数据就写进EEROM
  98.                     byte_write(0x2000,H);
  99.           }
  100.                 else if        (flag==2)
  101.                    {
  102.                         if(L>-55)L--;
  103.                         SectorErase(0x2200);
  104.                         byte_write(0x2200,L);
  105.            }       
  106.      }
  107. }

  108. if(!key3)                             //设置上限下限切换按键
  109. {
  110.          delay(1000);
  111.          if(!key3)
  112.                 {
  113.                   while(!key3);
  114.           flag=(flag+1)%3;                       
  115.         }
  116. }
  117. }
  118. void alarm()                          //报警
  119. {
  120.        
  121. if(temp/10>=H)                         //上限,当测得的值,大于等于设定值得时候,
  122.   {
  123.         led_0=0;  PWM_ON=20;              //上限警示灯亮,风扇PWM调节最大
  124.   }
  125. else
  126.    {
  127.         led_0=1;
  128.    }

  129. if((L<=temp/10)&&(temp/10<=H))             //当温度介于上下限之间时,风扇弱风转动
  130. {
  131.            PWM_ON=4;
  132. }

  133. if(temp/10<=L)                                    //如果温度在下限以下,那么风扇停止转动  下限指示灯亮
  134. {
  135.     led_2=0;  PWM_ON=0; voled=0;
  136.         Fan=1;
  137. }
  138. else
  139.   {
  140.       led_2=1;
  141.   }

  142. }
  143. void main()                           //主函数         
  144. {  
  145.         do
  146.          {
  147.                 temp=Temper();
  148.          }
  149.    while(temp==850);                   //因为DS18B20上电之后会读出来850,但不是温度值,所以等待读出温度值      
  150.         H=byte_read(0x2000);
  151.         L=byte_read(0x2200);                //读EEROM里面的数据
  152.         if((H>99)||(L>99)||(L>=H))          //如果数据不对,赋予初始值
  153.          {
  154.                 H=35;
  155.                 L=16;                    
  156.          }  
  157.         TMOD=0x21;                          //使用两个定时器,0工作在方式1,用来定时读取与显示温度  1工作在方式2,用来模拟PWM
  158.         TH0=(65536-10000)/256;     
  159.         TL0=(65536-10000)%256;              //装入初始值,一次定时10MS
  160.     TH1 = 0x06;
  161.     TL1 = 0x06;                         //一次定时0.25ms
  162.         EA=1;                               //  打开总中断
  163.         ET0=1;                              //打开定时器0中断      
  164.         TR0=1;                              //开始启动定时器0
  165.         ET1=1;                              //打开定时器1中断
  166.         TR1=1;                              //开始启动定时器1
  167.                
  168. while(1)                              
  169.         {
  170.         display();                        //消影问题,仿真里对中断里的显示函数只执行一次,不能达到一直显示
  171.                                               //所以,在仿真时解除屏蔽此语句,屏蔽中断里的display();
  172.                 key();               
  173.                 alarm();

  174.         }
  175. }

  176. void UART_1() interrupt 1
  177. {
  178.         TH0=(65536-10000)/256;
  179.         TL0=(65536-10000)%256;;           //一次定时10MS   
  180.         ms++;
  181.         //display();                      //显示函数    因为数码管存在消影问题,如果在电路上,不屏蔽此句子,如果需要仿真,屏蔽此句子,使用主函数里的显示函数
  182.         if(ms>100)                        //每1秒刷新一次温度数据
  183.         {
  184.          ms=0;
  185.          temp=Temper();                   //读温度
  186.         }
  187. }

  188. void T1_time() interrupt 3
  189. {
  190.   TH1 = 0x06;
  191.   TL1 = 0x06;                                             //一次定时0.25ms
  192.   T_ms++;
  193. if(voled==0&&temp/10>L)                     //软启动,因为电压太低,风扇不易启动/由温度低于下限的不启动到启动,电压太低也启动不了
  194.   {
  195.      voled=1;
  196.          Fan=0;
  197.          delay(3200);
  198.          Fan=1;
  199.   }       
  200. if(T_ms<PWM_ON)                 
  201.   {
  202.          Fan=0;
  203.   }
  204. else                                         
  205.   {
  206.          Fan=1;
  207.   }
  208. if(T_ms>20)
  209. {
  210.     T_ms=0;
  211. }
  212. }
复制代码

所有资料51hei提供下载:
Desktop1.zip (334.04 KB, 下载次数: 86)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:888341 发表于 2021-4-1 16:09 | 显示全部楼层
怎么感觉没用?测温测不准 ?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表