找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机与DS18B20设计温度报警器程序 可设置上下限

  [复制链接]
跳转到指定楼层
楼主
ID:70650 发表于 2014-12-18 01:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在51hei论坛找了几天资料后。昨天开始使用模块化编程,让DS18B20在液晶上显示。中间出现了一些问题,纠结了一天。后来才发现在.h文件里面用到的一些变量我只声明了,但是没在.c文件里面进行定义,导致了编译出现很多警告,而且液晶显示不正常。

这个问题发现之后,我又接着把程序修改了一下,加上了按键调节报警温度的上下限,并且可以切换显示测到的温度和自己设置的报警温度,嘿嘿程序就在下面



工程40文件.zip (63.44 KB, 下载次数: 1100)

评分

参与人数 5黑币 +25 收起 理由
wyx13777 + 5 很给力!
ficklelww + 5 很给力!
lzj602015234 + 5 很给力!
1136918172 + 5 很给力!
h832ea + 5 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:70650 发表于 2014-12-18 01:29 | 只看该作者
主要代码预览
DS18B20.c文件:
  1. //------------------------------------------------------
  2. //用数码管与DS18B20设计温度报警器
  3. //------------------------------------------------------
  4. //本例将报警温度设为高:40度 低:-3度,当DS18B20感知到温度达到此临界值时
  5. //系统发出报警声
  6. #include <REG52.H>
  7. #include <intrins.h>
  8. #include "delay.h"
  9. #include "DS18B20.h"

  10. uchar display_digit[4]={0,0,0,0};                  //待显示的各温度数位
  11. uchar LCD_display[16]="                ";                  //LCD显示的温度值
  12. uchar LCD_alarm_display[16]="H:      L:      ";          //显示报警温度
  13. bit HI_Alarm=0,LO_Alarm=0;                 //高低温报警标志
  14. bit DS18B20_IS_OK;                        //传感器正常标志

  15. //温度小数位对照表
  16. uchar code df_table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
  17. //报警温度上下限,为进行正负数比较,此处注意设为char类型
  18. //取值范围为-128~+127,DS18B20支持范围为-50~+125
  19. char Alarm_temp_HL[4]={30,-3,0,0};//报警温度预设及存储

  20. uchar currentT=0;                                                  //当前读取的温度整数部分
  21. uchar temp_value[]={0x00,0x00};                          //从DS18B20读取的温度值
  22. //初始化DS18B20
  23. uchar init_DS18B20()
  24. {
  25.         uchar status;
  26.         DQ=1; delay(8);
  27.         DQ=0; delay(90);
  28.         DQ=1; delay(8);
  29.         status=DQ;
  30.         delay(100);
  31.         DQ=1;
  32.         return status;          //初始化成功时返回0
  33. }

  34. //读一字节
  35. uchar readonebyte()
  36. {
  37.         uchar i,dat=0;
  38.         DQ=1; _nop_();
  39.         for(i=0;i<8;i++)
  40.         {
  41.            DQ=0;dat>>=1;
  42.            DQ=1;_nop_();_nop_();//拉高,延时进行采样 单总线是进行与的
  43.            if(DQ) dat|=0x80;  //如果DQ是1,把1存到dat里
  44.            delay(30);DQ=1;
  45.         }
  46.         return dat;
  47. }

  48. //写一字节
  49. void writeonebyte(uchar dat)
  50. {
  51.         uchar i;
  52.         for(i=0;i<8;i++)
  53.         {
  54.                 DQ=0;DQ=dat&0x01; //先取最低位,先读的也是最低位
  55.                 delay(5);DQ=1;dat>>=1;
  56.         }
  57. }

  58. //读取温度值
  59. void read_temp()
  60. {
  61.         if(init_DS18B20()==1)        //DS18B20故障
  62.                 DS18B20_IS_OK=0;
  63.         else
  64.         {
  65.                 writeonebyte(0xcc);          //跳过序列号
  66.                 writeonebyte(0x44);          //启动温度转换
  67.                 init_DS18B20();
  68.                 writeonebyte(0xcc);          //跳过序列号
  69.                 writeonebyte(0xbe);          //读取温度寄存器
  70.                 temp_value[0]=readonebyte(); //        温度低8位
  71.                 temp_value[1]=readonebyte(); //        温度高8位
  72.                 Alarm_temp_HL[2]=readonebyte(); //报警温度TH
  73.                 Alarm_temp_HL[3]=readonebyte(); //报警温度TL
  74.                 DS18B20_IS_OK=1;
  75.         }       
  76. }

  77. //设置DS18B20温度报警值
  78. void set_Alarm_temp()
  79. {
  80.         init_DS18B20();
  81.         writeonebyte(0xcc);          //跳过序列号
  82.         writeonebyte(0x4e);          //将设定的温度报警值写入DS18B20
  83.         writeonebyte(Alarm_temp_HL[0]);  //写TH
  84.     writeonebyte(Alarm_temp_HL[1]);  //写TL
  85.     writeonebyte(0x7f);                                //12位精度
  86.         init_DS18B20();
  87.         writeonebyte(0xcc);          //跳过序列号
  88.         writeonebyte(0x48);          //温度报警值存入DS18B20
  89. }

  90. //在液晶上显示温度处理
  91. void chuli_temp()
  92. {
  93. //------------------显示温度处理-------------------------
  94.         uchar ng=0;           //负数标识
  95.         uchar t=150;                 //延时值
  96.         char signed_current_temp;                //注意类型为char
  97.         //如果为负数则取反加1,并设置负号标识及负号显示位置
  98.         if((temp_value[1]&0xf8)==0xf8)
  99.         {
  100.                 temp_value[1]=~temp_value[1];
  101.                 temp_value[0]=~temp_value[0]+1;
  102.                 if(temp_value[0]==0x00) temp_value[1]++;
  103.                 ng=1;
  104.        
  105.         }
  106.   //查表得到温度小数部分
  107.   display_digit[0]=df_table[temp_value[0]&0x0f];
  108.   //获取温度整数部分(无符号)
  109.   currentT=((temp_value[0]&0xf0)>>4)|((temp_value[1]&0x07)<<4);
  110.   //有符号的当前温度值,注意定义为char,其值可为-128~+127
  111.   signed_current_temp=ng?-currentT:currentT;
  112.   //高低温报警标志设置(与定义为char类型的Alarm_temp_HL比较,这样可区分正负比较)
  113.   HI_Alarm=signed_current_temp>=Alarm_temp_HL[2]? 1 : 0;
  114.   LO_Alarm=signed_current_temp<=Alarm_temp_HL[3]? 1 : 0;
  115.   //将整数部分分解为三位待显示数字
  116.   display_digit[3]=currentT/100;
  117.   display_digit[2]=currentT%100/10;
  118.   display_digit[1]=currentT%10;
  119.   //LCD显示数据
  120.   LCD_display[2]=display_digit[3]+'0';          //bai
  121.   LCD_display[3]=display_digit[2]+'0';          //shi
  122.   LCD_display[4]=display_digit[1]+'0';          //ge
  123.   LCD_display[5]='.';
  124.   LCD_display[6]=display_digit[0]+'0';          //xiaoshu
  125.   LCD_display[7]=0xdf;                                 //。
  126.   LCD_display[8]=0x43;                                 // C

  127.   if(display_digit[3]==0)                          
  128.           {
  129.                     LCD_display[2]=' ';                        //高位为0则不显示               
  130.                   if(display_digit[2]==0)
  131.                   {
  132.                           LCD_display[3]=' ';
  133.                   }
  134.           }
  135.         //负号显示在恰当位置
  136.         if(ng)
  137.                   {
  138.                           if(LCD_display[3]==' ')
  139.                                 LCD_display[3]='-';
  140.                         else if(LCD_display[2]==' ')
  141.                                 LCD_display[2]='-';
  142.                         else LCD_display[1]='-';
  143.                   }
  144. //------------------------------------------------------

  145. }

  146. void chuli_alarm_temp()
  147. {
  148. //---------------------报警温度处理---------------------
  149.    uchar ng;
  150.    //由于Alarm_temp_HL类型为char 故可以直接进行正负比较
  151.    //高温报警值
  152.    ng=0;
  153.    if(Alarm_temp_HL[2]<0)
  154.    {
  155.               Alarm_temp_HL[2]=~Alarm_temp_HL[2]+1;
  156.            ng=1;
  157.    }
  158.    //分解高温各数位到待显示数组中
  159.    LCD_alarm_display[3]=Alarm_temp_HL[2]/100+'0';
  160.    LCD_alarm_display[4]=Alarm_temp_HL[2]%100/10+'0';
  161.    LCD_alarm_display[5]=Alarm_temp_HL[2]%10+'0';
  162.    //屏蔽高位不为0的
  163.    if(LCD_alarm_display[3]=='0') LCD_alarm_display[3]=' ';
  164.    if(LCD_alarm_display[3]==' ' && LCD_alarm_display[4]=='0')
  165.        LCD_alarm_display[4]=' ';
  166.         //'-' 显示
  167.    if(ng)
  168.    {
  169.                    if(LCD_alarm_display[4]==' ') LCD_alarm_display[4]='-';
  170.                 else
  171.                 if(LCD_alarm_display[3]==' ') LCD_alarm_display[3]='-';
  172.                 else LCD_alarm_display[2]='-';
  173.    }
  174.    //低温报警值
  175.    ng=0;
  176.    if(Alarm_temp_HL[3]<0)
  177.    {
  178.               Alarm_temp_HL[3]=~Alarm_temp_HL[3]+1;
  179.            ng=1;
  180.    }
  181.    //分解高温各数位到待显示数组中
  182.    LCD_alarm_display[11]=Alarm_temp_HL[3]/100+'0';
  183.    LCD_alarm_display[12]=Alarm_temp_HL[3]%100/10+'0';
  184.    LCD_alarm_display[13]=Alarm_temp_HL[3]%10+'0';
  185.    //屏蔽高位不为0的
  186.    if(LCD_alarm_display[11]=='0') LCD_alarm_display[11]=' ';
  187.    if(LCD_alarm_display[11]==' ' && LCD_alarm_display[12]=='0')
  188.        LCD_alarm_display[12]=' ';
  189.         //'-' 显示
  190.    if(ng)
  191.    {
  192.                    if(LCD_alarm_display[12]==' ') LCD_alarm_display[12]='-';
  193.                 else
  194.                 if(LCD_alarm_display[11]==' ') LCD_alarm_display[11]='-';
  195.                 else LCD_alarm_display[10]='-';
  196.    }
  197. //------------------------------------------------------
  198. }

