⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds18b20_drive.c

📁 DS18B20的驱动程序
💻 C
字号:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

uchar tplsb, tpmsb;//温度值低位、高位字节
sbit DQ = P0^7;

//延时t毫秒
void delay(uint t)
{
    uint i;
    for(;t>0;t--)
        //对于11.0592MHz时钟,延时约1ms
        for(i=125;i>0;i--);
}

//产生复位脉冲初始化DS18B20
void txReset()
{
    uint i;
    DQ = 0;

    //DQ拉低约900us
    i = 100;
    while(i>0) i--;

    //产生上升沿
    DQ = 1;
    i = 4;
    while(i>0) i--;
}

//等待应答脉冲
void rxWait()
{
    uint i;
    while(DQ);
    while(~DQ);//检查到应答脉冲
    i = 4;
    while(i>0) i--;
}

//读取数据的一位,满足读时隙要求
bit readBit()
{
    uint i;
    bit b;
    DQ = 0;
    i++;//保持低至少1us
    DQ = 1;
    i++; i++;//延时15us以上,读时隙下降沿后15us,DS18B20输出数据才有效
    b = DQ;
    i = 8;
    while(i>0) i--;//读时隙不低于60us
    return(b);
}

//读取数据的一个字节
uchar readByte()
{
    uchar i, j, b;
    b = 0;
    for(i=0;i<8;i++)
    {
        j = readBit();
        b = (j<<7)|(b>>1);
    }
    return(b);
}

//写数据的一个字节,满足写1和写0的时隙要求
void writeByte(uchar b)
{
    uint i;
    uchar j;
    bit btemp;
    for(j=0;j<8;j++)
    {
        btemp = b&0x01;
        b >>= 1;//取下一位,由低位向高位
        if(btemp)
        {
            //写1
            DQ = 0;
            i++; i++;//延时,使得15us以内拉高
            DQ = 1;
            i = 8;
            while(i>0) i--;//整个写1时隙不低于60us
        }
        else
        {
            //写0
            DQ = 0;
            i = 8;
            while(i>0) i--;//保持低电平在60us到120us之间
            DQ = 1;
            i++;
            i++;
        }
    }
}

//启动温度转换
void convert()
{
    txReset();//产生复位脉冲,初始化DS18B20
    rxWait();//等待DS18B20给出应答脉冲
    delay(1);//延时1ms
    writeByte(0xcc);//skip rom命令
    writeByte(0x44);//convert T 命令
}

//读取温度值
void readTemp()
{
    txReset();//产生复位脉冲,初始化DS18B20
    rxWait();//等待DS18B20给出应答脉冲
    delay(1);//延时1ms
    writeByte(0xcc);//skip rom命令
    writeByte(0xbe);//read scratchpad命令
    tplsb = readByte();//温度值低位字节(其中低4位为二进制的“小数”部分)
    tpmsb = readByte();//温度值高位字节(其中高5位为符号位)
}



//开始测试
//温度值显示在LCD上,显示格式如下:
//LCD字符位置:1  2   3   4   5   6   7   8   9   10  11  12  13  14  15  16
//LCD的第一行:R  e   a   l       t   i   m   e       T   e   m   p   :
//LCD的第二行:           +       x   x   x.  x   x   x   x   。  C
sbit LCDRS = P3^3;
sbit LCDRW = P3^4;
sbit LCDEN = P3^5;

uchar code NumTable[] = "0123456789";
uchar code HeadLine[] = "Real time Temp:";//15个字符
uchar code SecoLine[] = "   + xxx.xxxx。C";//14个字符

void write_com(uchar com) //写命令
{
    LCDRS = 0;
    LCDRW = 0;
    LCDEN = 0;
    P1 = com;
    LCDEN = 1;
    delay(5);
    LCDEN = 0;
}

void write_data(uchar dat) //写数据
{
    LCDRS = 1;
    LCDRW = 0;
    LCDEN = 0;
    P1 = dat;
    LCDEN = 1;
    delay(5);
    LCDEN = 0;
}


