打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
C51--DS18B20数字温度计--C语言



 

#include<reg52.h>

#include<intrins.h>

#define uint unsigned int
#define uchar unsigned char

sbit DQ=P2^6;

sbit lcdrs=P1^0;
sbit lcdrw=P1^1;
sbit lcden=P1^2;

void disp(uint a);
void init(void);

void delay(uint i);

uchar ds18b20_init(void);

void write_byte(uchar byte);

uchar read_byte(void);

uint read_ds18b20(void);

void delay50us(void);

void delayms(uint a);

void lcd1602_wr_com(uchar com);

void lcd1602_wr_data(uchar dat);

void lcd_init(void);

uchar code str[]="temperature"; 

void main(void)
{
    init();
    while(1)
    
        disp(read_ds18b20());
        delayms(50);
    }
}

void init(void)
{
    uchar i;
    lcd_init();
    lcd1602_wr_com(0x80+0x02);    //显示的地址
    for(i=0;i<11;i++)
    {
        lcd1602_wr_data(str[i]);
        delayms(2);
    }
}

void disp(uint a)
{
    uchar bai,ge,shi,dp,symbol;
    uint b;
    b=a&0x8000;
    if(b==0x8000)    //负温度
    {
        a&=0x7fff;          //将最高位置0
        symbol=0x2d;        //符号为“-”
    }
    else symbol=0x2b;       //符号为“+”
   
    bai=a/1000+0x30;
    shi=a00/100+0x30;
    ge=a0/10+0x30;
    dp=a+0x30;
    if(bai==0x30)
    {
        bai=0x20;     //如果百位为0,不显示
        if(shi==0x30)shi=0x20;    //如果百位为零,十位也为0,不显示
    }
    lcd1602_wr_com(0x80+0x43);
    lcd1602_wr_data(symbol);
    delayms(2);
    lcd1602_wr_data(bai);
    delayms(2);
    lcd1602_wr_data(shi);
    delayms(2);
    lcd1602_wr_data(ge);
    delayms(2);
    lcd1602_wr_data(0x2e);
    delayms(2);
    lcd1602_wr_data(dp);
    delayms(2);
    lcd1602_wr_data(0xdf);
    delayms(2);
    lcd1602_wr_data(0x43);
    delayms(2);
}
 

void delay(uint i)
{
    while(i--);   
}
uchar ds18b20_init(void)
{
    uchar n;
    DQ=1;         //初始化时序从高到低,因此先置高
    delay(4);     //延时等待稳定
    DQ=0;         //拉低
    delay(60);    //延时大约500us
    DQ=1;         //主机放开
    delay(6);     //延时15~60us
    n=DQ;         //读信号线状态,如为低,则说明线上有设备,否则说明没有或坏了
    delay(6);
    return n;   
}
void write_byte(uchar byte)
{
    uchar i;
    for(i=0;i<8;i++)
    {
        DQ=0;              //复位信号线
        DQ=byte&0x01;      //低位开始写入,0继续拉低信号线,1则被拉高
        delay(5);          //延时大约45us左右,等待设备采样数据
        byte>>=1;          //右移一位
        DQ=1;
    }
    delay(4);   
}
uchar read_byte(void)
{
    uchar i,temp;
    for(i=0;i<8;i++)
    {
        DQ=0;
        temp>>=1;           //右移一位
        DQ=1;               //主机释放信号线
        _nop_();
        if(DQ)temp|=0x80;   //将读出数据放在最高位,如果是0,信号线会设备继续拉低,1则为高
        delay(4);           
    }
    return temp;            //返回读出的一字节数据
}
uint read_ds18b20(void)
{
    uchar numh,numl;
    uint value;
    if(ds18b20_init()==0)           //判断设置是否正常,0为正常
    {
        write_byte(0xcc);   //跳过ROM序列号读取
        write_byte(0x44);   //启动温度转换
        if(ds18b20_init()==0)       //再次初始化
        {
            write_byte(0xcc);//跳过ROM序列号读取
            write_byte(0xbe);//读温度寄存器
            numl=read_byte();//读低位数据
            numh=read_byte();//读高位数据
            value=numh;
            value=value<<8|numl;  //将数据组合成16位数据
            if(value<0x0fff)      //正温度
            {
                value=value*0.0625*10+0.5;    //最一位小数,并进行4舍5入
            }
            else                  //负温度
            {
                value=~value+1;            //内存中数据是以补码存放的,负数补码为绝对值按位取反加1
                                           //而补码的补码为原码,这样就可以求得负数的绝对值
                value=value*0.0625*10+0.5; //最一位小数,并进行4舍5入,这是负数的绝对值
                value=value|0x8000;        //将最高位置1,表示此温度为负温度                                                    
            }
         
    }
    return value;       
}

void delay50us(void)
{
    uint j;
    j=4;
    while(j--);
}
void delayms(uint a)
{
    uint i,j;
    for(i=a;i>0;i--)
        for(j=122;j>0;j--);
}
void lcd1602_wr_com(uchar com)
{
    lcdrs=0;
    P0=com;
    delayms(2);
    lcden=1;
    delay50us();
    lcden=0;
}
void lcd1602_wr_data(uchar dat)
{
    lcdrs=1;
    P0=dat;
    delayms(2);
    lcden=1;
    delay50us();
    lcden=0;   
}
void lcd_init(void)
{
    lcden=0;
    lcdrw=0;
    lcd1602_wr_com(0x38);    //显示模式设置
    lcd1602_wr_com(0x0c);    //开显示,不显示光标   
    lcd1602_wr_com(0x06);    //写字符后地址指针加1,整屏显示不移动
    lcd1602_wr_com(0x01);    //清屏
}

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
<SPAN>LCD1602-DS1302时钟程序</SPAN>
PIC16f877a单片机DS18b20源程序
51/51单片机第9课:DS18B20温度检测系统
51单片机制作实践
DS18B20 测温程序完全解读
单片机温度检测报警程序(ds18b20)-Changing's Blog
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服