复制代码

评分

参与人数 1黑币 +5 收起 理由
青顶云上 + 5

查看全部评分

回复

使用道具 举报

板凳
ID:70769 发表于 2014-12-20 19:48 | 只看该作者
很好,正需要
回复

使用道具 举报

地板
ID:76267 发表于 2015-4-6 21:50 | 只看该作者
顶一个
回复

使用道具 举报

5#
ID:76267 发表于 2015-4-6 21:51 | 只看该作者
楼主,ds1820报警有米有
回复

使用道具 举报

6#
ID:74826 发表于 2015-4-11 15:34 | 只看该作者
正在做相关方面程序设计,借鉴一下
回复

使用道具 举报

7#
ID:77724 发表于 2015-4-22 16:19 | 只看该作者
楼主有这个程序的电路图吗?
回复

使用道具 举报

8#
ID:77760 发表于 2015-4-24 16:23 | 只看该作者
谢谢分享,太好了正好需要。
回复

使用道具 举报

9#
ID:77760 发表于 2015-4-24 16:24 | 只看该作者
谢谢分享,太好了正好需要。
回复

使用道具 举报

10#
ID:75461 发表于 2015-4-26 10:48 | 只看该作者
好资料,收下了,谢谢
回复

使用道具 举报

11#
ID:77720 发表于 2015-4-27 14:09 | 只看该作者
,有仿真图嘛
回复

