找回密码
 立即注册

QQ登录

只需一步,快速开始

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

DS1820的测温报警程序 温控程序 求助

[复制链接]
跳转到指定楼层
楼主
ID:67818 发表于 2014-10-23 15:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我想写个DS1820的测温报警程序,现在只把温度显示出来了,但是报警却不会做,报警范围就是在室温大于70度时就亮一个LED灯并且发出警报,室温小于-20度时就蓝灯亮同时发出警报。希望热心人帮帮我,我的QQ860689974
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:67818 发表于 2014-10-23 15:25 | 只看该作者
这是我的程序#include<reg51.h> #include<intrins.h> #define uchar unsigned char #define uint unsigned int  sbit bz=P3^7; sbit ledH=P2^3; sbit ledL=P2^6;         sbit DQ=P3^3;//ds18b20与单片机连接口 sbit RS=P2^0; sbit RW=P2^1; sbit EN=P2^2;  unsigned char code str1[]={"temperature:  "}; unsigned char code str2[]={"              "};   uchar data disdata[5]; uint tvalue;//温度值 uchar tflag;//温度正负标志  /*************************lcd1602程序**************************/  void delay1ms(unsigned int ms)  {unsigned int i,j;    for(i=0;i<ms;i++)     for(j=0;j<100;j++);  }         //蜂铃器  void buzzer()   {           while(1)       {           bz=~bz;         }        }           void wr_com(unsigned char com)//写指令//  {  delay1ms(1);    RS=0;    RW=0;    EN=0;    P0=com;    delay1ms(1);    EN=1;    delay1ms(1);    EN=0;   }  void wr_dat(unsigned char dat)//写数据// {  delay1ms(1);;    RS=1;    RW=0;    EN=0;    P0=dat;    delay1ms(1);    EN=1;    delay1ms(1);    EN=0; }   void lcd_init()//初始化设置// {delay1ms(15);  wr_com(0x38);delay1ms(5);  wr_com(0x08);delay1ms(5);  wr_com(0x01);delay1ms(5);  wr_com(0x06);delay1ms(5);  wr_com(0x0c);delay1ms(5);  bz=0;   ledH=0;   ledL=0; }    void display(unsigned char *p)//显示// { while(*p!='\0') { wr_dat(*p); p++; delay1ms(1); } }    init_play()//初始化显示   { lcd_init();     wr_com(0x80);          display(str1);          wr_com(0xc0);          display(str2);       wr_com(0xc7);       wr_dat(0xdf);       wr_com(0xc8);       wr_dat(0x43);            }  /******************************ds1820程序***************************************/  delay_18B20(uint t) {         for(t=11;t>0;t--); }  void ds1820rst()/*ds1820复位*/  {           uint i;                    //不能用uchar i;因:uchar为1个字节不能表示i=100         DQ=1; _nop_();_nop_();         DQ=0;         i=80;                     //延时约900us 理论延时:480~960us         while(i>0)i--;         DQ=1;         i=10;                       //延时约45us 理论延时:15~60us          while(i>0)i--;         while(DQ);                //等待DQ为低电平//         while(~DQ);               //等待DQ为高电平,检测到应答脉冲//                      }         uchar ds1820rd()/*读数据*/   { unsigned char i=0;          unsigned char dat = 0;          for (i=8;i>0;i--)          {   DQ = 0; //给脉冲信号           _nop_();                   dat>>=1;                   DQ = 1; //给脉冲信号           _nop_();           _nop_();                   if(DQ)                   dat|=0x80;                   delay_18B20(30);          }          return(dat);   }    void ds1820wr(uchar wdata)/*写数据*/   {unsigned char i=0;     for (i=8; i>0; i--)    { DQ = 0;      DQ = wdata&0x01;      delay_18B20(5);      DQ = 1;      wdata>>=1;    }  }         read_temp()/*读取温度值并转换*/  {uchar a,b;   ds1820rst();       ds1820wr(0xcc);//*跳过读序列号*/   ds1820wr(0x44);//*启动温度转换*/   ds1820rst();       ds1820wr(0xcc);//*跳过读序列号*/    ds1820wr(0xbe);//*读取温度*/    a=ds1820rd();   b=ds1820rd();   tvalue=b;   tvalue<<=8;   tvalue=tvalue|a;     if(tvalue<0x0fff)    tflag=0;     else    {tvalue=~tvalue+1;          tflag=1;    }   tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数         return(tvalue);   }  /*******************************************************************/    void ds1820disp()//温度值显示         { uchar flagdat;           disdata[0]=tvalue/1000+0x30;//百位数      disdata[1]=tvalue%1000/100+0x30;//十位数      disdata[2]=tvalue%100/10+0x30;//个位数      disdata[3]=tvalue%10+0x30;//小数位           if(tflag==0)             flagdat=0x20;//正温度不显示符号      else        flagdat=0x2d;//负温度显示负号:-       if(disdata[0]==0x30)            {disdata[0]=0x20;//如果百位为0,不显示                  if(disdata[1]==0x30)                   {disdata[1]=0x20;//如果百位为0,十位为0也不显示                   }          if(disdata[0]==7)            {             ledH=1;             buzzer();            }                 }             wr_com(0xc0);                 wr_dat(flagdat);//显示符号位            wr_com(0xc1);            wr_dat(disdata[0]);//显示百位            wr_com(0xc2);            wr_dat(disdata[1]);//显示十位                     wr_com(0xc3);            wr_dat(disdata[2]);//显示个位                     wr_com(0xc4);            wr_dat(0x2e);//显示小数点                     wr_com(0xc5);            wr_dat(disdata[3]);//显示小数位    }    /********************主程序***********************************/  void main()   {        init_play();//初始化显示       while(1)         {      read_temp();//读取温度      ds1820disp();//显示           }           //if(j<L_temp-20)    //  {ledL=1;    //   buzzer();   //   }        }   
回复

