找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于DS18B20数字温度计 单片机程序和proteus仿真

  [复制链接]
跳转到指定楼层
楼主
给大家分享2个温度显示程序和仿真
源程序
  1. #include "typedef.h"
  2. #include "device_init.h"
  3. #include "delay.h"

  4. /************************************************
  5. * 函数名称:ds18b20_reset
  6. * 输    入:
  7. * 输    出:
  8. * 功能描述:
  9. *************************************************/
  10. u8 ds18b20_reset(void)
  11. {
  12.         DQ_PIN = HIGH;
  13.         delay_16us(1);
  14.         DQ_PIN = LOW;
  15.         delay_16us(30);                //延时600us
  16.         DQ_PIN = HIGH;
  17.         delay_16us(5);                //延时80us
  18.         if(!DQ_PIN)
  19.         {
  20.                 delay_16us(30);        //延时420us
  21.                 return 1;
  22.         }
  23.         else
  24.                 return 0;
  25. }
  26. /************************************************
  27. * 函数名称:ds18b20_write_byte
  28. * 输    入:
  29. * 输    出:
  30. * 功能描述:
  31. *************************************************/
  32. void ds18b20_write_byte(u8 wByte)
  33. {
  34.         u8 i;

  35.         for(i=0; i<8; i++)
  36.         {
  37.                 DQ_PIN = LOW;
  38.                 NOP();
  39.                 NOP();
  40.                 NOP();
  41.                 NOP();
  42.                 NOP();
  43.                 NOP();
  44.                 NOP();
  45.                 DQ_PIN = wByte & 0x01;
  46.                 NOP();
  47.                 NOP();
  48.                 NOP();
  49.                 NOP();
  50.                 NOP();
  51.                 DQ_PIN = HIGH;
  52.                 NOP();
  53.                 NOP();
  54.                 NOP();
  55.                 wByte >>= 1;
  56.         }
  57. }
  58. /************************************************
  59. * 函数名称:ds18b20_read_byte
  60. * 输    入:
  61. * 输    出:
  62. * 功能描述:
  63. *************************************************/
  64. u8 ds18b20_read_byte(void)
  65. {
  66.         u8 rByte;
  67.         u8 i;

  68.         for(i=0; i<8; i++)
  69.         {
  70.                 DQ_PIN = LOW;
  71.                 NOP();
  72.                 NOP();
  73.                 rByte >>= 1;
  74.                 NOP();
  75.                 NOP();
  76.                 NOP();
  77.                 NOP();
  78.                 NOP();
  79.                 NOP();
  80.                 DQ_PIN = HIGH;
  81.                 NOP();
  82.                 NOP();
  83.                 NOP();
  84.                 NOP();
  85.                 NOP();
  86.                 NOP();
  87.                 NOP();
  88.                 if(DQ_PIN)
  89.                         rByte |= 0x80;
  90.                 NOP();
  91.                 NOP();
  92.                 NOP();
  93.                 NOP();
  94.                 NOP();
  95.                 NOP();
  96.                 NOP();
  97.         }
  98.         DQ_PIN = HIGH;
  99.         return rByte;
  100. }
  101. /************************************************
  102. * 函数名称:ds18b20_get_temp
  103. * 输    入:
  104. * 输    出:
  105. * 功能描述:
  106. *************************************************/
  107. u16 ds18b20_get_temp(void)
  108. {
  109.         u16 Temp;

  110.         if(ds18b20_reset() == 0)                        //复位
  111.                 return 0;
  112.         ds18b20_write_byte(0xcc);                        //忽略ROM
  113.         ds18b20_write_byte(0x44);                        //发送温度转化命令
  114.         delay_16us(30);
  115.         if(ds18b20_reset() == 0)                        //再次复位
  116.                 return 0;
  117.         ds18b20_write_byte(0xcc);                        //忽略ROM
  118.         ds18b20_write_byte(0xbe);

  119.         Temp = ds18b20_read_byte();
  120.         Temp |= ds18b20_read_byte() << 8;

  121.         return Temp;
  122. }