使用道具 举报

12#
ID:78521 发表于 2015-4-30 12:33 | 只看该作者
正需要~~~谢谢
回复

使用道具 举报

13#
ID:78896 发表于 2015-5-4 22:42 | 只看该作者
好东西
回复

使用道具 举报

14#
ID:66287 发表于 2015-5-29 08:21 | 只看该作者
看看楼主有何独招,谢谢分享!
回复

使用道具 举报

15#
ID:81503 发表于 2015-5-29 18:07 | 只看该作者
好东西
回复

使用道具 举报

16#
ID:7992 发表于 2015-5-30 17:33 | 只看该作者
谢谢你提供的程序,学习一下。
回复

使用道具 举报

17#
ID:85838 发表于 2015-7-16 15:10 | 只看该作者
好东西
回复

使用道具 举报

18#
ID:93949 发表于 2015-10-29 07:49 来自手机 | 只看该作者
好东东、太给力了!
回复

使用道具 举报

19#
ID:66287 发表于 2015-10-29 10:16 | 只看该作者
谢谢楼主的无私奉献,顶
回复

使用道具 举报

20#
ID:11064 发表于 2015-11-1 11:53 | 只看该作者
LCD 在线液晶显示器技术手册 J12864 中文/JGD12864 中文/FY12864Z
1
液晶显示模块技术手册
J12864 中文/JGD12864 中文/FY12864ZW
:(1)模组背部自带 10K 3*3 硬封可调电位器,可以调到
对比度
LED 背光极性可调,JP4 为液晶背光正负反接处,此模组
为 4 颗 LED 灯,非普通背光
模组自带原装三星正品防静电电容, 抗干扰性更强 C6 C
串并口可通过两种方式调节 1 PSB 脚控制 2 JP2 短路到
口 短路到-为串口
自改 3.3V 可通过 JP3 调节, 默认接+级为 5V, 接-为 3.3V
5 加极性电容即可 型号
06A 14FH4,背光电阻 33 欧改成 3.3 欧
回复