使用道具 举报

板凳
ID:262 发表于 2014-10-23 15:26 | 只看该作者
/******************************************************************
本程序只供学习使用,未经作者许可,不得用于其它任何用途
程序结构参考 安徽师范大学  Lyzhangxiang的EasyHW OS结构设计
Main.C  file
作者:bg8wj
建立日期: 2011.12.23
版本:V1.0
Copyright(C) bg8wj
/*******************************************************************/
#include "ioconfig.h"
#include "includes.h"
#include "datacomm.h"
/************************************************
              PID函数
*************************************************/
void PIDInit (struct PID *pp)
{
  memset ( pp,0,sizeof(struct PID));
}
/************************************************
              增量控制PID函数体
51单片机最不擅长浮点数计算,转换成int型计算
*************************************************/
unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint )
{
  unsigned int dError,Error,pError;
  //增量法计算公式:
  //Pdt=Kp*[E(t)-E(t-1)]+Ki*E(t)+Kd*[E(t)-2*E(t-1)+E(t-2)]
  Error = set_temper - NextPoint;       // 偏差E(t)
  pError=Error-pp->LastError;         //E(t)-E(t-1)
  dError=Error-2*pp->LastError+pp->PrevError; //E(t)-2*E(t-1)+E(t-2)
  pp->PrevError = pp->LastError;
  pp->LastError = Error;
  return (
            pp->Proportion * pError        //比例
            + pp->Integral *Error  //积分项
            + pp->Derivative * dError          // 微分项
                        );  
}

