找回密码
 立即注册

QQ登录

只需一步,快速开始

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

使用单片机+DS18B20设计温控系统 附文档+源程序

[复制链接]
跳转到指定楼层
楼主
ID:620336 发表于 2019-12-25 15:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

(1)主程序设计:主程序里只包含对温度对串口返回上位机的控制,整个采用模块化设计该实验。

(2)子程序设计:

该程序的子程序中包含DS18B20以及串口初始化函数,根据其时序图编写代码,其中包括DS18B20读一位数据函数和读一字节数据函数以及写一字节数据函数。DS18B20获取温度并转换子程序具有将当前温度转换为实际温度的作用,数据显示程序,报警程序,以及温度处理程序共同组成温控系统的逻辑部分。

过程:

1.DS18B20复位,初始化函数

2.DS18B20读一位数据函数,一字节数据函数以及写一字节数据函数

3.DS18B20开始获取温度并转换,将读到的温度数据*0.0625转换成实际温度数据

4.数据显示程序,将定义好的uchar型编码赋给P0口,将得到的温度数据显示在数码管上。其中,显示个位数码管时,需要得到带小数点的编码

5.蜂鸣器与led灯,用音调高低来控制蜂鸣器滴声的快慢,音调越长,滴声越慢,并且led灯根据所需实验现象闪烁

6.串口发送数据,并将实时温度返回给上位机

主程序的流程图如图8所示。


图8.主程序流程图

DS18B20读数据流程如图9所示,读程序为读一字节数据。

               图9.DS18B20读数据时序图


5.调试结

调试结果如图10所示,该图为温度在31.9度时,处于30到32度之间,现象为P1.2口发光二极管闪烁,蜂鸣器响。


图10.调试现象

最终调试出了正确的结果,理论上DS18B20的测量范围在-55度~+125度,由于环境温度,并没有达到峰值,并且,该芯片在-10度~+85度之间存在±5度的误差,因此在温度显示并返回上位机时会有时间差以及温度差。并且该芯片自身存在延时,不同分辨率时,会有不同的时间将温度转换为数字显示,分辨率越高,显示越快。并且在实验时,存在芯片插反的错误,此时芯片不会因为发烫而烧毁,但是不可以正常工作。

*温度控制系统被广泛地应用于生活中,本设计也还可以做一些拓展,例如在温室大棚里可以加一个温度控制器,蜂鸣器用来报警,来控制监测大棚内温度。