使用道具 举报

21#
ID:11064 发表于 2015-11-3 19:45 | 只看该作者
#include<reg52.h> //包含头文件,不需要改动,头文件包含特殊功能寄存器的定义

sbit LED0 = P2^0;   // 用sbit关键字定义LED到P2.0端口


void Delay(unsigned int t); //函数声明
/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main (void)
{
                  
        unsigned int TIME=300,PWM=0;//定义周期并赋值
        while (1)         //主循环
          {
                LED0=1;
                Delay(50000);        //特意加延时,可以看到熄灭的过程

/* 阶段1:这个循环中低电平时长从1累加到TIME(周期)的值,我们可以看到灯逐渐变亮 */
                for(PWM=1; PWM<TIME; PWM++)
                {  
                           LED0=0;        //点亮LED  
                           Delay(PWM);//延时长度,300次循环中从1加至299
                           LED0=1;        //熄灭LED
                      Delay(TIME-PWM);//延时长度,300次循环中从299减至1   
                   }

                LED0=0; /*阶段2:开始全亮*/

/* 阶段3:这个循环中低电平时长从TIME(周期)的值逐减到0,我们可以看到灯逐渐变暗 */
                for(PWM=TIME-1; PWM>0; PWM--)
                { //与逐渐变亮相反的过程
                           LED0=0;
                           Delay(PWM);
                           LED0=1;
                      Delay(TIME - PWM);     
                   }
                     //主循环中添加其他需要一直工作的程序
          }
}
/*------------------------------------------------
延时函数,含有输入参数 unsigned int t,无返回值
unsigned int 是定义无符号整形变量,其值的范围是
0~65535
------------------------------------------------*/
void Delay(unsigned int t)
{
while(--t);
}
回复

使用道具 举报

22#
ID:11064 发表于 2015-11-3 19:46 | 只看该作者
#include<reg52.h> //包含头文件,一般情况不需要改动,
//头文件包含特殊功能寄存器的定义

sbit LED0=P2^0;// 用sbit 关键字 定义 LED到P2.0端口,
sbit LED1=P2^1;
//LED是自己任意定义且容易记忆的符号

void Delay(unsigned int t); //函数声明
/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main (void)
{
                  //此方法使用bit位对单个端口赋值


        while (1)         //主循环
          {
                  LED0=0;            //将P2.0口赋值 0,对外输出低电平
                LED1=0;
                  Delay(20000);      //调用延时程序;更改延时数字可以更改延时长度;
                                //用于改变闪烁频率
                  LED0=1;            //将P2.0口赋值 1,对外输出高电平
                LED1=1;
                  Delay(20000);
                     //主循环中添加其他需要一直工作的程序
          }
}

/*------------------------------------------------
延时函数,含有输入参数 unsigned int t,无返回值
unsigned int 是定义无符号整形变量,其值的范围是
0~65535
------------------------------------------------*/
void Delay(unsigned int t)
{
while(--t);
}
回复

使用道具 举报

23#
ID:11064 发表于 2015-11-3 21:09 | 只看该作者
#include <REG51.H>
#include "array.h"

//--重定义函数变量--//
#define uchar unsigned char
#define uint  unsigned int
#define ulong unsigned long

//--定义SPI要使用的 IO--//
sbit MOSIO = P3^4;
sbit R_CLK = P3^5;
sbit S_CLK = P3^6;

//--全局函数声明--//
void HC595SendData(  uchar BT3, uchar BT2,uchar BT1,uchar BT0);
                                                                                                                                                                                       
/*******************************************************************************
* 函 数 名         : main
* 函数功能                   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/

void main(void)
{   
   int k, i, ms;

   //--定义一个指针数据指向汉字--//
   uchar *p[] = {
                                    tab1, tab2, tab3, tab4, tab5, tab6, tab7, tab8,
                                 tab9, tab10, tab11, tab12, tab13, tab14, tab15};                                               
        while(1)
        {
                for(i = 0; i < 15; i++)                //总共15个字
                {
                        for(ms = 50; ms > 0; ms--)        //显示50次,即肉眼可识别的停留时间
                        {
                                for(k = 0; k < 16; k++)                        //显示一个字
                                {                                                        
                                        //--因为字模软件取的数组是高电平有效,所以列要取反--//
                                        HC595SendData(~(*(p[i] + 2*k + 1)),~(*(p[i] + 2*k )),
                                                       tab0[2*k],tab0[2*k + 1]);
                                }

                                HC595SendData(0xff,0xff,0,0);                                //清屏                 
                        }
                }                                                                                
        }
}

/*******************************************************************************
* 函 数 名         : HC595SendData
* 函数功能                   : 通过595发送四个字节的数据
* 输    入         : BT3:第四个595输出数值
*                  * BT2: 第三个595输出数值
*                  * BT1:第二个595输出数值
*                  * BT0:第一个595输出数值
* 输    出         : 无
*******************************************************************************/

