个粉丝

问答

专栏

资料

 发布于  2008-08-24 16:11:36
采纳率 0%
128个问答
3565

DS18B20的c读写程序

这是关于DS18B20的c读写程序,数据脚P1.0,晶振12MHZ

采用的是启东单片机开发板AY-MPU89S51E

进行温度显示,这里我们考虑用四位数码管来显示温度

显示范围-55.0到+99.5度,显示精度为0.5度

关于程序中的延时请参考ds18b20的读写时序

#include <reg52.h>
#define uchar unsigned char 

uchar tempint,tempdf;             //温度整数部分和小数部分

sbit TMDAT = P1^0;            //根据实实际情况设定
sbit ld7=P1^7;            //初始化成功标志led
sbit ld6=P1^6;            //负温度标志led
sbit point=P0^7;          //小数点显示
uchar f;                  //负温度标志

code unsigned char ledmap[]={
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xBF};
                //7段数码管0~9数字的共阳显示代码和负号位代码(最后一位)

void set_ds18b20();               //初始化DS18B20子程序
void get_temperature();           //获得温度子程序
void read_ds18b20();              //读DS18B20子程序
void write_ds18b20(uchar command);//向DS18B20写1字节子程序
void delayms(uchar count);        //延时count毫秒子程序
void disp_temp();                 //显示温度子程序

void main()
{    
     SP=0x60;                     //设置堆栈指针
     while(1)
     {
         get_temperature();       //获得温度
         if(tempdf>=8)
          {           //0.5度精度显示
             tempdf=5;
          }
         else
          {  
             tempdf=0;
          }
         disp_temp();             //显示温度
     }
}

void set_ds18b20()
{
    while(1)
    { 
        uchar delay,flag;
        flag=0;
        TMDAT=1;
        delay=1;
        while(--delay);
        TMDAT=0;                  //数据线置低电平
        delay=250;
        while(--delay);          //低电平保持500us
        TMDAT=1;                  //数据线置高电平
        delay=30;
        while(--delay);          //高电平保持60us
        while(TMDAT==0)          //判断DS18B20是否发出低电平信号
        {
            delay=210;            //DS18B20响应,延时420us
            while(--delay);
            if(TMDAT)             //DS18B20发出高电平初始化成功,返回
            {
                flag=1;           //DS18B20初始化成功标志
                ld7=0;            //初始化成功LED标志
                break;
            }
        }
        if(flag)                  //初始化成功,再延时480us,时序要求
        {
            delay=240;
            while(--delay);
            break;
        }
    }
}

void get_temperature()            //温度转换、获得温度子程序
{
    set_ds18b20();                //初始化DS18B20
    write_ds18b20(0xcc);          //发跳过ROM匹配命令
    write_ds18b20(0x44);          //发温度转换命令
    disp_temp();                  //显示温度,等待AD转换
    set_ds18b20();
    write_ds18b20(0xcc);          //发跳过ROM匹配命令
    write_ds18b20(0xbe);          //发出读温度命令
    read_ds18b20();               //将读出的温度数据保存到tempint和tempdf处

}

void read_ds18b20()
{
    uchar delay,i,j,k,temp,temph,templ;
    j=2;                          //读2位字节数据
    do
    {
    for(i=8;i>0;i--)              //一个字节分8位读取
    {
        temp>>=1;                 //读取1位右移1位
        TMDAT=0;                  //数据线置低电平
        delay=1;
        while(--delay);
        TMDAT=1;                  //数据线置高电平
        delay=4;
        while(--delay);          //延时8us
        if(TMDAT)                 //读取1位数据
            temp|=0x80;         
        delay=25;                 //读取1位数据后延时50us
        while(--delay);
    }
    if(j==2)                      //读取的第一字节存templ
        templ=temp;
    else
        temph=temp;               //读取的第二字节存temph
    }while(--j);
    f=0;
    if((temph & 0xf8)!=0x00)      //若温度为负的处理,对二进制补码的处理
    {
        f=1;             //为负温度f置1
        ld6=0;
        temph=~temph;
        templ=~templ;        
        k=templ+1;
        templ=k;
        if(k>255)
        {
           temph++;
        }
    }
    tempdf=templ & 0x0f;          //将读取的数据转换成温度值,整数部分存tempint,小数部分存tempdf
    templ>>=4;
    temph<<=4;
    tempint=temph|templ;
}

void write_ds18b20(uchar command)
{
    uchar delay,i;
    for(i=8;i>0;i--)              //将一字节数据一位一位写入
    {
        TMDAT=0;                  //数据线置低电平
        delay=6;                  //延时12us
        while(--delay);
        TMDAT=command&0x01;       //将数据放置在数据线上
        delay=25;                 //延时50us
        while(--delay);
        command=command>>1;       //准备发送下一位数据
        TMDAT=1;                  //发送完一位数据,数据线置高电平
    }
}

void disp_temp()
{
    uchar tempinth,tempintl,cnt;

    tempinth=tempint/10;         //整数高半字节
    tempintl=tempint%10;         //整数低半字节
    cnt=200;                     //循环显示200次
    while(--cnt)
    {
    while(f==1)
    {
    P0=ledmap[10];
    if(tempinth==0)
    {
     P2=0xef;
     delayms(1);

     goto loop;
    }
    else
    {P2=0xdf;}
    }
    delayms(1);

    P0=ledmap[tempinth];
    P2=0xef;            //开十位
    delayms(1);

loop:P0=ledmap[tempintl];
    P2=0xf7;            //开个位
    point=0;            //小数点显示
    delayms(1);

    P0=ledmap[tempdf];
    P2=0xfb;            //开十分位
    delayms(1);
    }     
}

void delayms(uchar count)       //延时count ms子程序
{
    uchar i,j;
    do
    {
        for(i=5;i>0;i--)
        for(j=98;j>0;j--);
    }while(--count);
}
我来回答
回答0个
时间排序
认可量排序
易百纳技术社区暂无数据
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
相关问答
无更多相似问答 去提问
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区