找回密码
 立即注册

QQ登录

只需一步,快速开始

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

自己搞的DS18B20显示程序,可以用,但是在延时方面有点小BUG,望有缘人一起探讨

[复制链接]
跳转到指定楼层
楼主
ID:325916 发表于 2018-5-9 14:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <reg51.h>
#include <intrins.h>    //需要调用_nop_();延时函数

#define uchar unsigned char
#define uint  unsigned int
#define High_Temp  35    //定义空调适宜最高温度为35度
#define Low_Temp  15     //定义空调适宜最低温度为15度

/**********************第一部分门厅人员感应****************************/
sbit SPK = P3^4;       //音频输出
sbit door_call = P1^5; //红外感应按钮
sbit LED = P3^3;       //LED黄灯输出
uint T_count = 0;      //全局整形变量控制 叮咚 声响时长。

/**********************第二部分对温度的检测与控制****************************/
sbit DQ = P3^0;        //18B20数据线引脚
sbit Speaker=P3^1;     //蜂鸣器的定义
sbit KongTiao=P3^2;    //电机的定义
sbit RTGY=P1^4;        //空调人体感应的定义


/**********************第三部分天燃气检测   ****************************/
sbit TRQ = P1^6; //天然气感应按钮
sbit up=P3^5;        //自动开窗
sbit down=P3^6;        //自动关窗

//初始化程序
void initA ()
{
TMOD=0x00;          //T1方式定时器
TH1=(8192-700)/32;  //700us定时/初值高8位放TH1
TL1=(8192-700)%32;   //初值低5位放TL1
IE=0x88;          //打开T1中断
}
//T1中断控制叮咚声响程序
void Timer1() interrupt 3    //定时器中断服务函数
{
SPK=~SPK;
T_count ++;
if(T_count < 400)                 //叮  时长为400*700us
        {
          TH1=(8192-700)/32;  //0.3ms实现  叮  的音
          TL1=(8192-700)%32;   
        }
else if(T_count < 900)                 //咚  时长为400*1000us
        {

          TH1=(8192-900)/32;  //1ms实现  咚  的音
          TL1=(8192-900)%32;   
        }
        else         
        {
         TR1=0;        //关闭本次呼叫呼叫
         T_count=0;    //时长计数清零
        }
}


/**********************第二部分温度检测部分****************************/
uchar bw,sw,gw;       //温度的百 十  个位。

uchar code DSY_CODE[]=
        {0xc0,0xf9,0xa4,0xb0,0x99,0x92,
        0x82,0xf8,0x80,0x90,0xbf,0xff,0xC6};


void Delay_2US(uint us)   //微秒延时,延时2*50us
{
while(--us);
}   

void Delay_50Us(uint t)   //微秒延时,延时t*50us
{
uchar j;
while(t--)
for(j=19;j>0;j--);
}


//DS18B20复位函数
void reset()
{
uchar x=0;
DQ=1;          //复位DQ
Delay_2US(8);
DQ=0;          //将DQ拉低
Delay_2US(80);//精确延时 >480us <960us
DQ=1;          //将DQ拉高
Delay_2US(14);  //延时15~60us后,接收脉冲
x=DQ;     //DQ 若为0则初始化成功,否则失败
Delay_2US(20);
}

//读取一个字节的数据函数
uchar Ds18b20_Read(void)

{
uchar i=0;
uchar dat=0;
for(i=8;i>0;i--)
{
DQ=0;
dat>>=1;    //右移一位
DQ=1;
_nop_();
if(DQ)dat=dat|0x80;
Delay_2US(20);
}
return(dat);
}


//写入一个字节的数据函数
void Ds18b20_Write(uchar dat)

{
uchar i=0;
for(i=8;i>0;i--)
{
DQ=0;
_nop_();
DQ=dat&0x01;
Delay_2US(20);
DQ=1;
dat>>=1;
}
}

//读取实际温度函数
uchar Ds18b20_Read_Temperature(void)
{
uchar temp1,temp;
int temp2;
reset();
Ds18b20_Write(0xCC);      //跳过ROM
Ds18b20_Write(0x44);      //启动DS18B20进行温度转换
Delay_2US(200);
reset();

Ds18b20_Write(0xCC);      //跳过ROM
Ds18b20_Write(0xBE);      //读DS18B20内部暂存器命令
Delay_2US(200);
temp1=Ds18b20_Read();     //读出低字节
temp2=Ds18b20_Read();     //读出高字节
temp=(temp1|(temp2<<8))>>4;
return temp;
}



/*****转换成十进制温度并显示*********/
void Change_Display(uchar i)
{
        uchar temp=i;
        if((temp&0xc0)==0xc0)
        {
        temp=~temp+1;
        bw=10;
        sw=(temp/10==0)?11:temp/10;
        gw=temp%10;
        }
        else
        {
        bw=(temp/100==0)?11:1;
        if(bw!=1)
        sw=(temp/10==0)?11:temp/10;
        else sw=(temp-100)/10;
        gw=temp%10;
        }
        P1=~0x01;   P2=~DSY_CODE[bw]; Delay_2US(900);           //显示十位
        P1=~0x02;   P2=~DSY_CODE[sw]; Delay_2US(900);           //显示个位
        P1=~0x04;   P2=(~DSY_CODE[gw]+0x80); Delay_2US(900);    //显示小数点后一位
        P1=~0x08;   P2=~DSY_CODE[12]; Delay_2US(900);           //显示温度C
       
}
/********************************第一部分控制*********************************/
//红外感应控制程序
void  D_1bf()
{
        if(door_call==0) //按下按键启动定时器
                {
                TR1=1;  //启动计数,T1中断开始工作并发出叮咚声       
                while(!door_call);//等键释放
                LED=~LED;
                Delay_50Us(8000);
                LED=1;
                }
}

/********************************第三部分窗户的开关控制*********************************/
//开窗
void pwm1()
{
uchar i;
for(i=0;i<10;i++)
{
down=0;//确保窗户不闭合
up=1;
Delay_2US(10);
up=0;
Delay_2US(10);
}
up=0;
}

/****主函数**********/
void main()
{     
       
        uchar i;
        initA ();           //第一部分初始化         
        while(1)
        {
        i=Ds18b20_Read_Temperature();  //读取温度
        Change_Display(i);               //显示温度
       
        //对串口的初始化定义         
        KongTiao=1;
        RTGY=1;
        TRQ=1;
        LED=1;
        Speaker=1;

        //判断是否有人进门
        if(!door_call)    D_1bf();            //第一部分判断程序调用  
        //判断天然气是否泄漏
        if(!TRQ)
        {
        Speaker=0;    //蜂鸣器报警
        pwm1();
        }

       
        //判断当前温度是否超值,是否需要启动空调
        if(RTGY==0 & i!=0)
        {
                if(i>High_Temp||i<Low_Temp)     //蜂鸣器报警判断电路
                {
                Speaker=0;                      //蜂鸣器报警
                KongTiao=0;
                }
        }               
  }
}



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

使用道具 举报

沙发
ID:325916 发表于 2018-5-9 14:50 | 只看该作者
我的QQ1348216252可以一起探讨
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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