找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2801|回复: 12
打印 上一主题 下一主题
收起左侧

51单片机温度控制系统(温度控制部分有问题,求大佬解答)

[复制链接]
跳转到指定楼层
楼主
ID:902047 发表于 2021-4-27 16:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
采用ds18b20温度传感器,将实时温度与预设温度进行比较,若实时温度低于预设温度,则控制电阻丝进行加热,若实时温度高于预设温度,则停止电阻丝加热,系统温度在50~100摄氏度范围内可调,温度控制精度±0.5摄氏度。
我主程序的最后用if语句将实时温度与预设温度比较,但是用proteus仿真后,P3.1口一直输出低电平,发现if语句好像没有起作用,每次都直接执行else语句。下面是我的程序和proteus电路图。


单片机源程序如下:
  1. #include"reg51.h"
  2. #define uint unsigned int
  3. #define uchar unsigned char

  4. uchar code smg_duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数码管段选定义
  5. uchar code smg_duan1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//数码管段选定义(小数点)
  6. uchar code smg_wei[]={0xf7,0xfb,0xfd,0xfe};//数码管位选定义

  7. sbit key1=P1^0;//输入设定温度50度
  8. sbit key2=P1^1;//输入设定温度75度
  9. sbit key3=P1^2;//输入设定温度100度
  10. sbit key4=P1^3;//增加2度
  11. sbit key5=P1^4;//减少2度
  12. sbit key6=P1^5;//增加0.5度
  13. sbit key7=P1^6;//减少0.5度
  14. sbit key8=P1^7;//确认键
  15. float setH=0;//预设温度上限
  16. float setL=0;//预设温度下限
  17. uint bkey;
  18. sbit DQ=P3^0;//18b20 I/O口定义
  19. sbit jiare=P3^1;//加热电阻丝I/O口定义
  20. /***********1ms延时函数********/
  21. void delay_1ms(uint i)
  22. {
  23.      while(i--);
  24. }

  25. /***********小延时函数**********/
  26. void delay_small(uint q)
  27. {
  28.       while(q--);
  29. }

  30. /**********18b20初始化函数*******/
  31. void Init_18b20()
  32. {
  33.      bit q;
  34.          DQ=1;//把总线拉高
  35.          delay_small(1);//15us
  36.          DQ=0;//给复位脉冲
  37.          delay_small(80);//750us
  38.          DQ=1;//把总线拉高,等待
  39.          delay_small(10);//110us
  40.          q=DQ;//读取18b20初始化信号
  41.          delay_small(20);//200us
  42.          DQ=1;//把总线拉高,释放总线


  43. }

  44. /**********写18b20数据******/
  45. void write_18b20(uchar dat)
  46. {
  47.      uchar i;
  48.          for(i=0;i<8;i++)
  49.          {
  50.             DQ=0;
  51.                 DQ=dat&0x01;//向18b20总线写数据
  52.                 delay_small(5);//60us
  53.                 DQ=1;//释放总线
  54.                 dat>>=1;
  55.          }
  56. }

  57. /*********读18b20数据******/
  58. uchar read_18b20()
  59. {
  60.      uchar i,r_dat;
  61.          for(i=0;i<8;i++)
  62.          {
  63.             DQ=0;
  64.                 r_dat>>=1;//读数据从低位开始
  65.                 DQ=1;//释放总线
  66.                 if(DQ==1)
  67.                   r_dat|=0x80;
  68.                 delay_small(5);//60us
  69.          }
  70.          return r_dat;//返回数据
  71. }

  72. /**********读取实时温度数值*******/
  73. uint read_Tem()
  74. {
  75.      uint r_high;
  76.          uchar r_low;
  77.          Init_18b20();//初始化18b20
  78.          write_18b20(0xcc);//跳过64位ROM
  79.          write_18b20(0x44);//启动一次温度转换命令
  80.          delay_small(50);//500us
  81.          Init_18b20();//初始化18b20
  82.          write_18b20(0xcc);//跳过64位ROM
  83.          write_18b20(0xbe);//发出读取暂存器命令
  84.          EA=0;//关总中断
  85.          r_low=read_18b20();//读温度低字节
  86.          r_high=read_18b20();//读温度高字节
  87.          EA=1;//开总中断
  88.          r_high<<=8;//把温度的高字节左移8位
  89.          r_high|=r_low;//把读出的温度低位放到r_high的低八位中
  90.          r_high*=0.625;//转换到温度值小数
  91.          return r_high;//返回读出的温度


  92. }

  93. /**********数码管显示温度函数(实时显示)******/
  94. void DisplayTem(uint temperature)
  95. {
  96.         uint a,b;
  97.         P0=0x00;
  98.         P2=smg_wei[0];//位选小数位
  99.         P0=smg_duan[temperature%10];//段选显示小数位
  100.         delay_1ms(2300);
  101.         P0=0x00;
  102.         P2=smg_wei[1];//位选个位
  103.         P0=smg_duan1[temperature/10%10];//段选显示个位
  104.         delay_1ms(2300);
  105.         P0=0x00;
  106.         P2=smg_wei[2];//位选十位
  107.         P0=smg_duan[temperature/100%10];//段选显示十位
  108.         delay_1ms(2300);
  109.         P0=0x00;
  110.         b=temperature/1000%10;
  111.         if(b==0)
  112.         {
  113.            a=0;
  114.         }
  115.         else
  116.         {
  117.            a=1;
  118.         }
  119.         switch(a)
  120.         {
  121.            case(0):break;
  122.            case(1):P2=smg_wei[3];//位选百位
  123.                    P0=smg_duan[temperature/1000%10];//段选显示百位
  124.                    delay_1ms(2300);
  125.                    P0=0x00;
  126.                            break;
  127.         }
  128.         

  129. }

  130. void keyscan()
  131. {
  132.    bkey=0;
  133.   if(!key1)
  134.   {
  135.      delay_1ms(3000);
  136.          if(!key1)
  137.          bkey=1;
  138.   }
  139.   if(!key2)
  140.   {
  141.      delay_1ms(3000);
  142.          if(!key2)
  143.          bkey=2;
  144.   }
  145.   if(!key3)
  146.   {
  147.      delay_1ms(3000);
  148.          if(!key3)
  149.          bkey=3;
  150.   }
  151.   if(!key4)
  152.   {
  153.      delay_1ms(8000);
  154.          if(!key4)
  155.          bkey=4;
  156.   }
  157.   if(!key5)
  158.   {
  159.      delay_1ms(8000);
  160.          if(!key5)
  161.          bkey=5;
  162.   }
  163.   if(!key6)
  164.   {
  165.      delay_1ms(8000);
  166.          if(!key6)
  167.          bkey=6;
  168.   }
  169.   if(!key7)
  170.   {
  171.      delay_1ms(8000);
  172.          if(!key7)
  173.          bkey=7;
  174.   }
  175.   if(!key8)
  176.   {
  177.      delay_1ms(8000);
  178.          if(!key8)
  179.          bkey=8;
  180.   }
  181. }

  182. /***********数码管显示函数(按键显示)******/
  183. void displaytem1(float temperature1)
  184. {
  185.     do
  186.    {
  187.         uint b;
  188.         float c;
  189.         P0=0x00;
  190.         P2=smg_wei[0];//位选小数位
  191.         c=temperature1*10;
  192.         P0=smg_duan[(int)c/1%10];//段选显示小数位
  193.         delay_1ms(1325);
  194.         P0=0x00;
  195.         P2=smg_wei[1];//位选个位
  196.         P0=smg_duan1[(int)temperature1/1%10];//段选显示个位
  197.         delay_1ms(1325);
  198.         P0=0x00;
  199.         P2=smg_wei[2];//位选十位
  200.         P0=smg_duan[(int)temperature1/10%10];//段选显示十位
  201.         delay_1ms(1325);
  202.         P0=0x00;
  203.         b=(int)temperature1/100%10;
  204.         switch(b)
  205.         {
  206.            case(0):break;
  207.            case(1):P2=smg_wei[3];//位选百位
  208.                    P0=smg_duan[1];//段选显示百位
  209.                    delay_1ms(1325);
  210.                    P0=0x00;
  211.                            break;
  212.         }
  213.         keyscan();
  214.    }
  215.    while(bkey==0);
  216. }


  217. void main()
  218. {
  219.    uint temperature;
  220.    jiare=0;
  221.    do
  222.    {
  223.     keyscan();
  224.         switch(bkey)
  225.     {
  226.       case(0):break;
  227.           case(1):setH=50.0;
  228.                   setL=50.0;
  229.                           displaytem1(50.0);
  230.                           break;
  231.           case(2):setH=75.0;
  232.                   setL=75.0;
  233.                           displaytem1(75.0);
  234.                           break;
  235.           case(3):setH=100.0;
  236.                   setL=100.0;
  237.                           displaytem1(100.0);
  238.                           break;
  239.           case(4):setH=setH+2.0;
  240.                   setL=setL+2.0;
  241.                           displaytem1(setH);
  242.                           break;
  243.           case(5):setH=setH-2.0;
  244.                           setL=setL-2.0;
  245.                           displaytem1(setH);
  246.                           break;
  247.           case(6):setH=setH+0.5;
  248.                   setL=setL+0.5;
  249.                           displaytem1(setH);
  250.                           break;
  251.           case(7):setH=setH-0.5;
  252.                   setL=setL-0.5;
  253.                           displaytem1(setH);
  254.                           break;
  255.           case(8):P0=0x00;
  256.                   break;

  257.     }
  258.    }
  259.    while(bkey<8);
  260.    while(1)
  261.    {
  262.      temperature=read_Tem();//读出温度的值
  263.      DisplayTem(temperature);//显示实时温度
  264.      if(temperature<setH)
  265.     {
  266.         jiare=1;
  267.     }
  268.      else
  269.     {
  270.       jiare=0;
  271.     }

  272.    }
  273.                      
  274. }
