找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于DS81B20的数字温度计全套设计资料下载(仿真+代码+文档)

  [复制链接]
跳转到指定楼层
楼主
基于51单片机和DS18B20的数字温度计设计的资料,包括了protues的仿真设计和报告。

目录
摘要    2
一、 绪论    2
1.1单片机简介    2
1.2 DS18B20温度传感器简介    2
1.3基于单片机和温度传感器设计数字温度计的发展现状    2
1.4选题的意义    3
1.5本数字温度计设计的工作    3
二、设计方案论证与选择    4
2.1单片机具体方案论证与设计    4
2.2温度传感器具体方案论证与设计    4
三、主要芯片与硬件介绍    5
3.1 stc89C51    5
3.2 DS18B20    6
3.3四位一体数码管    9
四、 系统电路设计    10
4.1单片机最小系统电路设计    10
4.2 DS18B20温度传感器电路    11
4.3四位一体数码管显示电路    11
五、 系统的软件设计    11
5.1主程序    12
5.2读出温度子程序    12
5.3    温度转换命令子程序    13
5.4计算温度子程序    14
5.5 显示数据刷新子程序    14
5.6按键扫描处理子程序    15
六、 温度数据的计算处理方法    16
七、 仿真调试及性能分析    17
八、 总结    17
参考文献    18
附件一:系统原理图    18
附件二:     元件清单    19
附件三:程序源代码    19


