找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1766|回复: 4
收起左侧

求帮忙看看这DS18B20测温程序有什么问题

[复制链接]
ID:206654 发表于 2017-6-1 12:03 | 显示全部楼层 |阅读模式
4.2.1  DS18B20测温程序
#include<reg52.h>
#include"lcd1602.h"
#include"adc_stc60s2.h"
#define ucharunsigned char
#defineuint  unsigned int
#define jump_ROM0xCC
#define start0x44
#defineread_EEROM 0xBE
sbit DQ =P2^3;            //DS18B20数据口
unsigned charTMPH,TMPL;
/********************************************************************
* 名称 : delay()
* 功能 : 延时,延时时间大概为140US。
* 输入 : 无
* 输出 : 无
***********************************************************************/
void delay_1()
{
    int i,j;
    for(i=0; i<=10; i++)
    for(j=0; j<=2; j++)
;
}
/********************************************************************
* 名称 : delay()
* 功能 : 延时函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void delay(uintN)
{
    int i;
    for(i=0; i<N; i++)
    ;
}
/********************************************************************
* 名称 : Delay_1ms()
* 功能 : 延时子程序,延时时间为 1ms * x
* 输入 : x (延时一毫秒的个数)
* 输出 : 无
***********************************************************************/
voidDelay_1ms(uint i)//1ms延时
{
    uchar x,j;
    for(j=0;j<i;j++)
    for(x=0;x<=148;x++);
}
/********************************************************************
* 名称 : Reset()
* 功能 : 复位DS18B20
* 输入 : 无
* 输出 : 无
***********************************************************************/
ucharReset(void)
{
    uchar deceive_ready;
    DQ = 0;
    delay(29);
    DQ = 1;
    delay(3);
    deceive_ready = DQ;
    delay(25);
    return(deceive_ready);
}
/********************************************************************
* 名称 : read_bit()
* 功能 : 从DS18B20读一个位值
* 输入 : 无
* 输出 : 从DS18B20读出的一个位值
***********************************************************************/
ucharread_bit(void)
{
    uchar i;
    DQ = 0;
    DQ = 1;
    for(i=0; i<3; i++);
    return(DQ);
}
/********************************************************************
* 名称 : write_bit()
* 功能 : 向DS18B20写一位
* 输入 : bitval(要对DS18B20写入的位值)
* 输出 : 无
***********************************************************************/
voidwrite_bit(uchar bitval)
{
DQ=0;if(bitval==1)
DQ=1;
delay(5);
DQ=1;
}
/********************************************************************
* 名称 : read_byte()
* 功能 : 从DS18B20读一个字节
* 输入 : 无
* 输出 : 从DS18B20读到的值
***********************************************************************/
ucharread_byte(void)
{
    uchar i,m,receive_data;
    m = 1;
    receive_data = 0;
    for(i=0; i<8; i++)
    {
       if(read_bit())
       {
           receive_data = receive_data + (m<< i);
       }
       delay(6);
    }
    return(receive_data);
}
/********************************************************************
* 名称 : write_byte()
* 功能 : 向DS18B20写一个字节
* 输入 : val(要对DS18B20写入的命令值)
* 输出 : 无
***********************************************************************/
voidwrite_byte(uchar val)
{
    uchar i,temp;
    for(i=0; i<8; i++)
    {
       temp = val >> i;
       temp = temp & 0x01;
       write_bit(temp);
       delay(5);
    }
}
/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void main()
{
    uchar lcd_string[2][33]={0};
    uint temp,tmep1;
    long delay_time = 5;
    init_adc();
    L1602_init();
    while(1)
    {
       Reset();
       write_byte(jump_ROM);
       write_byte(start);
       Reset();
       write_byte(jump_ROM);
       write_byte(read_EEROM);
       TMPL = read_byte();
       TMPH = read_byte();
       temp = TMPL / 16 + TMPH * 16;
        lcd_string[0][0] = temp/10%10 + 0x30;
       //if (lcd_string[0][0]>=1)
              //L1602_string(1,1,"123");
        lcd_string[0][1] = temp%10 + 0x30;
       if (temp > 30) P3 &= ~(0x01<< 2);
       else P3 |= (0x01 << 2);
       if (temp < 27) P3 &= ~(0x01<< 3);
       else P3 |= (0x01 << 3);
      
       temp1= adc_out();
        lcd_string[1][0] = temp1/10%10 + 0x30;
        lcd_string[1][1] = temp1%10 + 0x30;
       //添加湿度上下限  result为湿度值
        if(temp > 55) P3 &= ~(0x01 << 4);   
       else P3 |= (0x01 << 4);
       if (temp < 40) P3 &= ~(0x01<< 5);
       else P3 |= (0x01 << 5);
       if(delay_time== 0)  {
               L1602_string(1,1,lcd_string[0]);
               L1602_string(2,1,lcd_string[1]);
               delay_time = 5;
        }
       delay_time--;
    }
}
4.2.2   A/D转换程序
#include<STC12c5a60s2/STC_12c5a.H>
#include<intrins.h>  //包含_nop_()函数定义的头文件
#include"adc_stc60s2.h"
voidinit_adc()
{
    unsigned long i;
    ADC_CONTR|=0x80;      //开A/D转换电源,第一次使用时要打开内部模拟电源
    for (i=0;i<10000;i++);   //适当延时
    P1ASF=0x04;              //选择P1.2作为A/D转换通道
    ADC_CONTR=0xE2;              
    for (i=0;i<10000;i++);      //适当延时
}
ucharadc_out()
{
    uchar result;
    uchar status;
    ADC_CONTR|=0x08;        //启动 A/D 转换
    status=0;
    while(status==0)         //等待A/D转换结束
    {
          status=ADC_CONTR&0x10;
    }
    ADC_CONTR&=0xE7;         //将ADC_FLAG清0
    result=ADC_RES;      //保存A/D转换结果
    return result;
}
4.2.3  1602显示程序
#include<reg52.h>
#include"lcd1602.h"
/********************************************************************
* 名称 : delay()
* 功能 : 延时,延时时间大概为140US。
* 输入 : 无
* 输出 : 无
***********************************************************************/
voiddelay()
{
    int i,j;
    for(i=0; i<=100; i++)
    for(j=0; j<=20; j++)
;
}
/********************************************************************
* 名称 : enable(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
voidenable(uchar del)
{
    DATA = del;
    RS = 0;
    RW = 0;
    E = 0;
    delay();
    E = 1;
    delay();
}
/********************************************************************
* 名称 : write(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/
voidwrite(uchar del)
{
    DATA = del;
    RS = 1;
    RW = 0;
    E = 0;
    delay();
    E = 1;
    delay();
}
/********************************************************************
* 名称 : L1602_init()
* 功能 : 1602初始化,请参考1602的资料
* 输入 : 无
* 输出 : 无
***********************************************************************/
voidL1602_init(void)
{
    enable(0x01);
    enable(0x38);
    enable(0x0c);
    enable(0x06);
    enable(0xd0);
}
/********************************************************************
* 名称 : L1602_char(ucharhang,uchar lie,char sign)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
        L1602_char(1,5,'b')
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
voidL1602_char(uchar hang,uchar lie,char sign)
{
    uchar a;
    if(hang == 1) a = 0x80;
    if(hang == 2) a = 0xc0;
    a = a + lie - 1;
    enable(a);
    write(sign);
}
/********************************************************************
* 名称 : L1602_string(ucharhang,uchar lie,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
         L1602_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
voidL1602_string(uchar hang,uchar lie,uchar *p)
{
    uchar a;
    if(hang == 1) a = 0x80;
    if(hang == 2) a = 0xc0;
    a = a + lie - 1;
    enable(a);
    while(1)
    {
       if(*p == '\0') break;
       write(*p);
       p++;
    }
}

Sheet1.pdf

24.84 KB, 下载次数: 5

电路图

回复

使用道具 举报

ID:206810 发表于 2017-6-1 18:07 | 显示全部楼层
ds18b20不需额外的ad转换 输出的就是数字量
回复

使用道具 举报

ID:206810 发表于 2017-6-1 18:15 | 显示全部楼层

这是我自己写的一个12864显示ds18b20 的程序 可以参考一下




#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int

sbit ds   = P2^2;
sbit beep = P2^3;

sbit RS=P3^5;
sbit LCDE=P3^4;
sbit RW=P3^6;
sbit PSB=P3^7;

char code t4[]={"0123456789"};
char code t2[]={"当前温度:"};
bit flag;
uint temp;//温度
void TempDelay(uchar us)
{
        while(us--); //6.51us
}
void delay(int z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=115;y>0;y--);
}


void xieml(unsigned char ml)
{
  RS=0;
        RW=0;
        LCDE=0;
  P0=ml;
        delay(5);
        LCDE=1;
        delay(5);
  LCDE=0;
}       

void xieshu(unsigned char shu)
{
  RS=1;
        RW=0;
        LCDE=0;
        P0=shu;
        delay(5);
        LCDE=1;
        delay(5);
        LCDE=0;
}

void init()
{
  PSB=1;
        xieml(0x30);
        delay(5);
  xieml(0x0C);
        delay(5);
}


void display(uint temp)
{
        uchar bai,sh,ge,i;
        bai=temp/100;
        sh=temp%100/10;
        ge=temp%100%10;
        init();
        xieml(0x90);
        xieshu(t4[bai]);
        xieshu(t4[sh]);
        xieshu('.');
  xieshu(t4[ge]);

        i=0;
        xieml(0x80);
                while(t2[i]!='\0')
        {
        xieshu(t2[i]);
                i++;
        }       
}
void ds_reset()
{
        ds=1;
        _nop_();
        ds=0;
        TempDelay(80);//520us
        ds=1;
        TempDelay(5);
        if(ds==0)
                flag=1;
        else
                flag=0;
        TempDelay(20);
        ds=1;
}
bit ds_read_bit()
{
        bit dat;
        ds=0;
        _nop_();
        _nop_();
        ds=1;
        _nop_();
        dat=ds;
        TempDelay(12);
        return dat;
}
uchar ds_read_byte()
{
        uchar i,j,value;
        for(i=0;i<8;i++)
        {
                j=ds_read_bit();
                value=(j<<7)|(value>>1);
        }
        return value;
}
void ds_write_byte(uchar dat)
{
        uchar i,onebit;
        for(i=0;i<8;i++)
        {
                onebit=dat&0x01;
                if(onebit)           //写1
                {
                        ds=0;
                        TempDelay(1);
                        ds=1;
                        _nop_();
                }
                else  //写0
                {
                        ds=0;
                        TempDelay(11);
                        ds=1;
                        _nop_();
                }
                dat>>=1;
        }
}
void ds_change()
{
        ds_reset();
        ds_write_byte(0xcc);
        ds_write_byte(0x44);
}

uint get_temperature()
{
        uchar a,b;
        float temperature;
        ds_reset();
        ds_write_byte(0xcc);
        ds_write_byte(0xbe);
        a=ds_read_byte();
        b=ds_read_byte();
        temp=b;
        temp<<=8;
        temp|=a;
        temperature=temp*0.0625;
        temp=temperature*10+0.5;
        return temp;
}
void main()
{
       
        ds_change();
        delay(1000);
        while(1)
        {               
                display(get_temperature());
                ds_change();
                if(get_temperature()>350)//35度蜂鸣器发声
                        beep=0;
                else
                        beep=1;
        }
}
回复

使用道具 举报

ID:206829 发表于 2017-6-1 19:10 | 显示全部楼层
看不出来啊
回复

使用道具 举报

ID:472242 发表于 2019-2-3 20:54 | 显示全部楼层
估计是楼主直接就将代码复制在一起没分开多文件产生的结果

评分

参与人数 3黑币 +85 收起 理由
Trump1438 + 15
shuisheng + 35
刀刀见红 + 35

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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