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

📄 ds1820.txt

📁 关于单总线的ds18b20测温器件的一些资料和源码(含汇编和c).
💻 TXT
📖 第 1 页 / 共 2 页
字号:
#define uchar unsigned char
#define ulong unsigned long int

#define DS18b20io     P2_0              //DS18B20数据线

sbit ACC0=ACC^0;
sbit ACC7=ACC^7;

uchar DS18b20_temp[2];  //读出的18b20温度值存放地
uchar display_date[4];    //要显示的四位数据的存放地
uchar dispaly_dot;        //LED显示小数点位置
uchar *display_point;   //LED显示数据存放地指针

void delay_5us(uchar y)         //(2.17*y+5)us延时,11.0592M晶振
{
    while(--y);
}
void delay(uint v)             //1ms单位延时(实际是0.998ms)。50是49ms;500是490ms,还算准. 晶振11.0592M
{
    uchar i;
    while(v--)
    {
        for(i=0;i<111;i++);
    }
}

void display(uchar *z,uchar spot) //数码管显示子程序。入口是要显示的4位数字(0、1、2、3。。。)及小数点位置,0/1/2/3四个位置,其他数字表示无小数点。BCD码转换等应由前期解决。
{                                  //为避免闪烁,应在主程序里不停调用这个子程序.它大约耗时4ms.因此凡是需要4ms以上延时的地方,最好都用它来延时.
    uchar i;
    for(i=0;i<4;i++)
    {
        P2|=0xf0;                     //关所有4个数码管
        switch(*(z+i))
        {
            case 0:P0=0xc0;break;      //共阳的段码表。若LED共阴,则码表取反。
            case 1:P0=0xf9;break;
            case 2:P0=0xa4;break;
            case 3:P0=0xb0;break;
            case 4:P0=0x99;break;
            case 5:P0=0x92;break;
            case 6:P0=0x82;break;
            case 7:P0=0xf8;break;
            case 8:P0=0x80;break;
            case 9:P0=0x90;break;
            case 12:P0=0xbf;break;      //“-”,表示零下温度
            case 13:P0=0xa7;break;      //“c”,表示温度
            case 15:P0=0xff;break;      //不亮
            default:P0=0xff;          //不亮
        }
        if(spot==i)
            P0&=0x7f;
        P2&=~(0x80>>i);
        delay(1);                     //亮1mS
    }
    P2|=0xf0;                         //关所有4个数码管,否则最后一位就会格外亮.    
}

void DS18b20_w_byte(uchar x)    //向18b20写一个字节.x是要写的内容
{
    uchar i;
    for(i=0;i<8;i++)
    {
        DS18b20io=0;
        _nop_();                      //要求>1us,但又不能超过15us
        _nop_();
        if(0x01&x)
             DS18b20io=1;
        delay_5us(30);                  //要求总时间在60-120us
        DS18b20io=1;                  //释放总线
        _nop_();                      //要求>1us      
        x=x>>1;
    }    
}

uchar DS18b20_r_byte(void)        //从18b20读一个字节.返回读到的内容
{
    uchar i,j;
    j=0;                              
    for(i=0;i<8;i++)
    {
        j=j>>1;
        DS18b20io=0;
        _nop_();                      //要求>1us,但又不能超过15us
        _nop_();
        DS18b20io=1;                  //释放总线
        _nop_();
        _nop_();
        if(DS18b20io)
             j|=0x80;
        delay_5us(30);                  //要求总时间在60-120us
        DS18b20io=1;                  //释放总线
        _nop_();                      //要求>1us
    }
    return j;    
}

void DS18b20_int(void)         //每次上电都给18b20初始化,设置18b20的参数.
{
    DS18b20io=0;
    delay_5us(255);                      //要求480-960us
    DS18b20io=1;                      //释放总线
    delay_5us(30);                      //要求60-120us
    if(DS18b20io==0)
    {
        delay_5us(200);                  //要求释放总线后480us内结束复位
        DS18b20io=1;                  //释放总线
        DS18b20_w_byte(0xcc);         //发送Skip ROM命令
        DS18b20_w_byte(0x4e);         //发送"写"暂存RAM命令
        DS18b20_w_byte(0x00);         //温度报警上限设为0
        DS18b20_w_byte(0x00);         //温度报警下限设为0
        DS18b20_w_byte(0x3f);         //将18b20设为10位,精度就是0.25度
        DS18b20io=0;
        delay_5us(255);                  //要求480-960us
        DS18b20io=1;                  //释放总线
        delay_5us(240);                  //要求释放总线后480us内结束复位
        DS18b20io=1;                  //释放总线
    }
}