/************************************************
                                PID函数初始化
*************************************************/
void PIDBEGIN()
{
  PIDInit(&spid); // Initialize Structure
  spid.Proportion = 10; // Set PID Coefficients
  spid.Integral = 5;
  spid.Derivative =4;
}
/************************************************
                         实时温度读取函数
从DS18b20中读取实时温度
返回值放大10倍便于PID计算
*************************************************/
int ReadTemperature(void)
{
        unsigned char TPL=0;
        unsigned char TPH=0;
        unsigned int temperture=0;

        //EA = 0;                 
        Init_DS18B20();
        WriteOneChar(0xCC); //跳过读序号列号的操作
        WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
        TPL=ReadOneChar();        //读温度低字节
        TPH=ReadOneChar();        //读温度高字节

        //启动下一次温度转换
        Init_DS18B20();
        WriteOneChar(0xCC); // 跳过读序号列号的操作
        WriteOneChar(0x44); // 启动温度转换
         //temperture=(TPH*256+TPL)*0.0625   //真实温度值 范围(+125,-55)
        if(TPH&0xfc)
         {
           tp_flag=1;    //负温度标记
           temperture=((TPH<<8)|TPL);
           temperture=((~temperture)+1);
           temperture*=0.625+0.5;
         }
        else
         {
           tp_flag=0;
           //temperture=((TPH<<8)|TPL)*0.0625 //温度输出值范围(125.00,-55.00)
           temperture=((TPH<<8)|TPL)*0.625+0.5;//温度值放大10倍 范围(+1250.00,-550.00)
         }                                                                        //         +0.5四舍五入 精度只到小数后一位
        return(temperture);         
}
/************************************************
                                  lcd1602显示函数
*************************************************/
void xianshi(void)
{
    LCD_Write_String(0,0,"NOW TMP:");
        LCD_Write_String(0,1,"SET TMP:");
}
/************************************************
                        lcd1602显示实时温度
*************************************************/
void view(unsigned int tmp)
{
        LCD_Write_Char(15,0,'C');
        LCD_Write_Char(14,0,0xdf);//摄氏温度符号
        LCD_Write_Char(13,0,zhi[tmp%10]);//小数点后第1位
        LCD_Write_Char(12,0,'.');                 
        LCD_Write_Char(11,0,zhi[tmp%100/10]);//        个位
        LCD_Write_Char(10,0,zhi[tmp/100]);         //十位
        if(0==tmp/1000)LCD_Write_Char(9,0,' ');//百位 如果为零显示空格
        else
         LCD_Write_Char(9,0,zhi[tmp/1000]);
        if(1==tp_flag)LCD_Write_Char(8,0,'-');//正负温度符号显示 负温度显示- 0上显示空格
         else
         LCD_Write_Char(8,0,' ');
}
/***********************************************************
             PID温度控制做动函数
***********************************************************/
void compare_temper()                 //PID温度控制输出函数
{
  unsigned char i;

  if(set_temper>temper)
   {
    if(set_temper-temper>50)//如果控制目标温度温与实时温度差大于5度,(放大10倍)是50
     {

           PWM0_set(10); //PWM 输出高电平占空比最大。即全速加温
           PWM1_set(10);
     }
        else
    {
     for(i=0;i<10;i++) //5度范围内PID增量控制,10次周期 即PID积分式中T=10
     {
      rin=ReadTemperature();//PID输入实时温度采样值
      rout = PIDCalc ( &spid,rin ); // PID增量输出
     }//PID增量输出范围(0-255)配合pwm取值范围
     send_string_com("pid out:"); //串口输出监视数据
         send_char_com(rin); //实时温度值
         send_char_com(rout);//PID增量输出值
         send_char_com(0x0d);//输出回车,换行间隔控制字符
         send_char_com(0x0a);//
         
         if(rout>=240)rout=240;        //保障PWM输入值10-240 防止pwm出现失调。stc单片机特性。
         if(rout<=20)rout=20;
         
         PWM0_set(255-rout);
         PWM1_set(255-rout);
          
    }
   }
  else if(set_temper<=temper) //目标温度小于实时温度pwm输出低电平最高占空比,关闭加热。
   {
     PWM0_set(250);
         PWM1_set(250);
   }
}
/************************************************
                        系统初始化函数
*************************************************/
void Sys_Init()                                                               
{
PWM_init();
PIDBEGIN();
LCD_Init();
Init_DS18B20();
LCD_Clear();
InitUart1();
}
/*************************************************
                  主函数
**************************************************/
void main(void)
{        
Sys_Init();                //系统初始化
xianshi();                        //显示字符
PWM0_set(250);                //初始化PWM两路输出最高低电平占空比,不要加热
PWM1_set(250);
delay500ms();                //延时稍等芯片初始化
while(1)
  {  
           EA=0;
          k=KeyPro();            //键盘扫描
          if(k!=0xff)
           {
           if(k==15){i=0;shu[0]=0;shu[1]=0;shu[2]=0;shu[3]=0;}
           else{shu[i]=k;i++;if(i>3)i=0;}//键值15对应清除设定温度显示及数组为0
         }
         if(k==14)//键值14键 置入设定温度并确定 输入格式xxx+确定键 第一位是百度 为0需要输入0
         {
          EA=1;
          set_temper=1000*(shu[0])+100*shu[1]+10*shu[2];
          compare_temper();        //启动PID温度控制作动函数
         }
        LCD_Write_Char(15,1,'C');        //显示设定温度值百位为0时 显示空格 但是输入必须输入0
           LCD_Write_Char(14,1,0xdf); //温标符号
        LCD_Write_Char(13,1,zhi[0]);
        LCD_Write_Char(12,1,'.');
        LCD_Write_Char(11,1,zhi[shu[2]]);
        LCD_Write_Char(10,1,zhi[shu[1]]);
       
        if(shu[0]==0)LCD_Write_Char(9,1,' ');
        else LCD_Write_Char(9,1,zhi[shu[0]]);   
       
        if(counter-- == 0) //温度联系读5次
         {
          temper=ReadTemperature();                        
          counter =5;
         }
        view(temper);    //温度显示;
        if(!set_temper==0)compare_temper();//只有设置目标温度后才启动PID温控作动函数       
}
}