单片机源程序如下:
  1. # include <reg51.h>  
  2. #define uint unsigned int
  3. #define uchar unsigned char   //宏定义
  4. #define Disdata P2          //段码输出口
  5. #define discan  P0           //扫描口
  6. sbit p34=P0^0;
  7. sbit p35=P0^1;
  8. sbit p36=P0^2;
  9. sbit dp=P2^7;
  10. sbit p37=P0^3;
  11. sbit DQ=P1^0;    //定义DS18B20总线I/O
  12. sbit set=P1^6;    //定义选择报调整警温度上限和下限(1为上限,0为下限)
  13. /****P1.4和P1.4为调整温度报警增加键和减少键******/
  14. sbit SET=P3^2;
  15. sbit add=P1^4;
  16. sbit dec=P1^5;
  17. sbit led_red=P1^2;                //超过上限温度或低于下限温度,红灯亮·
  18. sbit led_green=P1^3;                //温度在正常范围内,绿灯亮
  19. sbit speaker=P3^5;   //定义响铃
  20. int temp1;  
  21. signed char m;     //温度值全局变量
  22. bit sign=0;     //外部中断状态标志
  23. signed char shangxian=38;  //上限报警温度,默认值为38
  24. signed char xiaxian=6;   //下限报警温度,默认值为5
  25. uchar code  LEDData[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}; /*****延时子程序*****/
  26. uchar code dis_7[12]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF,0xBF};
  27. /*共阳LED段码表 "0","1","2","3","4","5","7","8","9","不亮","-"*/
  28. uchar code scan_con[4]={0xf1,0xF2,0xF4,0xF8};  //列扫描控制字
  29. uchar data temp_data[2]={0x00,0x00}; //读出温度暂存
  30. uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //显示单元数据,共4个数据,其中一个作为运算暂存用
  31. void Delay(uint i)
  32. {  
  33. while( i-- );
  34. }
  35.   /******************显示扫描函数**********************/
  36. void scan()
  37. {
  38.         char k;
  39.         for(k=0;k<4;k++)           //循环扫描4个口,并显示
  40.         {
  41.         Disdata=dis_7[display[k]];
  42.         if(k==1){dp=0;}
  43.         discan=scan_con[k];
  44.         Delay(65);
  45.         discan=0xff;
  46.         }
  47.        
  48. }

  49. void Init_DS18B20(void)
  50. {  
  51.   unsigned char x=0;   
  52.     DQ=1;    Delay(8);    //稍做延时
  53.    DQ=0;         //单片机将DQ拉低  
  54. Delay(80);   //精确延时,大于480us
  55.   DQ=1;         //拉高总线
  56.   Delay(14);
  57.    x=DQ;           //稍做延时后,如果x=0则初始化成功,x=1则初始化失败  
  58. Delay(20);
  59. }  
  60. /***************18b20读一字节函数****************/
  61.   unsigned char ReadOneChar(void)
  62. {   
  63. unsigned char i=0;
  64.   unsigned char dat=0;
  65.   for (i=8;i>0;i--)  
  66. {     
  67. DQ=0;     // 给脉冲信号   
  68.   dat>>=1;   
  69.    DQ=1;     // 给脉冲信号
  70.     if(DQ)     dat|=0x80;  
  71.    Delay(4);
  72.   }   
  73. return(dat); }  
  74. /***************18b20写命令函数**************/
  75. void WriteOneChar(unsigned char dat)
  76. {    unsigned char i=0;
  77.   for (i=8; i>0; i--)
  78.   {
  79.      DQ=0;   
  80.    DQ=dat&0x01;  
  81.    Delay(5);     
  82. DQ=1;     dat>>=1;
  83.   }
  84. }  
  85. void Tmpchange(void) //发送温度转换命令
  86. {  
  87.   Init_DS18B20();
  88.    WriteOneChar(0xCC);  //跳过读序号列号的操作  
  89. WriteOneChar(0x44);  //启动温度转
  90.    }
  91. unsigned int ReadTemperature(void)
  92. {   
  93. unsigned char a=0;
  94.   unsigned char b=0;
  95.   unsigned int t=0;  
  96. float tt=0;  
  97. Tmpchange();
  98.    Init_DS18B20();  
  99.   WriteOneChar(0xCC);  //跳过读序号列号的操作
  100.   WriteOneChar(0xBE);  //读取温度寄存器  
  101. a=ReadOneChar();     //读低8位
  102.   b=ReadOneChar();    //读高8位
  103.   t=b;   t<<=8;   t=t|a;    tt=t*0.0625;    t= tt*100+0.5;     //放大10倍输出并四舍五入
  104.   return(t); }     /*****显示开机初始化等待画面*****/
  105. Disp_init()     {   
  106. P2 = 0x80;      //显示-
  107. p34=1;p35=0;p36=0;p37=0;
  108. Delay(200);
  109. P2 = 0x80;
  110.    p34=0;p35=1;p36=0;p37=0;
  111. Delay(200);
  112.   P2 = 0x80;
  113.     p34=0;p35=0;p36=1;p37=0;
  114. Delay(200);
  115.   P2 = 0x80;
  116.    p34=0;p35=0;p36=0;p37=1;
  117. Delay(200);
  118.   P2 = 0x80;
  119.   }
  120. /******************温度数据处理函数****************/  
  121. work_temp()     //显示温度
  122. {   uint a,b,c,d,e;  
  123.   e=ReadTemperature();  //获取温度值
  124.   a=e/10000;             //计算得到百位数
  125.   b=e/1000;                                //计算得到十位数
  126.   c=e/100-b*10;         //计算得到个位数字                 
  127.   d=(e%100)/10;         //计算得到小数点后一位
  128.   m=e/100;  
  129.   p34=0;p35=0;p36=0;p37=0;   
  130.   P2 =LEDData[d];   //显示小数点后一位  
  131.   p34=1;p35=0;p36=0;p37=0;      
  132.   Delay(300);  p34=0;p35=0;p36=0;p37=0;   
  133.   P2 =LEDData[c];    //显示个位
  134.   dp=0;p34=0;p35=1;p36=0;p37=0;
  135.   Delay(300);
  136.   p34=0;p35=0;p36=0;p37=0;   
  137.   P2 =LEDData[b];    //显示十位
  138.   p34=0;p35=0;p36=1;p37=0;
  139.   Delay(300);  p34=0;p35=0;p36=0;p37=0;  
  140.   P2 =LEDData[a];    //显示百位
  141.   if(LEDData[a]==0){P0=0x0A;
  142.         if(LEDData[b]==0){P0=0x0A;}}        //最高位为0时都不显示
  143.   p34=0;p35=0;p36=0;p37=1;  
  144.   Delay(300);  p34=0;p35=0;p36=0;p37=0;        //关闭显示
  145. }  
  146. disptiaozheng()  
  147. {   
  148. uchar f,g,j,k;  
  149. f=shangxian/10;  
  150. g=shangxian%10;  
  151. j=xiaxian/10;  
  152. k=xiaxian%10;  
  153. p34=0;p35=0;p36=0;p37=0;
  154. P2 =dis_7[display[2]];          //显示0
  155. p34=0;p35=1;p36=0;p37=0;
  156. Delay(200);  
  157. p34=0;p35=0;p36=0;p37=0;   
  158. P2 =0xc0;          //显示0
  159. p34=0;p35=0;p36=1;p37=0;
  160. Delay(200);  
  161. p34=0;p35=0;p36=0;p37=0;  
  162. if(SET==1)
  163. {  
  164. P2 =LEDData[g];
  165.   dp=0;   //显示上限温度个位
  166.     }  
  167. else
  168. {
  169. P2 =LEDData[k];
  170.   dp=0;
  171.   }
  172. p34=0;p35=0;p36=1;p37=0;
  173.   Delay(200);  p34=0;p35=0;p36=0;p37=0;
  174.    if(SET==1) P2 =LEDData[f];   //显示上限温度十位
  175. else    {    if(f==0) P0=0x00;     //不显示下限温度十位
  176.   else P2 =LEDData[j];  //显示下限温度十位
  177.   }  p34=0;p35=0;p36=0;p37=1;
  178. Delay(200);
  179.   p34=0;p35=0;p36=0;p37=0;          //关闭显示
  180. Delay(20);  
  181. }
  182. /******************设置温度显示转换******************/
  183. exchange(int horl)
  184. {
  185.         int n=0;
  186.         if(horl>128)
  187.         {
  188.         horl=256-horl;n=1; //负温度求补码
  189.         }
  190.         display[3]=horl/100;  //百位数据暂存
  191.         display[3]=display[3]&0x0f;
  192.         display[2]=horl%100/10;           //十位数据暂存
  193.         display[1]=horl%10;                  //个位数据暂存
  194.         display[0]=0;
  195.         if(!display[3]){display[3]=0x0A;
  196.         if(!display[2]){display[2]=0x0A;}}        //最高位为0时都不显示
  197.         if(n){display[3]=0x0B;}                //负温度时最高位显示为“-”
  198.    
  199.   p34=0;p35=0;p36=0;p37=0;
  200.   P2 =0xc6;          //显示0
  201.   p34=1;p35=0;p36=0;p37=0;
  202.   Delay(200);  
  203.   p34=0;p35=0;p36=0;p37=0;   
  204.   P2 =dis_7[display[1]];dp=0;          //显示个位
  205.   p34=0;p35=1;p36=0;p37=0;
  206.   Delay(200);  
  207.   p34=0;p35=0;p36=0;p37=0;   
  208.   P2=dis_7[display[2]];
  209.   p34=0;p35=0;p36=1;p37=0;
  210.   Delay(200);  
  211.   p34=0;p35=0;p36=0;p37=0;
  212.   P2=dis_7[display[3]];
  213.   p34=0;p35=0;p36=0;p37=1;
  214.   Delay(200);
  215.   p34=0;p35=0;p36=0;p37=0;          //关闭显示
  216.   Delay(20);
  217. }
  218. /******************蜂鸣器报警程序*********************/
  219. void beep()
  220. {
  221.         if(m>=shangxian &&m<129|| m<xiaxian)   //温度不在范围内报警
  222.         {        speaker=~speaker;
  223.                 led_red=0;           //红灯亮
  224.                 led_green=1;}   //绿灯灭
  225.         else
  226.         {
  227.         speaker=0;
  228.         led_red=1;
  229.         led_green=0;}          //绿灯亮
  230. }
  231. /******************按键查询程序**********************/
  232. void keyscan()
  233. {
  234.         if(set==0)                 //判断设置温度键是否按下
  235.         {
  236.                 while(1)
  237.                 {
  238.                 Delay(500);  //消抖
  239.                 if(set==0)
  240.                 {
  241.                 temp1++;
  242.                 while(!set)
  243.                 scan();
  244.                 }
  245.                 if(temp1==1)                 //1时,显示温度上限
  246.                 {
  247.                 exchange(shangxian); //显示温度上限值
  248.                 scan();
  249.                 if(add==0)        //判断增加键是否按下
  250.                 {
  251.                 while(!add)
  252.                 scan();
  253.                 shangxian+=1;
  254.                 }
  255.                 if(dec==0)        //判断减少键是否按下
  256.                 {
  257.                 while(!dec)
  258.                 scan();
  259.                 shangxian-=1;
  260.                 }
  261.                 }
  262.                 if(temp1==2)          //2时,显示温度下限
  263.                 {
  264.                 exchange(xiaxian); //显示温度下限值
  265.                 scan();
  266.                 if(add==0)                  //判断增加键是否按下
  267.                 {
  268.                 while(!add)                  
  269.                 scan();
  270.                 xiaxian+=1;
  271.                 }
  272.                 if(dec==0)                  //判断减少键是否按下
  273.                 {
  274.                 while(!dec)
  275.                 scan();
  276.                 xiaxian-=1;
  277.                 }
  278.                 scan();
  279.                 }
  280.                 if(temp1==3)          //3时返回,显示当前温度
  281.                 {
  282.                 temp1=0;
  283.                 break;
  284.                 }
  285.                 }
  286.         }
  287. }   
  288. void int0(void) interrupt 0
  289. {     EX0=0;      //关外部中断0
  290. sign=1;  
  291. if(SET==1) shangxian++;  else xiaxian++;
  292.   Delay(500);  EX0=1;
  293. }   /*****外部中断1服务程序*****/
  294. void int1(void)  interrupt 2
  295. {   
  296. EX1=0;      //关外部中断0
  297. sign=1;   if(SET==1) shangxian--;
  298. else xiaxian--;  Delay(500);  EX1=1;
  299.   }   /*****主函数*****/
  300. void main(void)
  301. {   
  302.   uint h;
  303.   IT0=1;  
  304.   IT1=1;
  305.   EX0=1;
  306.   EX1=1;
  307.   EA=1;
  308.   for(h=0;h<4;h++)
  309.         {
  310.                 display[h]=8;                //开机显示8888
  311.         }
  312.   ReadTemperature();
  313.   speaker=0;   
  314. for(h=0;h<500;h++)
  315.         {
  316.                 scan();                //开机显示“8888”2s
  317. }
  318. while(1)  
  319. {      
  320.   if(temp1==0)
  321.           {
  322.                 work_temp();
  323.                 beep();                         //检测是否超过上限或低于下限
  324.                 keyscan();                //按键检测
  325.                 }
  326.                 else
  327.                 {
  328.                 keyscan();           //按键检测
  329.                 }   
  330. }
  331. }

复制代码

全部资料51hei下载地址:
数字温度计设计.zip (633.93 KB, 下载次数: 211)

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:460968 发表于 2019-1-3 15:13 | 只看该作者
非常漂亮的一篇帖子 对我的 课程设计很有帮助
回复

使用道具 举报

板凳
ID:682512 发表于 2020-1-8 14:33 | 只看该作者
你好,有汇编版的吗
回复

使用道具 举报

地板
ID:417194 发表于 2020-1-10 19:07 | 只看该作者
太棒了,顶楼主
回复

使用道具 举报

5#
ID:1055077 发表于 2022-12-4 17:01 来自手机 | 只看该作者
值得下载参考学习
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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