单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
上一页
1/3
下一页
查看:18823|回复:110
打印上一主题下一主题

基于DS18B20的数显温度计 数码管显示

 [复制链接]
跳转到指定楼层
楼主
ID:362076发表于 2018-7-24 08:35|只看该作者|只看大图回帖奖励
本帖最后由 凌净清河 于 2018-7-24 08:38 编辑

本作品采用STC15F104W单片机和四位共阴极数码管设计

主要亮点:
1.数码管使用74HC595作为段选驱动,为初学者提供了新的思路
次要亮点:
1.使用小巧的STC15F104W单片机

DS18B20的通信要点在于时序的严格对应,相比之下DHT11这一类的单总线通信时序要求更加宽松。
因为DS18B20算是极为常用的学习器件,故不做过多讲解,本次作品不涉及搜索BOM、精度调节等操作,只是单器件读取温度值,数据处理将可以显示的温度值设置为-20℃~80℃。

(事实证明不同器件之间会有差异,读取的值也会不尽相同)

DS18B20数据处理参考普中科技相关例程



#include<STC15.H>
sbit DSPORT=P3^5;//DS18B20管脚定义
#include<intrins.h>
#include"DS18B20.c"
sbit S1=P3^4;
sbit S2=P3^3;//数码管位选管脚定义
sbit SER=P3^0;
sbit RCLK=P3^1;
sbit SRCLK=P3^2;//74HC595管脚定义

//全局变量表
unsigned char code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//给74HC595的段选值
unsigned char Display_Temperature[4]={0x40,0x40,0x40,0x40};
int Data_temperature=0;
unsigned char t0_cnt=0;
/*##############################################################################################
设计名称:基于DS18B20的数显温度计
设计者:清河

平台:STC15F104W
硬件部分
数码管显示:位选使用74HC138改为2-4线译码、段选使用74HC595减少IO口使用
   使用4位共阴极数码管,显示无符号位

注意:由于STC15系列采用Y5内核,所以有关DS18B20精准延时部分在移植时应首先考虑更换
##############################################################################################*/
void delay(unsigned int cnt)//调用该函数进行一段时间的延时
{
   while(cnt--);
}

void hc595send(unsigned char dat)//使用SPI向74HC595发送一个字节的数据                      
{  
   unsigned char a;
   SRCLK=0;
   RCLK=0;
   for(a=0;a<8;a++)
   {
       SER=dat>>7;
       dat<<=1;
       SRCLK=1;
       _nop_();
       _nop_();
       SRCLK=0;  
   }
   RCLK=1;
   _nop_();
   _nop_();
   RCLK=0;
}

void smgdisplay()//数码管显示函数,参数为需要显示的数组
{
   unsigned char i;
   for(i=0;i<4;i++)
   {
       switch(i)//位选,选择点亮的数码管
       {
         case(0):
           S1=0;S2=1; break;
         case(1):
           S1=1;S2=0; break;
         case(2):
           S1=0;S2=0; break;
         case(3):
           S1=1;S2=1; break;  
       }
       hc595send(Display_Temperature);
       delay(10); //间隔一段时间扫描  
       hc595send(0x00);//消隐
   }
}