void init()
{
    uchar i;

    //初始化LCD
    write_com(0x38);
	write_com(0x0c);
	write_com(0x06);
	write_com(0x01);
	write_com(0x80);

    //在LCD上显示第一行:“Real time Temp:”//15个字符
    for(i=0;i<15;i++)
    {
        write_data(HeadLine[i]);
    }

    //在LCD上显示第二行:“   + xxx.xxxx。C”//14个字符
    write_com(0x80+0x40);//换行
    for(i=0;i<12;i++)
    {
        write_data(SecoLine[i]);
    }
    write_com(0x80+0x40+0x0d);
    write_data(0xdf);//显示“。”
    write_data(0x43);//显示“C”
}


void main()
{
    uint tempMsb, tempLsb, temp;
    uchar bai, shi, ge;//温度整数部分的数据
    uchar xiao1, xiao2, xiao3, xiao4;//温度小数部分的数据
    bit unit;//温度的正负情况

    init();

    while(1)
    {
        delay(1);//延时1ms
        convert();//启动温度转换,需要750ms
        delay(1000);//延时1s
        readTemp();//读取温度

        
        //将当前温度的整数部分及符号位存入tpmsb,小数部分存入tplsb
        tpmsb <<= 4;   //将其高四位符号位移出
        temp = tplsb;  
        temp >>= 4;    //将小数部分移出
        temp &= 0x0f;  //将高四位清0
        tpmsb |= temp; //当前温度的整数部分

        //温度的整数部分
        //当温度变化时数据逐位提出
        if(tempMsb!=tpmsb)//整数部分有变化,刷新LCD的整数部分
        {
            tempMsb = tpmsb;

            
            temp = tpmsb;
            temp <<= 1; 
            unit = CY;//温度的正负情况
            
            
            temp = tpmsb;
            temp &= 0x7f;//将温度的符号位屏蔽
            
            bai = temp/100; //提出温度的百位数字
            temp = temp%100;//减掉温度的百位

            shi = temp/10;  //提出温度的十位数字

            ge = temp%10; //提出温度的个位数字

            
            //显示当前温度
            //百位如果为0,则百位不显示;
            //百位和十位均为0,则只显示各位
            //显示当前温度的正负情况
            write_com(0x80+0x40+0x03);
            if(unit)
            {
                write_data(0x2d);//显示负号
            }
            else
            {
                write_data(0x2b);//显示正号
            }
            
            //显示当前温度的百位,如果为0则不显示
            write_com(0x80+0x40+0x05);
            if(bai)
            {
                write_data(NumTable[bai]);//显示百位数字
            }
            else
            {
                write_data(0x20);//显示空格    
            }

            //显示当前温度的十位,如果百位和十位均为0,则不显示
            if(bai|shi)
            {
                write_data(NumTable[shi]);//显示十位数字
            }
            else
            {
                write_data(0x20);//显示空格
            }

            //显示当前温度的个位
            write_data(NumTable[ge]);            
              
        }

        //温度小数部分的处理
        tplsb &= 0x0f; //将tplsb的温度整数部分屏蔽,仅保留小数部分
        if(tempLsb!=tplsb)//小数部分有变化,刷新LCD的小数部分
        {
            tempLsb = tplsb;

            //小数部分数值转换
            temp = tplsb;
            
            temp *= 625;
            
            //分析出小数部分各位数字
            xiao1 = temp/1000;//提出小数部分的第一位数字
            temp = temp%1000;//去除小数部分的第一位
                        
            xiao2 = temp/100;//提出小数部分的第二位数字
            temp = temp%100;//去除小数部分的第二位
                        
            xiao3 = temp/10;//提出小数部分的第三位数字
                        
            xiao4 = temp%10;//提出小数部分的第四位数字


            //显示小数部分
            write_com(0x80+0x49);//指针指向小数的第一位
            write_data(NumTable[xiao1]);//刷新小数部分的第一位数字
            write_data(NumTable[xiao2]);//刷新小数部分的第一位数字
            write_data(NumTable[xiao3]);//刷新小数部分的第一位数字
            write_data(NumTable[xiao4]);//刷新小数部分的第一位数字
        }
        


    }
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -