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

📄 wend.lst

📁 单片机控制的数字温度计程序源码
💻 LST
字号:
C51 COMPILER V8.02   WEND                                                                  05/10/2008 20:26:25 PAGE 1   


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

line level    source

   1          #include<reg52.H>                  //使用1602LCD显示DS18B20转换的温度值,12MHz,
   2          #include<intrins.H>
   3          #include<math.H>
   4          
   5          #define uchar unsigned char             //定义无符号字符为 uchar,方便书写
   6          #define uint unsigned int
   7          
   8          sbit RS=P3^3; //  数据/命令选择端(H/L)
   9          sbit LCDEN=P3^5;//使能端,RW读写端接地
  10          
  11          
  12          
  13          void delayUs()
  14          {
  15   1        _nop_();
  16   1      }
  17          //写命令:RS=0, RW=0;
  18          //第一行开始地址为0x80, 第二行开始地址为0xc0;
  19          void delayMs(uint a)
  20          {
  21   1       uint i,j;
  22   1      for(i=a;i>0;i--)
  23   1        for(j=100;j>0;j--);
  24   1      }
  25          
  26          
  27          void writeComm(uchar comm)
  28          {
  29   1       RS=0;
  30   1       P1=comm;
  31   1       LCDEN=1;
  32   1      delayUs();
  33   1       LCDEN=0;
  34   1       delayMs(1);
  35   1      }
  36          // 写数据:RS=1, RW=0;
  37          void writeData(uchar dat)
  38          {
  39   1       RS=1;
  40   1       P1=dat;
  41   1       LCDEN=1;
  42   1       delayUs();
  43   1       LCDEN=0;
  44   1       delayMs(1);
  45   1      }
  46          //初始化
  47          void init()
  48          {
  49   1      
  50   1       writeComm(0x38);  //显示模式,固定指令为00111000=0x38, 16*2显示, 5*7点阵,8位数据接口
  51   1       writeComm(0x0c);  //开显示, 关光标,指令1: 00001DCB : D:开显示/关显示(H/L);
  52   1                                         //C:显示光标/不显示(H/L), B:光标闪烁/不闪烁(H/L)
  53   1        writeComm(0x06);  //写字符后地址加1, 光标加1
  54   1       writeComm(0x01);  //清屏
  55   1      }
C51 COMPILER V8.02   WEND                                                                  05/10/2008 20:26:25 PAGE 2   

  56          
  57          void writeString(uchar * str,uchar length)
  58          {
  59   1       uchar i;
  60   1       for(i=0;i<length;i++)
  61   1       {
  62   2       writeData(str[i]);
  63   2       }
  64   1      }
  65          
  66          sbit ds=P3^7;
  67          //让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动
  68          //初始化DS18B20
  69          void dsInit()
  70          {
  71   1       unsigned int i;  //  对于12MHz时钟, unsigned int型的i, 作一个i++操作的时间大约为8us
  72   1       ds=0;
  73   1       i=100;  //     拉低约800us, 符合协议要求的480us以上
  74   1       while(i>0)i--;  //产生一个上升沿, 进入等待应答状态
  75   1       ds=1;
  76   1       i=4;
  77   1       while(i>0)i--;
  78   1      }
  79          
  80          void dsWait()
  81          {
  82   1       unsigned int i;
  83   1       while(ds);
  84   1       while(~ds);//检测到应答脉冲
  85   1       i=4;
  86   1       while(i>0)i--;
  87   1      }
  88          // 向DS18B20读取一位数据
  89          //读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,
  90          //之后DS18B20则会输出持续一段时间的一位数据
  91          bit readBit()
  92          {
  93   1       unsigned int i;
  94   1       bit b;
  95   1       ds=0;
  96   1       i++;     //延时约8us, 符合协议要求至少保持1us
  97   1       ds=1;
  98   1       i++;i++;//延时约16us, 符合协议要求的至少延时15us以上
  99   1       b=ds;
 100   1       i=8;
 101   1       while(i>0)i--;  //延时约64us, 符合读时隙不低于60us要求
 102   1       return b;
 103   1      }
 104          //读取一字节数据, 通过调用readBit()来实现
 105          unsigned char readByte()
 106          {
 107   1       unsigned int i;
 108   1       unsigned char j,dat;
 109   1       dat=0;
 110   1       for(i=0;i<8;i++)
 111   1       {
 112   2        j=readBit();  //最先读出的是最低位数据
 113   2        dat=(j<<7)|(dat>>1);
 114   2       }
 115   1       return dat;
 116   1      }
 117          //向DS18B20写入一字节数据