复制代码


  1. /*
  2. #include <REGX52.H>
  3. #define uchar unsigned char
  4. sbit DQ=P2^0;       //数据传输线接单片机的相应的引脚
  5. unsigned char tempL=0;    //临时变量低位(无符号字符变量)
  6. unsigned char tempH=0;   //临时变量高位
  7. unsigned int tempa;      //温度值(整型变量)
  8. uchar display_data[4]={0};
  9. void DS18_delay(int useconds)//延时函数
  10. {
  11. int s;
  12. for (s=0; s<useconds;s++);
  13. }
  14. unsigned char Init_DS18B20(void)
  15. {
  16. unsigned char x=0;

  17.    DQ=0;               //发送复位脉冲
  18.    DS18_delay(29);           //延时(>480ms)
  19.    DQ=1;             //拉高数据线
  20.    DS18_delay(3);         //等待(15~60ms) 等待存在脉冲
  21.     x=DQ;  //获得存在信号(用于判断是否有器件)
  22.     DS18_delay(25);  // 等待时间隙结束
  23.     return(x);  //返回存在信号,0 = 器件存在, 1 = 无器件
  24. }
  25. ReadOneChar(void)//读一个字节
  26. {
  27. unsigned char i=0;   
  28. unsigned char dat=0;
  29.     for (i=8;i>0;i--)   
  30.   {
  31.    DQ=1;
  32.       DS18_delay(1);
  33.       DQ=0;      
  34.       dat>>=1;//复合赋值运算,等效dat=dat>>1(dat=dat右移一位后的值)
  35.       DQ=1;
  36.       if(DQ)
  37.       dat|=0x80;
  38.       DS18_delay(4);
  39.   }
  40.     return(dat);
  41. }
  42. WriteOneChar(unsigned char dat)//有参函数,功能是"写",而写的内容就是括号内的参数
  43. {
  44. unsigned char i=0;   
  45. for(i=8;i>0;i--)   
  46. {
  47.   DQ=0;     
  48.   DQ=dat&0x01;
  49.   DS18_delay(5);
  50.   DQ=1;
  51.   dat>>=1;//复合赋值运算,等效dat=dat>>1(dat=dat右移一位后的值)
  52. }
  53. DS18_delay(4);
  54. }
  55. unsigned int ReadTemperature(void)//返回读取的温度.
  56. {  
  57. Init_DS18B20();   //初始化,调用初始化函数
  58. WriteOneChar(0xcc);    //跳过读序列号的操作,调用写函数,写0xcc指令码(跳过读序列号)
  59. WriteOneChar(0x44);   //启动温度转换,调用写函数,写0x44指令码(启动温度转换)
  60. DS18_delay(125);       //转换需要一点时间,延时
  61. Init_DS18B20();    //初始化,调用初始化函数
  62. WriteOneChar(0xcc);    //跳过读序列号的操作,调用写函数,写0xcc指令码(跳过读序列号?
  63. WriteOneChar(0xbe);   //调用写函数,写0xbe指令码,读温度寄存器(头两个值分别为温度的低位和高位)
  64. tempL=ReadOneChar();   //读出温度的低位LSB
  65. tempH=ReadOneChar();   //读出温度的高位MSB  
  66.    tempa=((tempH*256)+tempL)*6.25;  //温度转换,扩大100返回
  67. //DS18_delay(10);
  68. //tempa=tempL+tempH;
  69. return(tempa);//运算结果返回到函数
  70. }
  71. void display()//显示函数
  72. {
  73.   unsigned char i,j,k=0x80;
  74.   unsigned char code dis[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x39};
  75.   for(i=0;i<4;i++)
  76.    {
  77.     P2=0x0f;
  78.     if(i==1)
  79.      P0=dis[display_data[i]]+0x80;
  80.     else
  81.      P0=dis[display_data[i]];
  82.     P2=k;
  83.     k=k>>1;
  84.     for(j=250;j>0;j--);
  85.    }
  86.    P2=0x0f;
  87. }
  88. void main()
  89. {

  90. unsigned int temp;
  91. uchar i;
  92. while(1)
  93. {
  94.   temp=ReadTemperature();
  95.   display_data[0]=temp/1000;
  96.   display_data[1]=(temp/100)%10;
  97.   display_data[2]=(temp/10)%10;
  98.   display_data[3]=temp%10;
  99.   for(i=0;i<250;i++) display();
  100. }
  101. } */
  102. # include <reg51.h>  
  103. #define uint unsigned int
  104. #define uchar unsigned char   //宏定义
  105. sbit p34=P2^4;
  106. sbit p35=P2^5;
  107. sbit p36=P2^6;
  108. sbit dp=P0^7;
  109. sbit p37=P2^7;
  110. sbit  DQ=P2^2;    //定义DS18B20总线I/O
  111.   sbit SET=P3^1;    //定义选择报调整警温度上限和下限(1为上限,0为下限) /****P3.2和P3.3为调整温度报警增加键和减少键******/
  112. sbit LING=P2^0;   //定义响铃  
  113. signed char m;     //温度值全局变量
  114. bit sign=0;     //外部中断状态标志
  115. signed char shangxian=38;  //上限报警温度,默认值为38
  116. signed char xiaxian=6;   //下限报警温度,默认值为5
  117.   uchar code  LEDData[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}; /*****延时子程序*****/
  118. void Delay(uint i)
  119. {  
  120. while( i-- );
  121. }
  122. void Init_DS18B20(void)
  123. {  
  124.   unsigned char x=0;   
  125.     DQ=1;    Delay(8);    //稍做延时
  126.    DQ=0;         //单片机将DQ拉低  
  127. Delay(80);   //精确延时,大于480us
  128.   DQ=1;         //拉高总线
  129.   Delay(14);
  130.    x=DQ;           //稍做延时后,如果x=0则初始化成功,x=1则初始化失败  
  131. Delay(20);
  132. }  
  133. /*****读一个字节*****/
  134.   unsigned char ReadOneChar(void)
  135. {   
  136. unsigned char i=0;
  137.   unsigned char dat=0;
  138.   for (i=8;i>0;i--)  
  139. {     
  140. DQ=0;     // 给脉冲信号   
  141.   dat>>=1;   
  142.    DQ=1;     // 给脉冲信号
  143.     if(DQ)     dat|=0x80;  
  144.    Delay(4);
  145.   }   
  146. return(dat); }  
  147. /*****写一个字节*****/
  148. void WriteOneChar(unsigned char dat)
  149. {    unsigned char i=0;
  150.   for (i=8; i>0; i--)
  151.   {
  152.      DQ=0;   
  153.    DQ=dat&0x01;  
  154.    Delay(5);     
  155. DQ=1;     dat>>=1;
  156.   }
  157. }  
  158. void Tmpchange(void) //发送温度转换命令
  159. {  
  160.   Init_DS18B20();
  161.    WriteOneChar(0xCC);  //跳过读序号列号的操作  
  162. WriteOneChar(0x44);  //启动温度转
  163.    }
  164. unsigned int ReadTemperature(void)
  165. {   
  166. unsigned char a=0;
  167.   unsigned char b=0;
  168.   unsigned int t=0;  
  169. float tt=0;  
  170. Tmpchange();
  171.    Init_DS18B20();  
  172.   WriteOneChar(0xCC);  //跳过读序号列号的操作
  173.   WriteOneChar(0xBE);  //读取温度寄存器  
  174. a=ReadOneChar();     //读低8位
  175.   b=ReadOneChar();    //读高8位
  176.   t=b;   t<<=8;   t=t|a;    tt=t*0.0625;    t= tt*100+0.5;     //放大10倍输出并四舍五入
  177.   return(t); }     /*****显示开机初始化等待画面*****/
  178. Disp_init()     {   P0 = 0x80;      //显示-
  179. p34=1;p35=0;p36=0;p37=0;
  180. Delay(200);
  181. P0 = 0x80;
  182.    p34=0;p35=1;p36=0;p37=0;
  183. Delay(200);
  184.   P0 = 0x80;
  185.     p34=0;p35=0;p36=1;p37=0;
  186. Delay(200);
  187.   P0 = 0x80;
  188.    p34=0;p35=0;p36=0;p37=1;
  189. Delay(200);
  190.   P0 = 0x80;
  191.   }  
  192. Disp_Temperature()     //显示温度
  193. {   uint a,b,c,d,e;  
  194. e=ReadTemperature();  //获取温度值
  195.   a=e/1000;             //计算得到十位数
  196. b=e/100-a*10;         //计算得到个位数字  
  197. d=e%10;               //计算得到小数点后两位
  198. c=(e%100)/10;         //计算得到小数点后一位
  199. m=e/100;  
  200. if(m>shangxian || m<xiaxian) LING=1;  //温度不在范围内报警  
  201. else LING=0;  p34=0;p35=0;p36=0;p37=0;   
  202.   P0 =LEDData[d];   //显示小数点后两位  
  203.   p34=1;p35=0;p36=0;p37=0;      
  204.   Delay(300);  p34=0;p35=0;p36=0;p37=0;   
  205. P0 =LEDData[c];    //显示小数点后一位
  206. p34=0;p35=1;p36=0;p37=0;
  207. Delay(300);
  208. p34=0;p35=0;p36=0;p37=0;   
  209. P0 =LEDData[b];    //显示个位
  210. dp=0;  p34=0;p35=0;p36=1;p37=0;
  211. Delay(300);  p34=0;p35=0;p36=0;p37=0;  
  212.   P0 =LEDData[a];    //显示十位
  213. p34=0;p35=0;p36=0;p37=1;  
  214. Delay(300);  p34=0;p35=0;p36=0;p37=0;        //关闭显示
  215. }  
  216. disptiaozheng()  
  217. {   
  218. uchar f,g,j,k;  
  219. f=shangxian/10;  
  220. g=shangxian%10;  
  221. j=xiaxian/10;  
  222. k=xiaxian%10;  
  223. p34=0;p35=0;p36=0;p37=0;
  224.     P0 =0xc0;          //显示0 p34=1;p35=0;p36=0;p37=0;
  225. Delay(200);  p34=0;p35=0;p36=0;p37=0;   P0 =0xc0;          //显示0
  226. p34=0;p35=1;p36=0;p37=0;
  227. Delay(200);  p34=0;p35=0;p36=0;p37=0;  
  228. if(SET==1)
  229. {  
  230. P0 =LEDData[g];
  231.   dp=0;   //显示上限温度个位
  232.     }  
  233. else
  234. {
  235. P0 =LEDData[k];
  236.   dp=0;
  237.   }
  238. p34=0;p35=0;p36=1;p37=0;
  239.   Delay(200);  p34=0;p35=0;p36=0;p37=0;
  240.    if(SET==1) P0 =LEDData[f];   //显示上限温度十位
  241. else    {    if(f==0) P0=0x00;     //不显示下限温度十位
  242.   else P0 =LEDData[j];  //显示下限温度十位
  243.   }  p34=0;p35=0;p36=0;p37=1;
  244. Delay(200);
  245.   p34=0;p35=0;p36=0;p37=0;          //关闭显示
  246. Delay(20);  
  247. }   
  248. void int0(void) interrupt 0 {     EX0=0;      //关外部中断0
  249. sign=1;  
  250. if(SET==1) shangxian++;  else xiaxian++;
  251.   Delay(500);  EX0=1;
  252. }   /*****外部中断1服务程序*****/
  253. void int1(void)
  254. interrupt 2
  255. {   
  256. EX1=0;      //关外部中断0
  257. sign=1;   if(SET==1) shangxian--;
  258. else xiaxian--;  Delay(500);  EX1=1;
  259.   }   /*****主函数*****/
  260. void main(void)
  261. {   
  262. uint z;
  263. IT0=1;  
  264. IT1=1;
  265.   EX0=1;
  266.   EX1=1;
  267.   EA=1;
  268.    ReadTemperature();
  269.   LING=0;   
  270. for(z=0;z<100;z++)
  271.   {   
  272. Disp_init();     
  273.       }
  274. while(1)  
  275. {      
  276. Disp_Temperature();  
  277. if(sign==1)  
  278. {  
  279. for(z=0;z<300;z++)  
  280.   disptiaozheng();
  281.   sign=0;  
  282. }  
  283. }
  284. }