回复

使用道具 举报

地板
ID:262 发表于 2014-10-23 15:27 | 只看该作者
/********************************************************************
本程序只供学习使用,未经作者许可,不得用于其它任何用途
程序结构参考 安徽师范大学  Lyzhangxiang的EasyHW OS结构设计
datacomm.h
作者:bg8wj
建立日期: 2012.12.23
版本:V1.0

Copyright(C) bg8wj
/********************************************************************/
#ifndef  __DATACOMM_H__
#define  __DATACOMM_H__


/************************************************
PID函数
*************************************************/
/*************PID**********************************/
struct PID {
unsigned int Proportion; // 比例常数 Proportional Const
unsigned int Integral; // 积分常数 Integral Const
unsigned int Derivative; // 微分常数 Derivative Const
unsigned int LastError; // Error[-1]
unsigned int PrevError; // Error[-2]
};
xdata struct PID spid; // PID Control Structure

unsigned int rout; // PID Response (Output)
unsigned int rin; // PID Feedback (Input)

unsigned char key1,i,k;
unsigned int temper;
unsigned char shu[3]={0,0,0};
unsigned char counter;
unsigned char set_temper;
bit tp_flag;


#endif
回复

使用道具 举报

5#
ID:262 发表于 2014-10-23 15:27 | 只看该作者
回复

使用道具 举报

6#
ID:67818 发表于 2014-10-23 20:22 | 只看该作者
嘿嘿谢谢喽
回复

使用道具 举报

7#
ID:74571 发表于 2015-3-13 21:00 | 只看该作者
现在还需要不
回复

使用道具 举报

8#
ID:86621 发表于 2015-8-7 17:57 | 只看该作者
你会写1602吗  我有个会报警但是不显示啊
回复

使用道具 举报

9#
ID:86621 发表于 2015-8-7 17:57 | 只看该作者
是1602的  我不怎么会
回复

使用道具 举报

10#
ID:44267 发表于 2015-9-28 16:53 | 只看该作者
先顶一个再说
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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