<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://jackxiang.com/post//</link>
<title><![CDATA[DS18B20驱动]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[产品管理]]></category>
<pubDate>Wed, 30 May 2012 13:09:10 +0000</pubDate> 
<guid>http://jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	一.概述<br/>DS18B20是一种单总线数字温度传感器。测试温度范围-55℃-125℃，温度数据位可配置为9、10、11、12位，对应的刻度值分别为0.5℃、0.25℃、0.125℃、0.0625℃，对应的最长转换时间分别为93.75ms、187.5ms、375ms、750ms。出厂默认配置为12位数据，刻度值为0.0625℃，最长转换时间为750ms。从以上数据可以看出，DS18B20数据位越低、转换时间越短、反应越快、精度越低。<br/>单总线，意味着没有时钟线，只有一根通信线。单总线读写数据是靠控制起始时间和采样时间来完成，所以时序要求很严格，这也是DS18B20驱动编程的难点。<br/>需要注意的是，DS18B20和同一系列的DS18S20,在读写上，时序、命令一致，但因温度值存放的位置不一样，对温度数据的处理也不一样，所以程序不能直接套用。<br/>二.电路设计<br/>在WSF-51DB开发板上，利用AT89S52单片机的P1.1脚来驱动DS18B20，上拉电阻阻值为4.7K欧姆。DS18B20的上拉电阻的阻值是一个需要注意的参数，如果DS18B20放置的位置离电路板较远，需要用较长的电缆来连接时，上拉电阻要相应减小，以弥补线路损耗，而且连接电缆要选用优质的三芯带屏蔽层的电缆，否则不能正常读写数据。<br/> <br/><a href="http://jackxiang.com/attachment.php?fid=303" target="_blank"><img src="http://jackxiang.com/attachment.php?fid=303" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>三.软件设计<br/><textarea name="code" class="c" rows="15" cols="100">
/*****************************************************************
*程序名称：DS18B20驱动
*程序功能：读写DS18B20，数码管显示温度值，温度值精度为0.1度。
*开发工具：WSF-51DB开发板
* MCU型号：AT89S52-24PU
*时钟频率：11.0592-12MHZ
*程序作者：吴师傅
*版权说明：吴师傅版权所有，转载请注明来源和作者。
*****************************************************************/
＃i nclude &lt;reg52.h&gt;
＃i nclude &lt;intrins.h&gt;
unsigned char tempflag,fraction,tempr;
unsigned char code segmcode[]=&#123;0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f&#125;;
//共阴极数码管段码0-9
unsigned char code bitcode[]=&#123;0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f&#125;;
//8位共阴极数码管位码
unsigned char code fractioncode[]=&#123;0,0,1,2,2,3,4,4,5,6,6,7,8,8,9,9&#125;;
//将DS18B20的小数部分的0-f刻度转换为0-9刻度的查找表,将精度化为0.1度
sbit ser=P2^0;//74HC595串行数据输入
sbit oe=P2^1;//74HC595使能
sbit rclk=P2^2; //74HC595数据锁存
sbit srclk=P2^3;// 74HC595串行时钟
sbit DQ=P1^1; //温度总线
 
//延时函数(12MHZ晶振):
void Delayus(unsigned char t)
&#123;&nbsp;&nbsp;//此函数精确计算：18+6*(t-1)=延时时间(us)
&nbsp;&nbsp;&nbsp;&nbsp;while(t--);
&#125;
 
//延时ms延时函数:
void Delayms(unsigned int t)
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int i,j;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=t;i&gt;0;i--)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(j=0;j&lt;120;j++);
&#125;
 
//任意位数码管显示一个字符函数：
void DTDisplayChar(unsigned char segmd,unsigned char bitd )//数码管段码和数码管位码
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned char i;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned int dat;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oe=1;//输出为高阻
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dat=bitd;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dat=dat&lt;&lt;8&#124;segmd; //位码段码合并为一个int型数据
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i=0;i&lt;16;i++)//16位数据从高位依次移入74HC595
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ser=(dat&amp;0x8000)?1:0; //判断最高位，为真取1，为假取0
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; srclk=1;&nbsp;&nbsp;&nbsp;&nbsp;//上升沿送数据
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; srclk=0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dat&lt;&lt;=1;&nbsp;&nbsp; //左移取下一位
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rclk=1;//74HC595锁存数据
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rclk=0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oe=0;//输出数据
&#125;
 