复制代码





2个文件,都含有仿真和程序

温度显示.rar

156.57 KB, 下载次数: 266, 下载积分: 黑币 -5

DS18B20温度计.rar

69.17 KB, 下载次数: 246, 下载积分: 黑币 -5

评分

参与人数 6黑币 +30 收起 理由
BUDONGYAO + 5
我的autocad2010 + 5 很给力!
急不可待 + 5 很给力!
我的挨地 + 5 赞一个!
你不懂的丶我 + 5
xmd1972 + 5 赞一个!

查看全部评分

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

使用道具 举报

沙发
ID:108622 发表于 2016-10-12 18:39 来自手机 | 只看该作者
赞一个
回复

使用道具 举报

板凳
ID:108622 发表于 2016-10-12 18:40 来自手机 | 只看该作者
迷上温度计
回复

使用道具 举报

地板
ID:77498 发表于 2017-5-3 19:21 | 只看该作者
迷上温度计
回复

使用道具 举报

5#
ID:206965 发表于 2017-6-3 00:42 | 只看该作者
谢谢分享哈!好人一生平安!
回复

使用道具 举报

6#
ID:219090 发表于 2017-7-12 13:02 | 只看该作者
感谢大咖为我指明新路。
回复

使用道具 举报

7#
ID:228837 发表于 2017-8-22 18:58 | 只看该作者
兄弟你有c语言的程序吗?
回复