void Data_processing()
{
   float temperature=0.0;//【03c4】似乎只是一个用于更改值为float类型的中间变量,考虑删去
   int temperature_middle;//为了不更改全局变量中读取出来的Data_temperature设置此中转值
   if(Data_temperature>0xf000)//当温度值为负数
   {
       Display_Temperature[0]=0x40;//显示符号“-”的段码
       //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
       temperature_middle=Data_temperature-1;
       temperature_middle=~temperature_middle;
       temperature=temperature_middle;
       temperature_middle=temperature*0.0625*100+0.5;  
       //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
       //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
       //算加上0.5,还是在小数点后面。
       if(temperature_middle<2000)
       {
         if(temperature_middle>=1000)
         {
           Display_Temperature[1]=smgduan[temperature_middle%10000/1000];
           Display_Temperature[2]=smgduan[temperature_middle%1000/100]|0x80;
           Display_Temperature[3]=smgduan[temperature_middle%100/10];
         }
         else
         {
           Display_Temperature[1]=smgduan[temperature_middle%1000/100]|0x80;
           Display_Temperature[2]=smgduan[temperature_middle%100/10];
           Display_Temperature[3]=smgduan[temperature_middle%10];
         }
       }
       else
       {
         unsigned char i;
         for(i=0;i<4;i++)
         {
           Display_Temperature=0x40;
         }
       }
   }
   else
   {
       temperature=Data_temperature;//因为数据处理有小数点所以将温度赋给一个浮点型变量
       //如果温度是正的那么,那么正数的原码就是补码它本身
       temperature_middle=(int)(temperature*0.0625*100+0.5);  
       //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
       //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
       //算加上0.5,还是在小数点后面。
       if(temperature_middle<8000)
       {
         if(temperature_middle>=1000)
         {
           Display_Temperature[0]=smgduan[temperature_middle%10000/1000];
           Display_Temperature[1]=smgduan[temperature_middle%1000/100]|0x80;
           Display_Temperature[2]=smgduan[temperature_middle%100/10];
           Display_Temperature[3]=smgduan[temperature_middle%10];
         }
         else
         {
           Display_Temperature[0]=0x00;
           Display_Temperature[1]=smgduan[temperature_middle/100]|0x80;
           Display_Temperature[2]=smgduan[temperature_middle%100/10];
           Display_Temperature[3]=smgduan[temperature_middle%10];
         }
       }
       else
       {
         unsigned char i;
         for(i=0;i<4;i++)
         {
           Display_Temperature=0x40;
         }
       }
   }
}

void sys_init()
{
   TH0=0;
   TL0=0;
   ET0=1;
   TR0=1;
   EA=1;
}

void main()
{
   sys_init();
   while(1)
   {
       smgdisplay();
   }
}

void Temperature_Refresh() interrupt 1
{
   TL0 = 0x00;
   TH0 = 0x28;//5ms初值
   if(t0_cnt==10)
   {
       hc595send(0x00);
       Data_temperature=DS18B20_GetTemperature();
       Data_processing();
       t0_cnt=0;
   }
   else
   {
       t0_cnt++;
   }
}
由于中断时的数据读取和处理会占用一部分时间,导致数码管有轻微闪烁感,使用者可以考虑将转换精度调为最低并修改转换等待时间以减少数码管的闪烁感,同时别忘记调一下数据处理函数中对应的精度值。
上述程序仍然臃肿,但由于是普通器件的使用,没有难点,所以也没有进行优化,以完成功能为目的。


新矿城学习基地 凌净清河
游客,如果您要查看本帖隐藏内容请回复

评分

黑币 +110
收起理由
+ 30
赞一个!
+ 30
+ 50
共享资料的黑币奖励!

查看全部评分

沙发
ID:350006发表于 2018-7-26 10:41|只看该作者
温度读取值怎么转换?
板凳
ID:362076发表于 2018-7-26 16:57|只看该作者
空格键~~ 发表于 2018-7-26 10:41
温度读取值怎么转换?

温度转换在Data_processing()函数中,分正负数之后,temperature_middle就是转换之后温度值*100
地板
ID:323496发表于 2018-7-26 19:36|只看该作者
可否有源程序和电路图可以下载
5#
ID:362076发表于 2018-7-27 12:57|只看该作者
manpingshui 发表于 2018-7-26 19:36
可否有源程序和电路图可以下载

源程序回复之后就应该可以下载了,原理图没有的,74HC595驱动数码管的典型应用电路在STC单片机的手册上可以找到,138是基本模块也不用解释,单片机一共就6个IO口,定义在程序开头处已经表明出来了,尝试一下,看不明白再问。
6#
ID:203000发表于 2018-7-28 08:08|只看该作者
这个温度计的硬件设计思路很好。简单实用。
7#
ID:79874发表于 2018-7-28 15:59|只看该作者
下载学习下
8#
ID:56186发表于 2018-8-8 23:02|只看该作者
下载学习下
9#
ID:385800发表于 2018-8-13 14:55|只看该作者
喜欢。。。。。。。。。。。。
10#
ID:108366发表于 2018-8-21 16:19|只看该作者
下载学习下
11#
ID:108366发表于 2018-8-21 16:19|只看该作者
下载学习下
12#
ID:388788发表于 2018-8-22 10:05|只看该作者
下载学习下
13#
ID:65956发表于 2018-8-22 11:16|只看该作者
我一直有要作这个的方案,结果让你先实现了
14#
ID:362076发表于 2018-9-4 21:51|只看该作者
aking991 发表于 2018-8-22 11:16
我一直有要作这个的方案,结果让你先实现了

