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

📄 ds18b20_drive.lst

📁 DS18B20的驱动程序
💻 LST
字号:
C51 COMPILER V8.02   DS18B20_DRIVE                                                         01/22/2009 20:44:42 PAGE 1   


C51 COMPILER V8.02, COMPILATION OF MODULE DS18B20_DRIVE
OBJECT MODULE PLACED IN DS18B20_drive.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE DS18B20_drive.c BROWSE DEBUG OBJECTEXTEND

line level    source

   1          #include <reg52.h>
   2          #define uchar unsigned char
   3          #define uint unsigned int
   4          
   5          uchar tplsb, tpmsb;//温度值低位、高位字节
   6          sbit DQ = P0^7;
   7          
   8          //延时t毫秒
   9          void delay(uint t)
  10          {
  11   1          uint i;
  12   1          for(;t>0;t--)
  13   1              //对于11.0592MHz时钟,延时约1ms
  14   1              for(i=125;i>0;i--);
  15   1      }
  16          
  17          //产生复位脉冲初始化DS18B20
  18          void txReset()
  19          {
  20   1          uint i;
  21   1          DQ = 0;
  22   1      
  23   1          //DQ拉低约900us
  24   1          i = 100;
  25   1          while(i>0) i--;
  26   1      
  27   1          //产生上升沿
  28   1          DQ = 1;
  29   1          i = 4;
  30   1          while(i>0) i--;
  31   1      }
  32          
  33          //等待应答脉冲
  34          void rxWait()
  35          {
  36   1          uint i;
  37   1          while(DQ);
  38   1          while(~DQ);//检查到应答脉冲
  39   1          i = 4;
  40   1          while(i>0) i--;
  41   1      }
  42          
  43          //读取数据的一位,满足读时隙要求
  44          bit readBit()
  45          {
  46   1          uint i;
  47   1          bit b;
  48   1          DQ = 0;
  49   1          i++;//保持低至少1us
  50   1          DQ = 1;
  51   1          i++; i++;//延时15us以上,读时隙下降沿后15us,DS18B20输出数据才有效
  52   1          b = DQ;
  53   1          i = 8;
  54   1          while(i>0) i--;//读时隙不低于60us
  55   1          return(b);
C51 COMPILER V8.02   DS18B20_DRIVE                                                         01/22/2009 20:44:42 PAGE 2   

  56   1      }
  57          
  58          //读取数据的一个字节
  59          uchar readByte()
  60          {
  61   1          uchar i, j, b;
  62   1          b = 0;
  63   1          for(i=0;i<8;i++)
  64   1          {
  65   2              j = readBit();
  66   2              b = (j<<7)|(b>>1);
  67   2          }
  68   1          return(b);
  69   1      }
  70          
  71          //写数据的一个字节,满足写1和写0的时隙要求
  72          void writeByte(uchar b)
  73          {
  74   1          uint i;
  75   1          uchar j;
  76   1          bit btemp;
  77   1          for(j=0;j<8;j++)
  78   1          {
  79   2              btemp = b&0x01;
  80   2              b >>= 1;//取下一位,由低位向高位
  81   2              if(btemp)
  82   2              {
  83   3                  //写1
  84   3                  DQ = 0;
  85   3                  i++; i++;//延时,使得15us以内拉高
  86   3                  DQ = 1;
  87   3                  i = 8;
  88   3                  while(i>0) i--;//整个写1时隙不低于60us
  89   3              }
  90   2              else
  91   2              {
  92   3                  //写0
  93   3                  DQ = 0;
  94   3                  i = 8;
  95   3                  while(i>0) i--;//保持低电平在60us到120us之间
  96   3                  DQ = 1;
  97   3                  i++;
  98   3                  i++;
  99   3              }
 100   2          }
 101   1      }
 102          
 103          //启动温度转换
 104          void convert()
 105          {
 106   1          txReset();//产生复位脉冲,初始化DS18B20
 107   1          rxWait();//等待DS18B20给出应答脉冲
 108   1          delay(1);//延时1ms
 109   1          writeByte(0xcc);//skip rom命令
 110   1          writeByte(0x44);//convert T 命令
 111   1      }
 112          
 113          //读取温度值
 114          void readTemp()
 115          {
 116   1          txReset();//产生复位脉冲,初始化DS18B20
 117   1          rxWait();//等待DS18B20给出应答脉冲
C51 COMPILER V8.02   DS18B20_DRIVE                                                         01/22/2009 20:44:42 PAGE 3   

 118   1          delay(1);//延时1ms
 119   1          writeByte(0xcc);//skip rom命令
 120   1          writeByte(0xbe);//read scratchpad命令
 121   1          tplsb = readByte();//温度值低位字节(其中低4位为二进制的“小数”部分)
 122   1          tpmsb = readByte();//温度值高位字节(其中高5位为符号位)
 123   1      }
 124          
 125          
 126          
 127          //开始测试
 128          //温度值显示在LCD上,显示格式如下:
 129          //LCD字符位置:1  2   3   4   5   6   7   8   9   10  11  12  13  14  15  16
 130          //LCD的第一行:R  e   a   l       t   i   m   e       T   e   m   p   :
 131          //LCD的第二行:           +       x   x   x.  x   x   x   x   。  C
 132          sbit LCDRS = P3^3;
 133          sbit LCDRW = P3^4;
 134          sbit LCDEN = P3^5;
 135          
 136          uchar code NumTable[] = "0123456789";
 137          uchar code HeadLine[] = "Real time Temp:";//15个字符
 138          uchar code SecoLine[] = "   + xxx.xxxx。C";//14个字符
 139          
 140          void write_com(uchar com) //写命令
 141          {
 142   1          LCDRS = 0;
 143   1          LCDRW = 0;
 144   1          LCDEN = 0;
 145   1          P1 = com;
 146   1          LCDEN = 1;
 147   1          delay(5);
 148   1          LCDEN = 0;
 149   1      }
 150          
 151          void write_data(uchar dat) //写数据
 152          {
 153   1          LCDRS = 1;
 154   1          LCDRW = 0;
 155   1          LCDEN = 0;
 156   1          P1 = dat;
 157   1          LCDEN = 1;
 158   1          delay(5);
 159   1          LCDEN = 0;
 160   1      }
 161          
 162          
 163          void init()
 164          {
 165   1          uchar i;
 166   1      
 167   1          //初始化LCD
 168   1          write_com(0x38);
 169   1              write_com(0x0c);
 170   1              write_com(0x06);
 171   1              write_com(0x01);
 172   1              write_com(0x80);
 173   1      
 174   1          //在LCD上显示第一行:“Real time Temp:”//15个字符
 175   1          for(i=0;i<15;i++)
 176   1          {
 177   2              write_data(HeadLine[i]);
 178   2          }
 179   1      
C51 COMPILER V8.02   DS18B20_DRIVE                                                         01/22/2009 20:44:42 PAGE 4   

 180   1          //在LCD上显示第二行:“   + xxx.xxxx。C”//14个字符
 181   1          write_com(0x80+0x40);//换行
 182   1          for(i=0;i<12;i++)
 183   1          {
 184   2              write_data(SecoLine[i]);
 185   2          }
 186   1          write_com(0x80+0x40+0x0d);
 187   1          write_data(0xdf);//显示“。”
 188   1          write_data(0x43);//显示“C”
 189   1      }
 190          
 191          
 192          void main()
 193          {
 194   1          uint tempMsb, tempLsb, temp;
 195   1          uchar bai, shi, ge;//温度整数部分的数据
 196   1          uchar xiao1, xiao2, xiao3, xiao4;//温度小数部分的数据
 197   1          bit unit;//温度的正负情况
 198   1      
 199   1          init();
 200   1      
 201   1          while(1)
 202   1          {
 203   2              delay(1);//延时1ms
 204   2              convert();//启动温度转换,需要750ms
 205   2              delay(1000);//延时1s
 206   2              readTemp();//读取温度
 207   2      
 208   2              
 209   2              //将当前温度的整数部分及符号位存入tpmsb,小数部分存入tplsb
 210   2              tpmsb <<= 4;   //将其高四位符号位移出
 211   2              temp = tplsb;  
 212   2              temp >>= 4;    //将小数部分移出
 213   2              temp &= 0x0f;  //将高四位清0
 214   2              tpmsb |= temp; //当前温度的整数部分
 215   2      
 216   2              //温度的整数部分
 217   2              //当温度变化时数据逐位提出
 218   2              if(tempMsb!=tpmsb)//整数部分有变化,刷新LCD的整数部分
 219   2              {
 220   3                  tempMsb = tpmsb;
 221   3      
 222   3                  
 223   3                  temp = tpmsb;
 224   3                  temp <<= 1; 
 225   3                  unit = CY;//温度的正负情况
 226   3                  
 227   3                  
 228   3                  temp = tpmsb;
 229   3                  temp &= 0x7f;//将温度的符号位屏蔽
 230   3                  
 231   3                  bai = temp/100; //提出温度的百位数字
 232   3                  temp = temp%100;//减掉温度的百位
 233   3      
 234   3                  shi = temp/10;  //提出温度的十位数字
 235   3      
 236   3                  ge = temp%10; //提出温度的个位数字
 237   3      
 238   3                  
 239   3                  //显示当前温度
 240   3                  //百位如果为0,则百位不显示;
 241   3                  //百位和十位均为0,则只显示各位
C51 COMPILER V8.02   DS18B20_DRIVE                                                         01/22/2009 20:44:42 PAGE 5   

 242   3                  //显示当前温度的正负情况
 243   3                  write_com(0x80+0x40+0x03);
 244   3                  if(unit)
 245   3                  {
 246   4                      write_data(0x2d);//显示负号
 247   4                  }
 248   3                  else
 249   3                  {
 250   4                      write_data(0x2b);//显示正号
 251   4                  }
 252   3                  
 253   3                  //显示当前温度的百位,如果为0则不显示
 254   3                  write_com(0x80+0x40+0x05);
 255   3                  if(bai)
 256   3                  {
 257   4                      write_data(NumTable[bai]);//显示百位数字
 258   4                  }
 259   3                  else
 260   3                  {
 261   4                      write_data(0x20);//显示空格    
 262   4                  }
 263   3      
 264   3                  //显示当前温度的十位,如果百位和十位均为0,则不显示
 265   3                  if(bai|shi)
 266   3                  {
 267   4                      write_data(NumTable[shi]);//显示十位数字
 268   4                  }
 269   3                  else
 270   3                  {
 271   4                      write_data(0x20);//显示空格
 272   4                  }
 273   3      
 274   3                  //显示当前温度的个位
 275   3                  write_data(NumTable[ge]);            
 276   3                    
 277   3              }
 278   2      
 279   2              //温度小数部分的处理
 280   2              tplsb &= 0x0f; //将tplsb的温度整数部分屏蔽,仅保留小数部分
 281   2              if(tempLsb!=tplsb)//小数部分有变化,刷新LCD的小数部分
 282   2              {
 283   3                  tempLsb = tplsb;
 284   3      
 285   3                  //小数部分数值转换
 286   3                  temp = tplsb;
 287   3                  
 288   3                  temp *= 625;
 289   3                  
 290   3                  //分析出小数部分各位数字
 291   3                  xiao1 = temp/1000;//提出小数部分的第一位数字
 292   3                  temp = temp%1000;//去除小数部分的第一位
 293   3                              
 294   3                  xiao2 = temp/100;//提出小数部分的第二位数字
 295   3                  temp = temp%100;//去除小数部分的第二位
 296   3                              
 297   3                  xiao3 = temp/10;//提出小数部分的第三位数字
 298   3                              
 299   3                  xiao4 = temp%10;//提出小数部分的第四位数字
 300   3      
 301   3      
 302   3                  //显示小数部分
 303   3                  write_com(0x80+0x49);//指针指向小数的第一位
C51 COMPILER V8.02   DS18B20_DRIVE                                                         01/22/2009 20:44:42 PAGE 6   

 304   3                  write_data(NumTable[xiao1]);//刷新小数部分的第一位数字
 305   3                  write_data(NumTable[xiao2]);//刷新小数部分的第一位数字
 306   3                  write_data(NumTable[xiao3]);//刷新小数部分的第一位数字
 307   3                  write_data(NumTable[xiao4]);//刷新小数部分的第一位数字
 308   3              }
 309   2              
 310   2      
 311   2      
 312   2          }
 313   1      }
 314          
 315          


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =    722    ----
   CONSTANT SIZE    =     44    ----
   XDATA SIZE       =   ----    ----
   PDATA SIZE       =   ----    ----
   DATA SIZE        =      2       9
   IDATA SIZE       =   ----    ----
   BIT SIZE         =   ----       3
END OF MODULE INFORMATION.


C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)

⌨️ 快捷键说明

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