使用道具 举报

8#
ID:244345 发表于 2017-11-2 17:05 | 只看该作者
有没有设计说明书
回复

使用道具 举报

9#
ID:272215 发表于 2018-1-6 09:25 | 只看该作者
赞一个
回复

使用道具 举报

10#
ID:272470 发表于 2018-1-6 19:00 | 只看该作者
1602显示比较麻烦吧
回复

使用道具 举报

11#
ID:146834 发表于 2018-1-6 21:22 | 只看该作者
要是3年前看见这个程序我就不用破费了
回复

使用道具 举报

12#
ID:283883 发表于 2018-3-12 19:03 | 只看该作者
at89c52应该可以用stc89c52代替吧
回复

使用道具 举报

13#
ID:291942 发表于 2018-3-14 18:51 | 只看该作者
温度计

温度计.rar

81.7 KB, 下载次数: 39, 下载积分: 黑币 -5

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

14#
ID:351921 发表于 2018-6-14 15:44 来自手机 | 只看该作者
可以发一下第二张全图吗?蟹蟹哟!
回复

使用道具 举报

15#
ID:359673 发表于 2018-6-27 14:48 | 只看该作者
请问大神这些程序都是什么功能呢,没有注释看不懂啊

620.png (132.44 KB, 下载次数: 35)

