1
收藏
微博
微信
复制链接

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

提问于
2024-12-03 11:37

温控风扇仿真(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:

  1. #include
  2. #include                                           //包含头文件
  3. #define uchar unsigned char
  4. #define uint unsigned int                           //宏定义
  5. ////////////////////
  6. sbit dj=P1^0;//电机控制端接口
  7. sbit DQ=P1^6;//温度传感器接口
  8. //////////按键接口/////////////////////////////////
  9. sbit key1=P3^5;//设置温度
  10. sbit key2=P3^6;//温度加
  11. sbit key3=P3^7;//温度减
  12. //////////////////////////////////////////////////////
  13. sbit w1=P2^4;
  14. sbit w2=P2^5;
  15. sbit w3=P2^6;
  16. sbit w4=P2^7;                                //数码管的位选端
  17. /////共阴数码管段选//////////////////////////////////////////////
  18. uchar table[22]=
  19. {0x3F,0x06,0x5B,0x4F,0x66,                //0 1 2 3 4
  20. 0x6D,0x7D,0x07,0x7F,0x6F,                //5 6 7 8 9
  21. 0x77,0x7C,0x39,0x5E,0x79,0x71,
  22. 0x40,0x38,0x76,0x00,0xff,0x37};//'-',L,H,灭,全亮,n         16-21
  23. uint wen_du;                                   //温度变量
  24. int shang,xia; //对比温度暂存变量
  25. uchar dang;//档位显示
  26. uchar speed;                        //速度变量
  27. uchar flag=0;                        //设置的变量
  28. bit start=0;                        //开始采集温度变量
  29. uchar d1,d2,d3;//显示数据暂存变量
  30. void delay(uint ms)                  //延时函数
  31. {
  32.         uchar x;
  33.         for(ms;ms>0;ms--)
  34.                 for(x=10;x>0;x--);
  35. }
  36. /***********ds18b20延迟子函数(晶振12MHz )*******/
  37. void delay_18B20(uint i)
  38. {
  39.         while(i--);
  40. }
  41. /**********ds18b20初始化函数**********************/
  42. void Init_DS18B20()
  43. {
  44.          uchar x=0;
  45.          DQ=1;          //DQ复位
  46.          delay_18B20(8);  //稍做延时
  47.          DQ=0;          //单片机将DQ拉低
  48.          delay_18B20(80); //精确延时 大于 480us
  49.          DQ=1;          //拉高总线
  50.          delay_18B20(14);
  51.          x=DQ;            //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
  52.          delay_18B20(20);
  53. }
  54. /***********ds18b20读一个字节**************/  
  55. uchar ReadOneChar()
  56. {
  57.         uchar i=0;
  58.         uchar dat=0;
  59.         for (i=8;i>0;i--)
  60.          {
  61.                   DQ=0; // 给脉冲信号
  62.                   dat>>=1;
  63.                   DQ=1; // 给脉冲信号
  64.                   if(DQ)
  65.                   dat|=0x80;
  66.                   delay_18B20(4);
  67.          }
  68.         return(dat);
  69. }
  70. /*************ds18b20写一个字节****************/  
  71. void WriteOneChar(uchar dat)
  72. {
  73.         uchar i=0;
  74.         for (i=8;i>0;i--)
  75.         {
  76.                   DQ=0;
  77.                 DQ=dat&0x01;
  78.             delay_18B20(5);
  79.                 DQ=1;
  80.             dat>>=1;
  81.         }
  82. }
  83. /**************读取ds18b20当前温度************/
  84. void ReadTemperature()
  85. {
  86.         uchar a=0;
  87.         uchar b=0;
  88.         uchar t=0;
  89.         Init_DS18B20();
  90.         WriteOneChar(0xCC);            // 跳过读序号列号的操作
  91.         WriteOneChar(0x44);         // 启动温度转换
  92. //        delay_18B20(100);       // this message is wery important
  93.         Init_DS18B20();
  94.         WriteOneChar(0xCC);         //跳过读序号列号的操作
  95.         WriteOneChar(0xBE);         //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  96. //        delay_18B20(100);
  97.         a=ReadOneChar();            //读取温度值低位
  98.         b=ReadOneChar();                   //读取温度值高位
  99.         wen_du=((b*256+a)>>4);    //当前采集温度值除16得实际温度值
  100. }
  101. void init()                        //定时器初始化函数
  102. {
  103.         TMOD=0x01;                //工作方式
  104.         TH0=0xff;
  105.         TL0=0x38;                //定时器赋初值
  106.         EA=1;                        //打开中断总开关
  107.         ET0=1;                        //打开定时器0中断允许开关
  108.         TR0=1;                        //打开定时器0定时开关
  109. }
  110. void init_dis()                //开机显示
  111. {
  112.         w1=0;w2=0;w3=0;w4=0;P0=table[16];
  113. }
  114. void display()//显示温度
  115. {
  116.         if(flag==0)
  117.         {
  118.                 if(speed>5) d1=speed-5;else d1=0;d2=wen_du/10;d3=wen_du%10;          //速度分10个档位,但是风扇在1 2 3 4 5档位时转不起来,所以从6开始为转动的1档
  119.         }
  120.         w1=0;P0=table[d1];delay(20); //第1位
  121.         P0=0x00;w1=1;
  122.          
  123.         w2=0;P0=table[16];delay(20);//第2位
  124.         P0=0x00;w2=1;

  125.         w3=0;P0=table[d2]; delay(20);//第3位
  126.         P0=0x00;w3=1;;

  127.         w4=0;P0=table[d3];delay(20);//第4位
  128.         P0=0x00;w4=1;
  129. }
  130. void zi_keyscan()//自动模式按键扫描函数
  131. {
  132.         if(key1==0)                          //设置键按下
  133.         {
  134.                 delay(10);                  //按键去抖
  135.                 if(key1==0)                  //再次判断
  136.                 {
  137.                         flag++;                  //设置状态加,等于1时是设置上限,等于2时是设置下限,等于0时退出设置
  138.                         TR0=0;                  //关闭定时器
  139.                         dj=0;                  //关闭风扇
  140.                         if(flag>=3)          //退出设置
  141.                         {
  142.                                 TR0=1;          //打开定时器,准备读取温度
  143.                                 flag=0;          //变量清零,退出设置
  144.                         }
  145.                 }
  146.                 while(key1==0) display();//按键释放,按键不松开,程序就停在这里,防止重复执行上面的程序,造成按键重复判断
  147.         }
  148.         if(flag==1)                                  //设置上限时
  149.         {
  150.                 d1=18;d2=shang/10;d3=shang%10;        //显示字母H
  151.                 if(key2==0)                                                //加键按下
  152.                 {
  153.                         delay(10);                                        //延时去抖
  154.                         if(key2==0)                                        //再次判断按键
  155.                         {
  156.                                 shang+=1;                                //上限值加
  157.                                 if(shang>=99)shang=99;        //最大加到99
  158.                         }
  159.                         while(key2==0) display();//松手检测
  160.                 }
  161.                 if(key3==0)                                                //减键按下
  162.                 {
  163.                         delay(10);                                   //延时去抖
  164.                         if(key3==0)                                         //再次判断
  165.                         {
  166.                                 shang-=1;                                           //上限减
  167.                                 if(shang<=xia+4)shang=xia+4;        //上限最小比下限大4
  168.                         }
  169.                         while(key3==0) display();//松手检测
  170.                 }               
  171.         }
  172.         if(flag==2)                                                        //设置下限
  173.         {
  174.                 d1=17;d2=xia/10;d3=xia%10;                //显示字母L
  175.                 if(key2==0)
  176.                 {                                                                //以下注释参考设置上限
  177.                         delay(10);
  178.                         if(key2==0)
  179.                         {
  180.                                 xia+=1;
  181.                                 if(xia>=shang-4)xia=shang-4;       
  182.                         }
  183.                         while(key2==0) display();//松手检测
  184.                 }
  185.                 if(key3==0)
  186.                 {
  187.                         delay(10);
  188.                         if(key3==0)
  189.                         {
  190.                                 xia-=1;
  191.                                 if(xia<=0)xia=0;       
  192.                         }
  193.                         while(key3==0) display();//松手检测
  194.                 }               
  195.         }
  196. }
  197. void zi_dong()//自动温控模式
  198. {
  199. //        此函数的目的是将上限和下限的差值平均为5份,每一份对应一个速度值                14-25
  200.         if(wen_du
  201.         speed=0;                                                                                                                           //速度0档
  202.         else if(wen_du>=xia&&(wen_du<(uint)((shang-xia)/4+xia)))                                           //温度大于下限并且小于(上限减去下限)除以4加下限
  203.         speed=6;                                                                                                                           //6档                14-16.75          14-15
  204.         else if((wen_du>=(uint)((float)(shang-xia)/4+xia))&&(wen_du<(uint)((float)(shang-xia)/2+xia)))           //温度大于 (上限减去下限)除以4加下限  并且小于(上限减去下限)除以2加下限
  205.         speed=7;                                                                                                                           //7档                16-19.5                  16-18
  206.         else if((wen_du>=(uint)(shang-xia)/2+xia)&&(wen_du<(uint)((float)((float)(shang-xia)/4)*3+xia)))   //温度大于 (上限减去下限)除以2加下限  并且小于(上限减去下限)除以4乘以3加下限
  207.         speed=8;                                                                                                                           //8档                19-22.25          19-21
  208.         else if((wen_du>=(uint)((float)((float)(shang-xia)/4)*3+xia))&&wen_du
  209.         speed=9;                                                                                                                           //9档                22-24                  22-24
  210.         else if(wen_du>=shang)                                                                                                   //大于上限
  211.         speed=10;                                                                                                                           //10档                >25
  212. }
  213. void main()                         //主函数
  214. {
  215.         uchar j;
  216.        
  217.         dj=0;                         //关闭风扇
  218.         shang=34;         //34  30
  219.         xia=30;                         //初始化上下限值
  220.         init_dis();                 //初始化显示
  221.         for(j=0;j<200;j++)           //读取温度,防止开机显示85
  222.         ReadTemperature();         
  223.         init();                                        //定时器初始化
  224.         while(1)                          //进入while循环,括号内为1,也就是死循环
  225.         {       
  226.                 if(start==1)          //开始读取温度
  227.                 {
  228.                         start=0;          //清零
  229.                         TR0=0;                  //关闭定时器
  230.                         dj=0;                  //关闭风扇
  231.                         ReadTemperature();//读取温度
  232.                         TR0=1;                  //打开定时器
  233.                         zi_dong();//自动温控模式
  234.                 }
  235.                 zi_keyscan();//按键扫描函数
  236.                 display();         //显示函数
  237.         }
  238. }
  239. //以下是控制PWM的
  240. void time0() interrupt 1         //定时器服务函数
  241. {
  242.         uchar m;
  243.         uint n;
  244.         TH0=0xff;          //200us初值
  245.         TL0=0x38;

  246.         if(m
  247.         dj=1;                                  //打开风扇
  248.         else if(m>=speed)          //否则
  249.         dj=0;                                  //关闭风扇

  250.         m++;                                  //m加
  251.         if(m>=10)                          //m极爱到10,也就是2ms
  252.         m=0;

  253.         n++;                                  //200us  n加一次
  254.         if(n>=10000)                  //n加到10000  也就是2秒
  255.         {
  256.                 n=0;
  257.                 start=1;                  //启动一次温度测量
  258.         }
  259. }
复制代码


温控风扇.zip (715.49 KB, 下载次数: 41)
2021-5-19 15:20 上传
点击文件名下载附件
下载积分: 黑币 -5


收藏 5 0 1
粉丝
0
关注
0
主题
3
请问我仿真完之后只在第一位显示8怎么处理啊
0

回答于 · 2024-12-03 17:02