单片机学习小组
直播中

李慎梓

7年用户 1383经验值
私信 关注

如何利用单总线去读取18B20温度传感器的ROM ID号呢

如何利用单总线去读取18B20温度传感器的ROM ID号呢?求解

回帖(1)

bozai602

2022-2-16 14:39:05

/*****************************************************/
功 能: 用于读取18B20温度传感器的ROM,16位ID
时 间:2019-09-25
作 者: 零点工作室(RMLS)
/*****************************************************/


#include
#define uchar unsigned char
#define uint unsigned int
***it DS= P3^7;                                                                 //根据实实际情况设定DS18B20端口
uchar code table[]={"0123456789ABCDEF"};         //用于1602显示
uchar sn[8];                                                                 //4个器件的序列号,先读出单个序列号后填上才可以读取温度
/************1602部分******************/
***it rs=P2^6;
***it rw=P2^5;
***it lcden=P2^7;
void delay1602(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}


void write_com(uchar com)//写命令
{
        rs=0;
        lcden=0;
        P0=com;
        delay1602(5);
        lcden=1;
        delay1602(5);
        lcden=0;
}


void write_date(uchar date)//写数据
{
        rs=1;
        lcden=0;
        P0=date;
        delay1602(5);
        lcden=1;
        delay1602(5);
        lcden=0;
}


void init_lcd() //初始化
{
        lcden=0;
        rw=0;
        write_com(0x38);
        write_com(0x0c);
        write_com(0x06);
        write_com(0x01);
        write_com(0x80);
}
/****************************************/
/*************DS18B20部分****************/
void delayb(uint count)      //延时
{
        uint i;
                while(count)
                {
                   i=200;
                        while(i>0)i--;
                   count--;
                }
}
void dsreset()       //DS18B20初始化
{
        uint i;               
        DS=0;
        i=103;
                while(i>0)i--;
        DS=1;
        i=4;
                while(i>0)i--;
}


bit readbit()               // 读一位
{
        uint i;
        bit dat;
        DS=0;i++;                 //小延时一下
        DS=1;i++;i++;
        dat=DS;
        i=8;while(i>0)i--;
        return (dat);
}


uchar readbyte()                   //读一个字节
{
        uchar i,j,dat;
        dat=0;
        for(i=1;i<=8;i++)
        {
           j=readbit();
           dat=(j<<7)|(dat>>1);  //读出的数据最低位在最前面,这样刚好一个字节在DAT里
        }
        return(dat);             //将一个字节数据返回
}


void writebyte(uchar dat) //写一个字节到DS18B20里
{                           
        uint i;
        uchar j;
        bit testb;
        for(j=1;j<=8;j++)
        {
                   testb=dat&0x01;
                   dat=dat>>1;
                   if(testb)     // 写1部分
                   {
                                DS=0;
                                i++;i++;
                                DS=1;
                                i=8;while(i>0)i--;
                   }
                   else
                   {
                                DS=0;       //写0部分
                                i=8;while(i>0)i--;
                                DS=1;
                                i++;i++;
                   }
        }
}


void rom() //读取序列号
{
        uchar i;
        dsreset(); //复位
        delayb(1); //延时
        writebyte(0x33); //发送读序列号子程序
        for(i=0;i<8;i++) //因为是8个字节,所以要读取8次
        {
           sn=readbyte(); //读取序列号
        }
}
/************主程序及显示部分*************/
main()
{
        uchar i,c,l,h;
        init_lcd(); //初始化1602
        while(1)
        {
                   rom();    //调用读序列号子程序
                   delayb(100); //如果是不断地读取的话可以不延时
                   for(i=0;i<8;i++) //因为是8个字节,所以要循环8次,每次显示一个字节
                   {
                                l=(sn&0xf0)>>4;   //获取低四位
                                h=sn&0x0f;    //获取高四位
                                write_com(0x80+c);   //显示位置
                                write_date(table[l]); //显示低四位的16进制码
                                write_date(table[h]); //显示高四位的16进制码
                                c++;c++; //每显示一个字节,显示位置右移两位
                   }
                   while(1);
        }
}
举报

更多回帖

×
20
完善资料,
赚取积分