单片机源程序如下:


  1. #include<reg52.h>
  2. #include<stdio.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. sbit ds=P2^2;//温度传感器信号线
  6. sbit dula=P2^6;//数码管段选管
  7. sbit wela=P2^7;//数码管位选线
  8. sbit beep=P2^3;//蜂鸣器
  9. uint temp,templa;定义整型温度数据
  10. float f_temp;//定义浮点型温度数据
  11. uint warn_11=270;定义温度下限值,是温度*10的结果
  12. uint warn_12=250; 定义温度下限值
  13. uint warn_h1=300; 定义温度上限值
  14. uint warn_h2=320; 定义温度上限值
  15. sbit led0=P1^0;//控制发光二极管
  16. sbit led1=P1^1;
  17. sbit led2=P1^2;
  18. sbit led3=P1^3;
  19. uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
  20. void delay(uint z)
  21. {
  22.               uint x,y;
  23.               for(x=z;x>0;x--)
  24.                  for(y=110;y>0;y--);
  25. }
  26. void dsreset(void)//DS18B20复位,初始化函数
  27. {
  28.               uint i;
  29.               ds=0;
  30.               i=103;
  31.               while(i>0)i--;
  32.               ds=1;
  33.               i=4;
  34.               while(i>0)i--;
  35. }
  36. bit tempreadbit(void)//读一位数据函数
  37. {
  38.               uint i;
  39.               bit dat;
  40.               ds=0;i++;//i++起延时作用
  41.               ds=1;i++;i++;
  42.               dat=ds;
  43.               i=8;while(i>0)i--;
  44.               return(dat);
  45. }
  46. uchar tempread(void)//读1个字节数据
  47. {
  48.               uchar i,j,dat;
  49.               dat=0;
  50.               for(i=1;i<=8;i++)
  51.               {
  52.                             j=tempreadbit();
  53.                             dat=(j<<7)|(dat>>1);//读出的数据最低位在最前面,这样刚好一个字节在dat里
  54.               }
  55.               return(dat);
  56. }
  57. void tempwritebyte(uchar dat)//向DS18B20写一个字节数据函数
  58. {
  59.    uint i;
  60.    uchar j;
  61.    bit testb;
  62.    for(j=1;j<=8;j++)
  63.    {
  64.       testb=dat&0x01;
  65.       dat=dat>>1;
  66.       if(testb)//写1
  67.       {
  68.         ds=0;
  69.         i++;i++;
  70.         ds=1;
  71.         i=8;while(i>0)i--;
  72.       }
  73.       else
  74.       {
  75.         ds=0;//写0
  76.         i=8;while(i>0)i--;
  77.         ds=1;
  78.         i++;i++;
  79.       }
  80.    }
  81. }
  82. void tempchange(void)//DS18B20开始获取温度并转换
  83. {
  84.    dsreset();
  85.    delay(1);
  86.    tempwritebyte(0xcc);//写跳过ROM指令
  87.               tempwritebyte(0x44);//写温度转换指令
  88. }
  89. uint get_temp()//读取寄存器中存储的温度数据
  90. {
  91.    uchar a,b;
  92.    dsreset();
  93.    delay(1);
  94.    tempwritebyte(0xcc);
  95.    tempwritebyte(0xbe);
  96.    a=tempread();//读低8位
  97.    b=tempread();//读高8位
  98.    temp=b;
  99.    temp<<=8;//两个字节组合为1个字
  100.    temp=temp|a;
  101.    f_temp=temp*0.0625;//温度在寄存器中为12位,分辨率为0.0625°
  102.    temp=f_temp*10+0.5;//*10表示小数点后面只取1位,加0.5是四舍五入
  103.    f_temp=f_temp+0.05;
  104.    return temp;//temp是整型
  105. }
  106. void display(uchar num,uchar dat)//num第几个数码管,dat要显示的数字
  107. {
  108.    uchar i;
  109.    dula=0;
  110.    P0=table[dat];
  111.    dula=1;
  112.    dula=0;
  113.    wela=0;
  114.    i=0XFF;
  115.    i=i&(~((0X01)<<(num)));//用i来存储位选数据,只有一位为0
  116.    P0=i;
  117.    wela=1;
  118.    wela=0;
  119.    delay(1);
  120. }
  121. void dis_temp(uint t)//显示温度数值函数t传递的是整型的温度值
  122. {
  123.    uchar i;
  124.    i=t/100;//除以100得到商,为温度的十位
  125.    display(0,i);//在数码管第一个显示
  126.    i=t%100/10;//100取余在除以10得到商,为温度的个位
  127.    display(1,i+10); //在数码管第二个显示
  128.    i=t%100%10; //100取余在用10取余,为温度的小数位
  129.    display(2,i);//在数码管第三个显示
  130. }
  131. void warn(uint s,uchar led)//蜂鸣器报警,灯闪烁,s控制音调,led控制灯
  132. {
  133.    uchar i;i=s;
  134.    beep=0;//蜂鸣器响
  135.    P1=~(led);//控制相应的灯灭
  136.    while(i--)
  137.    {
  138.     dis_temp(get_temp());//用温度显示函数起到延时作用
  139.    }
  140.    beep=1;//蜂鸣器不响
  141.    P1=0XFF;
  142.    i=s;
  143.    while(i--)
  144.    {
  145.     dis_temp(get_temp());//控制相应的灯灭
  146.    }
  147. }
  148. void deal(uint t)//温度处理函数
  149. {
  150.    uchar i;
  151.    if((t>warn_12)&&(t<=warn_11))//t:温度
  152.    {
  153.      warn(40,0x01);//第一个灯亮,蜂鸣器发声
  154.    }
  155.    else if(t<=warn_12)
  156.    {
  157.      warn(10,0x03);// 第一个的第二个灯亮,蜂鸣器发声
  158.    }
  159.    else if((t<warn_h2)&&(t>=warn_h1))
  160.    {
  161.      warn(40,0x04); //第三个灯亮,蜂鸣器发声
  162.    }
  163.    else if(t>=warn_h2)
  164.    {
  165.      warn(10,0x0c); //第三个和第四个灯亮,蜂鸣器发声
  166.    }
  167.    else//在27度和30度之间时只是调用显示函数延时
  168.    {
  169.      i=40;
  170.      while(i--)
  171.       {
  172.         dis_temp(get_temp());
  173.       }
  174.    }
  175. }
  176. void init_com(void)//串口初始化
  177. {
  178.    TMOD=0x20;
  179.    PCON=0x00;
  180.    SCON=0x50;
  181.    TH1=0xFd;//波特率9600
  182.    TL1=0xFd;
  183.    TR1=1;
  184. }
  185. void comm(char*parr)//串口数据发送函数
  186. {
  187.               do
  188.               {
  189.                 SBUF=*parr++;//发送数据
  190.                 while(!TI);//等待发送完标志为1
  191.                 TI=0;//标志清0
  192.    }while(*parr);//保持循环知道字符为‘、0’
  193. }
  194. void main()
  195. {
  196.               uchar buff[4],i;
  197.               dula=0;
  198.               wela=0;
  199.               init_com();
  200.               while(1)
  201.               {
  202.                             tempchange();//温度转换函数
  203.                             for(i=10;i>0;i--)
  204.                             {
  205.                                           dis_temp(get_temp());//获取温度并显示
  206.       }
  207.                                deal(temp);//进行温度处理
  208.                                           sprintf(buff,"%f",f_temp);//将浮点型温度格式化为字符型
  209.                             for(i=10;i>0;i--)
  210.                             {
  211.                                           dis_temp(get_temp());//温度显示
  212.        }
  213.                                comm(buff);//串口发送数据
  214.                             for(i=10;i>0;i--)
  215.                             {
  216.                                           dis_temp(get_temp());温度显示
  217.                             }
  218.    }
  219. }
复制代码

全部资料51hei下载地址:

代码+文档.7z (729.86 KB, 下载次数: 32)


评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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