void HC595SendData(  uchar BT3, uchar BT2,uchar BT1,uchar BT0)
{  
        uchar i;
       
        //--发送第一个字节--//
        for(i=0;i<8;i++)
        {
                MOSIO = BT3 >> 7 ;        //从高位到低位
                BT3 <<= 1;

                S_CLK = 0;
                S_CLK = 1;               
        }

        //--发送第一个字节--//
        for(i=0;i<8;i++)
        {
                MOSIO = BT2 >>7;                //从高位到低位
                BT2 <<= 1;

                S_CLK = 0;
                S_CLK = 1;       
        }

        //--发送第一个字节--//
        for(i=0;i<8;i++)
        {
                MOSIO = BT1 >> 7;                //从高位到低位
                BT1 <<= 1;
                S_CLK = 0;
                S_CLK = 1;       
        }

        //--发送第一个字节--//
        for(i=0;i<8;i++)
        {
                MOSIO = BT0 >> 7;                //从高位到低位
                BT0 <<= 1;
                S_CLK = 0;
                S_CLK = 1;
        }
   
        //--输出--//
        R_CLK = 0; //set dataline low
        R_CLK = 1; //片选
        R_CLK = 0; //set dataline low
}





回复

使用道具 举报

24#
ID:80741 发表于 2015-11-6 16:44 | 只看该作者
学习了,下载来,研究研究
回复

使用道具 举报

25#
ID:98305 发表于 2015-12-4 14:41 | 只看该作者
看看是不是正需要的
回复

使用道具 举报

26#
ID:102260 发表于 2016-1-7 16:28 | 只看该作者
楼主太棒了
回复

使用道具 举报

27#
ID:102627 发表于 2016-1-10 13:02 | 只看该作者
楼主太棒啦
回复

使用道具 举报

28#
ID:112336 发表于 2016-4-5 16:21 | 只看该作者
不错的,学习一下
回复

使用道具 举报

29#
ID:119479 发表于 2016-5-9 12:25 | 只看该作者
借鉴下。希望能行
回复

使用道具 举报

30#
ID:121652 发表于 2016-5-18 11:22 | 只看该作者
为什么我下载烧录了后LCD上第一行和第二行只显示了“Now Wen Du”,“NO NO”,并没有温度显示,按键也没反应,楼主求解
回复

使用道具 举报

31#
ID:123373 发表于 2016-5-26 17:47 | 只看该作者
必须给楼楼点赞
回复

使用道具 举报

32#
ID:123916 发表于 2016-5-31 20:42 | 只看该作者
谢谢很有用,已经急哭了。。
回复

使用道具 举报

33#
ID:124367 发表于 2016-6-1 14:47 | 只看该作者
谢谢楼主分享,我遇到的情况和30#一样的 “LCD上第一行和第二行只显示了“Now Wen Du”,“NO NO”,并没有温度显示”,想请教下楼主电路图是什么样的,虽然已经2年多了....
回复

使用道具 举报

34#
ID:124627 发表于 2016-6-2 10:04 | 只看该作者
谢谢楼主分享经验
回复

使用道具 举报

35#
ID:122434 发表于 2016-6-2 15:49 | 只看该作者
这个必须要好好学习
回复

使用道具 举报

36#
ID:122434 发表于 2016-6-2 15:50 | 只看该作者
必须给楼楼点赞
回复

使用道具 举报

37#
ID:128596 发表于 2016-6-29 19:50 | 只看该作者
多谢楼主分享,对我很有帮助
回复

使用道具 举报

38#
ID:127965 发表于 2016-7-1 07:19 | 只看该作者
jiujiu 发表于 2014-12-18 01:29
主要代码预览
DS18B20.c文件:

挺好 谢谢
回复

使用道具 举报

39#
ID:136144 发表于 2016-8-6 20:58 | 只看该作者
很好,正需要
回复

使用道具 举报

40#
ID:147529 发表于 2016-11-12 15:38 | 只看该作者
???????????????????
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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