复制代码



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2021-4-27 17:49 | 只看该作者
把这个程序稍改一下即可用于温度控制 DS18B20温度上下限报警 仿真示例.zip (214.7 KB, 下载次数: 50)

回复

使用道具 举报

板凳
ID:213173 发表于 2021-4-27 18:32 | 只看该作者
这个程序可能更适合你,只要把LCD显示改为数码管显示即可 ds18b20 0~120度PWM恒温控制LCD显示 仿真.zip (161.08 KB, 下载次数: 49)



回复

使用道具 举报

地板
ID:902047 发表于 2021-4-27 20:17 | 只看该作者
wulin 发表于 2021-4-27 17:49
把这个程序稍改一下即可用于温度控制

谢谢,大佬,有时间的话再帮我看看我的程序应该怎么改一下就可以用吧,
回复

使用道具 举报

5#
ID:569384 发表于 2021-4-28 10:55 | 只看该作者
temperature有数值吗?
回复

使用道具 举报

6#
ID:902047 发表于 2021-4-28 11:12 | 只看该作者
haokey 发表于 2021-4-28 10:55
temperature有数值吗?

我把第282行的if语句改成过:if(temperature),结果P3.1口可以正常输出高电平,这应该就说明temperature有数值吧
回复

使用道具 举报

