DS18B20 理解与操作源码

最近研究了DS18B20 数字温度传感器,它的时序控制确实有点小烦躁,参看了很多资料。
其中http://www.cnblogs.com/fengmk2/archive/2007/03/11/670955.html 这篇资料算是很详细的,十分感谢作者的无私奉献。

这里,只是对自己的理解做一个记录。

  1/*
  2程序说明:
  3    功能: 
  4    1、能用上位机控制单片机,具体来说
  5    发 握手命令   单片机回状态
  6    发 读温度命令 单片机回温度
  7    2、接多点温度的情况下,可以通过串口读到任何一个点的温度    
  8    
  9    说明:
 10    1、ds18b20 都接到p3.7脚
 11    2、延时在c程序中确实不好控制,看了网上一些资料,选了一个延时,
 12    单位时间大约能做到7.8us的,理论上说通过一定的设置可以满足时序的。
 13    
 14*/

 15
 16#include <reg51.h> 
 17#include <intrins.h>
 18
 19#define uchar       unsigned char
 20#define uint        unsigned int
 21sbit ds = P3^7;
 22bit  readflag=0;
 23
 24//Fuction declaration
 25
 26// 串口函数
 27void  initCom();
 28void  receiveCom(); 
 29void  sendcharCom(uchar);
 30
 31//延时函数
 32void  delayOne(uint);
 33void  temDealy(uint);
 34
 35//操作DS18B20函数
 36void  dsInit();
 37void  dsWait();
 38bit   readBit();
 39uchar readByte();
 40void  writeByte(uchar);
 41void  sendChangeCmd();
 42void  sendReadCmd();
 43int   getTmpValue();
 44
 45
 46void main()
 47{
 48    uchar tmpValue=0
 49    initCom();
 50
 51    while (1
 52    {
 53        sendChangeCmd();
 54        delayOne(1000);
 55        tmpValue=getTmpValue();
 56        
 57        if(readflag)
 58        {
 59            readflag=0;
 60            sendcharCom(tmpValue);
 61        }

 62
 63
 64    }

 65
 66
 67}
//func main
 68
 69//串口初始化
 70void initCom()
 71{
 72     TMOD=0X20//定时器1,工作方式2 
 73     TH1=0XFD//9600bps 
 74     TL1=0XFD;
 75     TR1=1//启动定时器 
 76     PCON=0X00//波特率不倍频 
 77     SCON=0X50//串口方式1
 78     EA=1//开总中断 
 79     ES=1//开串口中断 
 80}
//func initcom
 81
 82//串口中断接受
 83void receiveCom() interrupt 4 using 3 
 84{
 85    uchar recChar;
 86    if(RI)
 87    {
 88        RI=0;
 89        recChar=SBUF;
 90        TI=1;
 91
 92        switch(recChar)
 93        {
 94            case 0xff:
 95                 SBUF=0xff;
 96                 TI=0;
 97                 break;
 98
 99            case 0x00:
100                 readflag=1;
101                 break;
102
103            default:
104                 readflag=0;
105                 break;    
106        }
    
107    }

108}
//func receivecom
109
110//串口发送程序
111void sendCharCom(uchar ch)
112{
113    SBUF=ch;
114    while(TI==0);
115    TI=0;
116}
//func sendcharcom
117
118
119//延时1ms
120void delayOne(uint t)
121{
122     uint i=0;
123     while(t--)
124     {
125          while(i<125)i++;          
126     }
    
127}
//func delayOneMs
128
129//一个delay延时约7.8-8us,12Mhz/11.0592Mhz晶振
130void temDelay(uint i)
131{
132     while(i>0)i--;                                              
133}
//func temDelay
134
135//初始化总线上的ds18b20  
136void dsInit()
137{  
138     uint i;
139     uchar etFlag;
140     ds=0;
141     temDelay(80); //延时约600us,符合协议480us的标准 
142     ds=1;//拉高总线
143     temDelay(5); //延时约40us,符合30us的标准,等待从机应答信号 
144     i++;
145     if (ds==0)
146        etFlag=1//检测到18b20 
147     else
148        etFlag=0//没有检测到18b20 
149     temDelay(20); //延时150us,等待18b20拉低总线
150     ds=1;
151}
//func dsInit
152
153//读一位数据 
154bit readBit()
155{
156     uint i;
157     bit bValue; //一位数据 
158     ds=0;
159     i++;
160     ds=1//根据读时序协议先拉低总线,延时8us后再拉高总线
161     //i++; 
162     i++
163     i++//延时16us,可以读数
164     bValue=ds; //读出一位数据 
165     temDelay(10); //延时超过60us,保证读时隙长度 
166     return bValue;
167}
//func readBit 
168
169//读一个字节的数据 
170uchar readByte()
171{
172     uint i;
173     uchar j;
174     uchar btValue; //一个字节数据 
175     btValue=0;
176     for(i=0;i<8;i++)
177     {
178          j=readBit();
179          btValue= (j<<7)|(btValue>>1);
180     }

181     return btValue;
182}
//func readByte
183
184//写一个字节的数据到18b20
185void writeByte(uchar dat)        
186{
187     uint i;
188     uchar j;
189     bit oneBit;
190     for(j=0;j<8;j++)
191     {
192          oneBit=dat && 0x01;
193          dat=dat>>1;
194          if(oneBit) //写1操作
195          {
196               ds=0;
197               i++;
198               i++//拉低15us后拉高总线
199               ds=1//完成写1操作
200               temDelay(10); //延时70us以上,符合协议写1时隙 
201          }

202          else //写0操作
203          {
204               ds=0;
205               temDelay(10); //延时70us以上,产生写0时隙,并完成写0操作 
206               ds=1
207               i++;
208          }

209     }

210}
//func writeByte
211
212//rom操作,发温度转换命令 
213void sendChangeCmd() 
214{
215     dsInit();
216     temDelay(125);
217     writeByte(0xcc); //写skip rom命令 
218     writeByte(0x44); //写温度转换命令 
219}
//func sendChangeCmd
220
221//rom操作,发读存储器命令 
222void sendReadCmd()
223{
224     dsInit();
225     temDelay(125);
226     writeByte(0xcc);
227     writeByte(0xbe); //写读暂存器命令    
228}
//func sendReadCmd
229
230//读温度 
231int getTmpValue()
232{
233     int tValue;
234     uchar tempLow,tempHigh;
235     sendReadCmd(); 
236     tempLow=readByte();
237     tempHigh=readByte();
238     tValue=(tempHigh<<8)|tempLow;
239     return tValue;
240}
//func getTmpValue 
posted @ 2008-07-24 14:44  ezra  阅读(1384)  评论(0编辑  收藏  举报