//DS18B20复位函数:
void Reset18B20(void)
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DQ=0;//拉低,开始复位操作
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Delayus(100);//延时至少480us
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DQ=1;//拉高，释放总线控制权
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(DQ);//等待器件应答（器件拉低），约15-60us后
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(!DQ);//应答脉冲出现后，等待器件拉高，约60-240us后
&#125;
//DS18B20写命令函数:
void Write18B20(unsigned char com)
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned char i;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i=0;i&lt;8;i++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DQ=0;//开始写操作
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _nop_(); _nop_();//至少延时1us
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DQ=com&amp;0x01;//写数据
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Delayus(2);//延时，器件在45us内采样
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DQ=1;//释放总线控制权
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; com&gt;&gt;=1; //右移1位，写下一位
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&#125;
 
//DS18B20读数据函数:
unsigned char Read18B20()
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned char i,rdata=0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i=0;i&lt;8;i++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DQ=0;//开始读操作
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _nop_();_nop_();//至少延时1us
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DQ=1;//释放总线控制权，15us内要读取数据
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(DQ==1) rdata&#124;=0x01&lt;&lt;i;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Delayus(10);//延时要大于45us.读0时，45us后器件才拉高总线
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return rdata;
&#125;
 
//读出温度函数:
 void Read18B20Temperature()
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned char templ,temph,temp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned int tempv;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reset18B20();//复位
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write18B20(0xcc);//写命令，跳过ROM编码命令
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write18B20(0x44);//转换命令
&nbsp;&nbsp;&nbsp;&nbsp; while(!DQ);//等待转换完成
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reset18B20();//复位
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write18B20(0xcc);//写命令，跳过ROM编码命令
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write18B20(0xbe);//读取暂存器字节命令
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;templ=Read18B20();//读低字节
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temph=Read18B20();//读高字节
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reset18B20();//复位
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempv=temph;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempv=tempv&lt;&lt;8&#124;templ;//两个字节合并为一个int型数据
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp=(unsigned char)(tempv&gt;&gt;4);//去掉小数部分,化成char型数据
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((temph&amp;0x80)==0x80)//如果是负温度
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempflag=1; //负号显示
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempr=~temp+1; //实际温度值为读取值的补码
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fraction=fractioncode[(~templ+1)&amp;0x0f];
//取小数部分补码，将16刻度转换为10刻度，精度为0.1度
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else//如果是正温度
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempflag=0;//正温度,负号不显示
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempr=temp;//
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fraction=fractioncode[templ&amp;0x0f];
//取小数部分，将16刻度转换为10刻度，精度为0.1度
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;&nbsp;&nbsp;&nbsp;&nbsp; 
&#125;
&nbsp;&nbsp; 
//主函数:
int main(void)
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempflag=0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(1)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Read18B20Temperature();//读取温度值
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DTDisplayChar(segmcode[fraction],0x7f);//显示小数部分
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Delayms(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DTDisplayChar(segmcode[tempr%10]&#124;0x80,0xbf);//显示个位和小数点
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Delayms(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DTDisplayChar(segmcode[tempr%100/10],0xdf);//显示十位
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Delayms(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(tempflag==1) DTDisplayChar(0x40,0xef);//如果是负温度就显示“-”
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else DTDisplayChar(segmcode[tempr/100],0xef);//显示百位
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Delayms(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DTDisplayChar(0xff,0xff);//均衡数码管亮度
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;
&#125;
</textarea><br/><br/>来自：http://blog.21ic.com/user1/8392/archives/2012/91760.html
]]>
</description>
</item><item>
<link>http://jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] DS18B20驱动]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>