C51 COMPILER V8.02   WEND                                                                  05/10/2008 20:26:25 PAGE 3   

 118          void writeByte(unsigned char dat)
 119          {
 120   1       unsigned int i;
 121   1       unsigned char j;
 122   1       bit b;
 123   1       for(j=0;j<8;j++)
 124   1       {
 125   2        b=dat&0x01;
 126   2        dat>>=1;        //写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1
 127   2        if(b)
 128   2        {
 129   3          ds=0;
 130   3         i++;i++;               // 拉低约16us, 符号要求15~60us内
 131   3         ds=1;
 132   3          i=8;while(i>0)i--;  //延时约64us, 符合写时隙不低于60us要求
 133   3         }
 134   2         else                 //写"0", 将DQ拉低60us~120us
 135   2         {
 136   3          ds=0;
 137   3          i=8;while(i>0)i--; // 拉低约64us, 符号要求
 138   3          ds=1;
 139   3          i++;i++; //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了
 140   3          }
 141   2         }
 142   1      }
 143          // 向DS18B20发送温度转换命令
 144          void sendChangeCmd()
 145          {
 146   1       dsInit();                       //     初始化DS18B20, 无论什么命令, 首先都要发起初始化
 147   1       dsWait();                       //等待DS18B20应答
 148   1       delayMs(1);             //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号
 149   1       writeByte(0xcc);       //写入跳过序列号命令字 Skip Rom
 150   1       writeByte(0x44);       // 写入温度转换命令字 Convert T
 151   1      }
 152          // 向DS18B20发送读取数据命令
 153          void sendReadCmd()
 154          {
 155   1       dsInit();
 156   1       dsWait();
 157   1       delayMs(1);
 158   1       writeByte(0xcc);        //写入跳过序列号命令字 Skip Rom
 159   1       writeByte(0xbe);        //写入读取数据令字 Read Scratchpad
 160   1      }
 161          //        获取当前温度值
 162          int getTmpValue()
 163          {
 164   1       unsigned int tmpvalue;
 165   1       int value;                //   存放温度数值
 166   1       float t;
 167   1       unsigned char low,high;
 168   1       sendReadCmd();  //连续读取两个字节数据
 169   1       
 170   1       low=readByte();
 171   1       high=readByte();
 172   1       
 173   1       tmpvalue=high;    // 若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的value
 174   1       tmpvalue<<=8;
 175   1       tmpvalue|=low;    //计算机中对于负数是利用补码来表示的
 176   1       value=tmpvalue;   //将高低两个字节合成一个整形变量,将高低两个字节合成一个整形变量
 177   1       t=value*0.0625;   //使用DS18B20的默认分辨率12位, 精确度为0.0625度,
 178   1                                         // 即读回数据的最低位代表0.0625度
 179   1       value=t*100+(value>0?0.5:-0.5); //将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入
C51 COMPILER V8.02   WEND                                                                  05/10/2008 20:26:25 PAGE 4   

 180   1                                     // 如t=11.0625, 进行计数后, 得到value = 1106, 即11.06 度
 181   1                                         //如t=-11.0625, 进行计数后, 得到value = -1106, 即-11.06 度大于0加0.5, 小于0减0.5
 182   1       return value;
 183   1      }
 184          
 185          void display(int v)
 186          {
 187   1       unsigned char count;
 188   1       unsigned char datas[]={0,1,2,3,4};
 189   1       unsigned int tmp=abs(v);
 190   1       datas[0]=tmp/10000;            //最高位
 191   1       datas[1]=tmp%10000/1000;
 192   1       datas[2]=tmp%1000/100;
 193   1       datas[3]=tmp%100/10;
 194   1       datas[4]=tmp%10;                       //最低位
 195   1      
 196   1      
 197   1       writeComm(0xc0+1);        //0xc0=1100 0011     ->DDRAM地址设置,两行显示,第二行开始地址,距头1个距离
 198   1       if(v<0)                                        //温度的符号判断
 199   1       {
 200   2          writeString("- ",2);        //注意符号后有一个空格
 201   2       }
 202   1       else
 203   1       {
 204   2        writeString("+ ",2);
 205   2       }
 206   1       if(datas[0]!=0)
 207   1       {
 208   2       writeData('0'+datas[0]);       //输入字符0,1,2,3,4,5,6,7,8,9
 209   2       }
 210   1       for(count=1;count!=5;count++)  //      依次显示由高到低位
 211   1       {
 212   2         writeData('0'+datas[count]);
 213   2         if(count==2)          //两高位之后小数点
 214   2        {
 215   3          writeData('.');
 216   3         }
 217   2        }
 218   1       
 219   1        }
 220          
 221          void main()
 222          {
 223   1       uchar table[]="Now Temperature:";
 224   1        sendChangeCmd();       //先放入温度传感指令再液晶驱动,将顺序执行,没有检测到温度传感则无数据输出
 225   1       init();
 226   1       writeComm(0x80);
 227   1       writeString(table,16);
 228   1      
 229   1       while(1)
 230   1       {
 231   2        delayMs(1000);        //温度转换时间需要750ms以上
 232   2        writeComm(0xc0);
 233   2        display(getTmpValue());
 234   2        sendChangeCmd();
 235   2        }
 236   1      } 


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =    720    ----
   CONSTANT SIZE    =     28    ----
C51 COMPILER V8.02   WEND                                                                  05/10/2008 20:26:25 PAGE 5   

   XDATA SIZE       =   ----    ----
   PDATA SIZE       =   ----    ----
   DATA SIZE        =   ----      35
   IDATA SIZE       =   ----    ----
   BIT SIZE         =   ----       2
END OF MODULE INFORMATION.


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

⌨️ 快捷键说明

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