620.png
回复

使用道具 举报

16#
ID:272932 发表于 2018-6-29 23:24 | 只看该作者
非常nice,谢谢
回复

使用道具 举报

17#
ID:283883 发表于 2018-7-30 06:52 | 只看该作者
请问数码管是共阴还是共阳,没安装proteus
回复

使用道具 举报

18#
ID:401573 发表于 2018-9-23 14:45 | 只看该作者
看看,学习下
回复

使用道具 举报

19#
ID:401573 发表于 2018-9-23 15:51 | 只看该作者
第二个仿真里的reset有什么用呢
回复

使用道具 举报

20#
ID:417927 发表于 2018-10-30 15:56 | 只看该作者
很给力,谢谢楼主
回复

使用道具 举报

21#
ID:422278 发表于 2018-11-8 13:45 | 只看该作者
第二张的图下面有点看不到
回复

使用道具 举报

22#
ID:362076 发表于 2018-11-11 19:46 | 只看该作者
你的程序有一个问题,就是在主函数中设置的是unsigned量用来存储温度,而温度全局变量m是signed 的,这样你显示的时候调用temp位处理之后,温度的负值就会显示不正确。
回复

使用道具 举报

23#
ID:425523 发表于 2018-11-13 10:20 | 只看该作者
非常好,这个帖子
回复

使用道具 举报

24#
ID:418772 发表于 2018-11-17 21:23 | 只看该作者
迫切需要
回复

使用道具 举报

25#
ID:243394 发表于 2019-7-13 09:40 | 只看该作者
很给力,谢谢楼主
回复

使用道具 举报

26#
ID:658207 发表于 2019-12-9 15:43 来自手机 | 只看该作者
请问楼主,6mhz换成11.0592mhz应该怎么改程序呢
回复

使用道具 举报

27#
ID:761335 发表于 2020-5-26 09:42 | 只看该作者
非常好,这个帖子
回复

使用道具 举报

28#
ID:280206 发表于 2020-5-26 11:46 | 只看该作者
本帖最后由 haikuotian 于 2020-5-27 06:36 编辑

18B20的输出状态 26.5 度

回复

使用道具 举报

29#
ID:764266 发表于 2020-5-30 16:03 | 只看该作者
很给力
回复

使用道具 举报

30#
ID:786665 发表于 2020-6-22 14:47 | 只看该作者
回复

使用道具 举报

31#
ID:786665 发表于 2020-6-22 14:51 | 只看该作者
第一个程序,头文件里面是不是还封装了什么?报错误打不开
回复

使用道具 举报

32#
ID:787020 发表于 2020-6-23 11:44 来自手机 | 只看该作者
程序不对把
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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