热卖开发板:
  • 51单片机开发板
  • USB开发板
  • AVR单片机开发板
  • 玩转CEPARK51实验板DS18B20之二:在数码管上显示温度(C版本^_^)

      /*
      Cepark51实验板数码管温度显示程序
      日期:2008年7月19日
      文件名:DS18b20_LED_C.c
      作者:yanwuxu
      实验板上四位数码管依次显示温度的百位,十位,个位和小数十分位
      */

      #include <at89x51.h>
      #include <intrins.h>
      #define uchar unsigned char
      #define uint unsigned int
      #define ledport P0
      sbit bai=P1^0;  //百位数码管位选
      sbit shi=P1^1;  //十位数码管位选
      sbit ge=P1^2;  //个位数码管位选
      sbit sfw=P1^3;  //十分位数码管位选
      sbit ds18b20_dat=P1^6;  //ds18b20数据端
      sbit ACC0=ACC^0;
      sbit ACC7=ACC^7;

      uchar code ds18b20_xs_tab[]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; //ds18b20小数转换表格
      uchar code ds18b20_ledtab1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//共阳数码管0~9和不显示字形码表
      uchar code ds18b20_ledtab2[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
      uchar data ds18b20_t[2]={0x00,0x00};//定义ds18b20读取温度高低字节保存位置
      bit ds18b20_flag; //ds18b20标记位,为0说明检测到ds18b20,否则没有检测到ds18b20
      uchar ds18b20_zf;//ds18b20温度正负标志保存部分
      uchar ds18b20_bai; //百位数码管缓冲区
      uchar ds18b20_shi; //十位数码管缓冲区
      uchar ds18b20_ge;  //个位数码管缓冲区
      uchar ds18b20_sfw; //十分位数码管缓冲区
      void uDelay(uint i) //us延时
      {  
      while(i--);
      }
      void mDelay(uint mDelay1) //1ms延时
      {
      uint mDelay2;
      for(;mDelay1>0;mDelay1--)
      {
        for(mDelay2=0;mDelay2<114;mDelay2++)
        {;;}
      }
      }

      /* DS18B20读一个字节*/
      uchar ds18b20_read()
      {
      uchar i;
      uchar dat;
      for(i=8;i>0;i--)
      {
        ds18b20_dat=0; //拉低总线
        dat>>=1;
        ds18b20_dat=1;
        if(ds18b20_dat)
         dat|=0x80;
         uDelay(4);
      }
      return(dat);
      }

      /* DS18B20读一个字节   //
      uchar ds18b20_read()
      {
      uchar i;
      uchar dat;
      for(i=8;i>0;i--)
      {
        ds18b20_dat=0; //拉低总线
        CY=ds18b20_dat; //读取数据到CY
        ACC7=CY;
        ds18b20_dat=1;
        ACC=ACC>>1;
        uDelay(4);
      }
      return(dat);
      }
      */

      /* DS18B20写一个字节
      void ds18b20_write(uchar ds18b20_cmd)
      {
      uchar i;
      ACC=ds18b20_cmd;
      for(i=8;i>0;i--)
      {
        ds18b20_dat=0; //拉低总线
        ds18b20_dat=ACC0;//最低位先送
        uDelay(5);  //延时约16us
        ds18b20_dat=1; //总线复位
        ACC=ACC>>1;
      }
      uDelay(5);
      }
      */

      /* DS18B20写一个字节*/

      void ds18b20_write(uchar ds18b20_cmd)
      {
      uchar i;
      for(i=8;i>0;i--)
      {
        ds18b20_dat=0; //拉低总线
        ds18b20_dat=ds18b20_cmd&0x01;
        uDelay(5);  //延时约16us
        ds18b20_dat=1; //总线复位
        ds18b20_cmd>>=1;
      }
      uDelay(5);
      }
      /* DS18B20复位*/
      void ds18b20_reset()
      {
      ds18b20_dat=1;
      uDelay(8);
      ds18b20_dat=0;
      uDelay(80);   //复位脉冲
      ds18b20_dat=1;
      uDelay(14);   //拉高总线等待应答
      ds18b20_flag=ds18b20_dat; //0是存在,1是不存在
      uDelay(20);
      ds18b20_dat=1;
      // ruturn(ds18b20_flag);
      }

      /* 读取DS18B20温度寄存器前2个字节*/
      void ds18b20_read_temp()
      {
      uchar i;
      uint ds18b20_zs; //保存转换后的整数部分
      uint ds18b20_xs; //保存转换后的小数部分
      ds18b20_reset();
      ds18b20_write(0xcc);//跳过rom
      ds18b20_write(0x44);//温度转换
      uDelay(5);
      ds18b20_reset();
      ds18b20_write(0xcc);//跳过rom
      ds18b20_write(0xbe);//读取暂存器前2个字节,第0个字节是温度低8位,第1个字节是温度高8位

      for(i=0;i<2;i++)
      {
        ds18b20_t=ds18b20_read();
      }
      ds18b20_reset();

      ds18b20_zs=((ds18b20_t[1]&0x0f)<<4)|((ds18b20_t[0]&0xf0)>>4);//整数部分转换
      ds18b20_xs=ds18b20_t[0]&0x0f;//小数部分转换
      // if(ds18b20_zs&0x80==0x80)//使用这句判断温度正负的话测试到的温度的整数如果是奇数的话则显示混乱,很不解!
      if(ds18b20_zs>0xf7)  //如果是负数
        {
         ds18b20_zs=~ds18b20_zs;
         ds18b20_xs=~ds18b20_xs+1;
      //   ds18b20_zf=0xbf;//负标记第一位数码管显示“-”
      //  }
      //  else
      //   {
      //   ds18b20_zf=0xff;//正标记数码管不显示
        }
      ds18b20_bai=(ds18b20_zs/100); //百位转换
      if(ds18b20_bai==0)
      {
        ds18b20_bai=10;
      }
      ds18b20_ge=ds18b20_zs%100;      
      ds18b20_shi=ds18b20_ge/10;    //十位转换
      ds18b20_ge=(ds18b20_ge%10); //个位转换
      // ds18b20_sfw=(ds18b20_xs*625)/1000; //使用这种方法计算小数位生成的目标文件比查表方式大了84个字节
      ds18b20_sfw=(ds18b20_xs_tab[ds18b20_xs]);//小数的十分位部分部分查表取得并转换为ASCII码

      }
      void ds18b20_disp_temp() //显示温度
      {
      ledport=ds18b20_ledtab1[ds18b20_bai];
      bai=0;
      mDelay(2);
      bai=1;
      ledport=ds18b20_ledtab1[ds18b20_shi];
      shi=0;
      mDelay(2);
      shi=1;
      ledport=ds18b20_ledtab2[ds18b20_ge];
      ge=0;
      mDelay(2);
      ge=1;
      ledport=ds18b20_ledtab1[ds18b20_sfw];
      sfw=0;
      mDelay(2);
      sfw=1;
      }

      void main()
      {
      ds18b20_reset();
      while(1)
        {
         ds18b20_read_temp();
         ds18b20_disp_temp();
         }
      }
    声明:CEPARK已尽力确保内容的准确性,但因业务发展和技术服务的需要,有关内容可能会根据实际情况随时更新或者修改,恕不另行通知,不便之处敬请谅解!
      商城推荐
      社区指南
    CEPARK电子园-电子工程师自己的网络家园!
      迷你博客,轻松完成日志发布,管理相册;展示个性自我
      兴趣小组,热点话题,加入您感兴趣的话题讨论小组,一起交流吧
      最新资讯,热门话题与好友一起分享信息,他评论感兴趣的话题
      实名认证,真实交友,还可以轻松快捷的了解好友动态
      邀请您身边的好友,朋友,同事一起加入欢乐圈