7#
ID:844772 发表于 2021-4-28 11:57 | 只看该作者
r_high*=0.625;//转换到温度值小数
没太仔细看,但我觉得应该0.0625,你看一下手册。
回复

使用道具 举报

8#
ID:569384 发表于 2021-4-28 17:23 | 只看该作者
各位都是大佬 发表于 2021-4-28 11:12
我把第282行的if语句改成过:if(temperature),结果P3.1口可以正常输出高电平,这应该就说明temperatur ...

那再数码管把temperature和setH都显示出来看看就知道了嘛。
回复

使用道具 举报

9#
ID:902047 发表于 2021-4-28 19:48 | 只看该作者
glinfei 发表于 2021-4-28 11:57
r_high*=0.625;//转换到温度值小数
没太仔细看,但我觉得应该0.0625,你看一下手册。

谢谢,我改成0.0625之后,数码管显示的实时温度刚好是ds18b20温度数值的十分之一。我突然发现如果预设温度为56的话,数码管显示的实时温度低于5.6则P3.1口输出高电平,高于5.6度则输出低电平。我把第282行的语句改为if(temperature/10<setH)后就实现正常功能了,但是我还是不太清楚为什么改成这样就好了
回复

使用道具 举报

10#
ID:902047 发表于 2021-4-28 19:51 | 只看该作者
haokey 发表于 2021-4-28 17:23
那再数码管把temperature和setH都显示出来看看就知道了嘛。

谢谢,我把第282行的语句改成if(temperature/10<setH)后就实现温度控制的正常功能了,但是我不太清楚为什么这样就好了
回复

使用道具 举报

11#
ID:844772 发表于 2021-4-28 20:57 | 只看该作者
各位都是大佬 发表于 2021-4-28 19:48
谢谢,我改成0.0625之后,数码管显示的实时温度刚好是ds18b20温度数值的十分之一。我突然发现如果预设温 ...

这就不该再问了,你temperature变量显然存到了小数后一位,比如56.1度,就是561了也就是放大了10倍,所以我建议你用0.0625。你看看void DisplayTem(uint temperature) 函数,它取了temperature个为作为小数位显示的。
回复

使用道具 举报

12#
ID:902047 发表于 2021-4-29 09:03 | 只看该作者
glinfei 发表于 2021-4-28 20:57
这就不该再问了,你temperature变量显然存到了小数后一位,比如56.1度,就是561了也就是放大了10倍,所以 ...

好的,谢谢大佬
回复

使用道具 举报

13#
ID:923364 发表于 2021-5-18 16:49 | 只看该作者
大佬你好,请问你这个原理图右下角那个原件叫什么啊?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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