hhh,不好意思啦~不过你可以试试别的模块呀,BMP180、DHT11、这些常用的传感器精度和可用性都不输于DS18B20,配上OLED小屏幕,再加一个无线显示功能,无线方式传输显示多个不同位置传感器的数据。

评分

黑币 +50
收起理由
+ 50
回帖助人的奖励!

查看全部评分

15#
ID:90140发表于 2018-9-5 08:19|只看该作者
下载学习下
16#
ID:33449发表于 2018-9-5 10:07|只看该作者
谢谢分享
17#
ID:33544发表于 2018-9-9 08:47|只看该作者
学习数码管显示
18#
ID:187675发表于 2018-9-9 09:19|只看该作者
可否有源程序和电路图可以下载
19#
ID:187675发表于 2018-9-9 09:21|只看该作者
学习数码管显示
20#
ID:386381发表于 2018-9-9 16:08来自手机|只看该作者
这个比较小巧经典
21#
ID:388870发表于 2018-9-10 15:43|只看该作者
谢谢分享
22#
ID:87193发表于 2018-9-11 10:43|只看该作者
回复了看下,学习了
23#
ID:362076发表于 2018-9-11 11:08|只看该作者
rs7cai 发表于 2018-9-9 09:19
可否有源程序和电路图可以下载

这个真没有,这款单片机只有6个IO,DS18B20是单总线通信,再加上一个595驱动的数码管显示电路,当初制作的时候是直接焊接的,根本没画电路图。
24#
ID:310820发表于 2018-9-17 22:53|只看该作者
感谢分享,
25#
ID:16663发表于 2018-9-18 22:06来自手机|只看该作者
下载学习一下
26#
ID:216625发表于 2018-9-19 17:52|只看该作者
谢谢分享,
27#
ID:258542发表于 2018-9-23 16:33|只看该作者
新手学习学习温度模块
28#
ID:291850发表于 2018-10-8 16:26|只看该作者
学习学习
29#
ID:405456发表于 2018-10-8 21:50来自手机|只看该作者
做得很漂亮

评分

黑币 +5
收起理由
+ 5
蟹蟹!

查看全部评分

30#
ID:409954发表于 2018-10-15 21:41|只看该作者
下载学习下
31#
ID:204228发表于 2018-10-16 08:40|只看该作者
谢谢分享!
32#
ID:101014发表于 2018-10-18 11:22来自手机|只看该作者
楼主厉害啊

评分

黑币 +15
收起理由
+ 15
蟹蟹,不过没有很厉害啦

查看全部评分

33#
ID:3212发表于 2018-10-18 14:21|只看该作者
用C语言好几次都不成功(导师说是1T的51单片机定时中断不好控制),改成汇编的就行了。佩服楼主调试的耐性。

评分

黑币 +15
收起理由
+ 15
其实还好,这些器件的通讯协议没有特别严格.

查看全部评分

34#
ID:148003发表于 2018-10-18 15:14|只看该作者
谢谢作者的分享和制作

评分

黑币 +15
收起理由
+ 15
蟹蟹,客气了~

查看全部评分

35#
ID:58241发表于 2019-4-10 18:34|只看该作者
简单实用!!1

评分

黑币 +12
收起理由
+ 12
黑币补贴

查看全部评分

36#
ID:499474发表于 2019-4-11 01:30来自手机|只看该作者
不错,顶一下

评分

黑币 +12
收起理由
+ 12
黑币补贴

查看全部评分

37#
ID:106887发表于 2019-4-11 08:49|只看该作者
学习一下

评分

黑币 +12
收起理由
+ 12
黑币补贴

查看全部评分

38#
ID:509665发表于 2019-4-11 19:21来自手机|只看该作者
学习一下

评分

黑币 +12
收起理由
+ 12
黑币补贴

查看全部评分

39#
ID:510842发表于 2019-4-12 21:46|只看该作者
给您点赞

评分

黑币 +12
收起理由
+ 12
黑币补贴

查看全部评分

40#
ID:171746发表于 2019-4-14 10:32|只看该作者
下来学习

评分

黑币 +12
收起理由
+ 12
黑币补贴

查看全部评分

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

Powered by 单片机教程网