void DS18b20_readTemp(void)     //读18b20温度值
{
    uchar i;
    DS18b20io=0;
    delay_5us(255);                      //要求480-960us
    DS18b20io=1;                      //释放总线
    delay_5us(30);                      //要求60-120us
    if(DS18b20io==0)
    {
        delay_5us(200);                  //要求释放总线后480us内结束复位
        DS18b20io=1;                  //释放总线
        DS18b20_w_byte(0xcc);         //发送Skip ROM命令
        DS18b20_w_byte(0x44);         //发送温度转换命令    
        DS18b20io=1;                  //释放总线
        for(i=0;i<50;i++)              //10位方式需要180ms.这里用显示子程序代替延时,可以避免LED闪烁,一举两得
            display(display_point,dispaly_dot);
        DS18b20io=0;
        delay_5us(255);                  //要求480-960us
        DS18b20io=1;                  //释放总线
        delay_5us(30);                  //要求60-120us
        if(DS18b20io==0)
        {
            delay_5us(200);              //要求释放总线后480us内结束复位
            DS18b20io=1;              //释放总线
            DS18b20_w_byte(0xcc);     //发送Skip ROM命令
            DS18b20_w_byte(0xbe);     //发送"读"暂存RAM命令
            DS18b20_temp[0]=DS18b20_r_byte();    //读温度低字节
            DS18b20_temp[1]=DS18b20_r_byte();    //读温度高字节    
            DS18b20io=0;
            delay_5us(255);              //要求480-960us
            DS18b20io=1;              //释放总线
            delay_5us(240);              //要求释放总线后480us内结束复位
            DS18b20io=1;              //释放总线
        }
    }    
}

void main(void)
{
    uchar zz;    
    uint DS18b20_tempdate;     //为整理读到的温度值而设的中间结果存放地
    display_point=&display_date[0];
    EA=0;                
    DS18b20_int();
    EA=1;
    while(1)
    {
        EA=0;                
        DS18b20_readTemp();
        EA=1;
        if(DS18b20_temp[1]&0xf8)  //显示零下温度,小数不显示,有负标志
        {
            DS18b20_tempdate=DS18b20_temp[1]<<8;
            DS18b20_tempdate+=DS18b20_temp[0];
            DS18b20_tempdate&=0x03ff;
            DS18b20_tempdate=DS18b20_tempdate>>2;
            DS18b20_tempdate-=1;
            DS18b20_tempdate=~DS18b20_tempdate;           //以上是将18b20里的负温度补码转换为原码
            
            DS18b20_tempdate=DS18b20_tempdate/4;
            zz=(uchar)(DS18b20_tempdate&0x00ff);       //这是整数位,小数位忽略不显示
            display_date[0]=12;                        //负温度标志“-”
            display_date[1]=zz/10;                     //温度十位数
            display_date[2]=zz%10;                       //温度个位数
            dispaly_dot=9;
        }
        else                      
        {
            DS18b20_tempdate=(((DS18b20_temp[1]&0x07)<<8)+DS18b20_temp[0])>>2;
            DS18b20_temp[1]=DS18b20_tempdate>>2;       //这是整数位
            DS18b20_temp[0]=DS18b20_tempdate&0x03;       //这是小数位
            if(DS18b20_temp[1]>=100)                   //如果超过100度,就不显示小数位
            {                      //显示100度以上温度,无小数位
                display_date[0]=DS18b20_temp[1]/100;       //温度百位数
                display_date[1]=(DS18b20_temp[1]-100)/10;  //温度十位数
                display_date[2]=(DS18b20_temp[1]-100)%10;  //温度个位数
                dispaly_dot=9;
            }
            else                  //0-100度,显示一位小数
            {
                display_date[0]=DS18b20_temp[1]/10;     //温度十位数
                display_date[1]=DS18b20_temp[1]%10;     //温度个位数
                switch(DS18b20_temp[0])
                {
                    case 0:display_date[2]=0;break;
                    case 1:display_date[2]=2;break;
                    case 2:display_date[2]=5;break;
                    case 3:display_date[2]=8;break;
                    default:display_date[2]=0;
                }
                dispaly_dot=1;
            }
        }
        display_date[3]=13;             //显示温度符号“c”
        display(display_point,dispaly_dot);                //实际显示温度
            
    }
}

 
 
  

⌨️ 快捷键说明

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