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

📄 ds1820.txt

📁 关于单总线的ds18b20测温器件的一些资料和源码(含汇编和c).
💻 TXT
📖 第 1 页 / 共 2 页
字号:

DS1820读写编程中注意事项

DS1820虽然具有测温系统简单、测温精度高、连接方便、占用口线少等优点,但在实际应用中也应注意以下几方面的问题: 

  (1)较小的硬件开销需要相对复杂的软件进行补偿,由于DS1820与微处理器间采用串行数据传送,因此,在对DS1820进行读写编程时,必须严格的保证读写时序,否则将无法读取测温结果。在使用PL/M、C等高级语言进行系统程序设计时,对DS1820操作部分最好采用汇编语言实现。 

  (2)在DS1820的有关资料中均未提及单总线上所挂DS1820数量问题,容易使人误认为可以挂任意多个DS1820,在实际应用中并非如此。当单总线上所挂DS1820超过8个时,就需要解决微处理器的总线驱动问题,这一点在进行多点测温系统设计时要加以注意。 

  (3)连接DS1820的总线电缆是有长度限制的。试验中,当采用普通信号电缆传输长度超过50m时,读取的测温数据将发生错误。当将总线电缆改为双绞线带屏蔽电缆时,正常通讯距离可达150m,当采用每米绞合次数更多的双绞线带屏蔽电缆时,正常通讯距离进一步加长。这种情况主要是由总线分布电容使信号波形产生畸变造成的。因此,在用DS1820进行长距离测温系统设计时要充分考虑总线分布电容和阻抗匹配问题。 
字串2 
  (4)在DS1820测温程序设计中,向DS1820发出温度转换命令后,程序总要等待DS1820的返回信号,一旦某个DS1820接触不好或断线,当程序读该DS1820时,将没有返回信号,程序进入死循环。这一点在进行DS1820硬件连接和软件设计时也要给予一定的重视。 




读出ds1820序列号应用程序

;|       读出ds1820序列号应用程序,P1.0接ds1820        |
;|--------------------------------------------------|
         ORG 0000H
         AJMP MAIN
         ORG 0020H
;=========================================================== 
MAIN:    MOV   SP,#60H
         CLR   EA         ;使用ds1820一定要禁止任何中断产生
         LCALL   INT        ;初始化ds1820
         MOV   A,#33H
         LCALL   WRITE      ;送入读ds1820的ROM命令
         LCALL   READ       ;开始读出当前ds1820序列号
         MOV   40H,A
         LCALL   READ
         MOV   41H,A
         LCALL   READ
         MOV   42H,A
         LCALL   READ
         MOV   43H,A
         LCALL   READ
         MOV   44H,A
         LCALL   READ
         MOV   45H,A
         LCALL READ
         MOV   46H,A
         LCALL   READ
         MOV   47H,A
         LCALL   READ
         MOV   48H,A
         LCALL   READ
         MOV   49H,A
         SETB   EA
         SJMP   $
;===========================================================
INT:     CLR   EA           ;初始化ds1820子程序        
L0:   CLR   P1.0         ;ds1820总线为低复位电平
         MOV   R2,#200
L1:   CLR   P1.0
         DJNZ   R2,L1       ;总线复位电平保持400us
         SETB   P1.0        ;释放ds1820总线
         MOV   R2,#30
L4:   JNZ   R2,L4        ;释放ds1820总线保持60us
         CLR   C            ;清存在信号(存在C=1,不存在c=0)
         ORL   C,P1.0
         JC    L0            ;存在吗?不存在则重新来
         MOV   R6,#80
L5:   ORL   C,P1.0
         JC    L3
         DJNZ   R6,L5      
         SJMP   L0
L3:   MOV   R2,#240
L2:   JNZ   R2,L2
         RET
;===========================================================
WRITE:   CLR   EA           ;向ds1820写操作命令子程序
         MOV   R3,#8        ;写入ds1820的bit数,一个字节8个bit
WT1: SETB   P1.0
         MOV   R4,#8
         RRC   A            ;把一个字节data(A)分成8个bit环移给 C
         CLR   P1.0         ;开始写入ds1820总线要处于复位(低)状态
WT2: JNZ   R4,WT2       ;ds1820总线复位保持16us
         MOV   P1.0,C       ;写入一个bit
         MOV   R4,#20
WT3: JNZ   R4,WT3      ;等待40us
         DJNZ   R3,WT1      ;写入下一个bit
         SETB   P1.0        ;重新释放ds1820总线
         RET
;===========================================================
READ:    CLR   EA
         MOV   R6,#8        ;连续读8个bit
RE1: CLR   P1.0         ;读前总线保持为低
         MOV   R4,#4
         NOP
         SETB   P1.0        ;开始读,总线释放
RE2: JNZ   R4,RE2      ;持续8us
         MOV   C,P1.0       ;从ds1820总线读得一个bit
         RRC   A            ;把读得的位值环移给 A
         MOV   R5,#30
RE3: JNZ   R5,RE3      ;持续60us
         DJNZ   R6,RE1      ;读下一个bit
         SETB   P1.0        ;重新释放ds1820总线
         RET
;===========================================================  
         END 





这个只需要一根线就行了。所以你可以根据你自己的连线来定义这个数据线,我是定义在P1^3的。 
sbit DQ =P1^3; 

void delay1820(unsigned int i) 
{ 
while(i--); 
} 

//初始化函数 
Init_DS18B20(void) 
{ 
wtdg=!wtdg; 
DQ = 1; //DQ复位 
delay1820(8); //稍做延时 
DQ = 0; //单片机将DQ拉低 
delay1820(80); //精确延时 大于 480us 
DQ = 1; //拉高总线 
delay1820(14); 
xbz=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败 
delay1820(20); 
DQ=1; 
} 

//读一个字节 
ReadOneChar(void) 
{ 
unsigned char i=0; 
unsigned char dat = 0; 
wtdg=!wtdg; 
for (i=8;i>0;i--) 
{ 
DQ = 0; // 给脉冲信号 
dat>>=1; 
DQ = 1; // 给脉冲信号 
if(DQ) 
dat|=0x80; 
delay1820(4); 
} 
return(dat); 
} 

//写一个字节 
WriteOneChar(unsigned char dat) 
{ 
unsigned char i=0; 
wtdg=!wtdg; 
for (i=8; i>0; i--) 
{ 
DQ = 0; 
DQ = dat&0x01; 
delay1820(5); 
DQ = 1; 
dat>>=1; 
} 
delay(4); 
} 

void Config18b20() 
{ 
Init_DS18B20(); 
WriteOneChar(0xcc); //skip rom 
WriteOneChar(0x4e); //write scratchpad 
WriteOneChar(0x55); //上限 
WriteOneChar(0x00); //下限 
WriteOneChar(0x7f); //set 11 bit (0.125) 
Init_DS18B20(); 
WriteOneChar(0xcc); //skip rom 
WriteOneChar(0x48); //保存设定值 
Init_DS18B20(); 
WriteOneChar(0xcc); //skip rom 
WriteOneChar(0xb8); //回调设定值 
} 

void ReadTemperature() 
{ 
unsigned char a=0,s[5]; 
unsigned char b=0; 
unsigned char t=0; 
unsigned int g; 
Config18b20(); 
Init_DS18B20(); 
WriteOneChar(0xCC); // 跳过读序号列号的操作 
WriteOneChar(0x44); // 启动温度转换 
delay(500); 
Init_DS18B20(); 
WriteOneChar(0xCC); //跳过读序号列号的操作 
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度 
a=ReadOneChar(); //读取温度值低位 
b=ReadOneChar(); //读取温度值高位 
DQ=1; 
g=b<<8; //最终数据在a和b中,怎么处理你自己用吧 呵呵 
g=g|a; 
g=g*0.625; //这是转换成具体温度值,1点代表0.625°C 
cler(); 
writebbstring(1,14,tab6); //这里是我自己的显示程序,对你来说作用不大 
if(xbz==0) putch('*',2,0,0); 
sprintf(s,"%d\0",g); 
writemsst(6,2,s); 
delay(2000); 
}







//测温功能:用18B20,外部供电(寄生供电程序操作麻烦,且100度上效果不好,且实际并不节省导线(因还需要一根强上拉线),因此最好不用).
//不同温度范围均只显示3位温度(但显示方式不一致,见主程序).若18B20的VDD(3脚)与电源5伏接触不良,则只能读出它默认的85度.
//晶振是11.0592M.若用别的频率,延时必须修改!!!  所有与温度有关的函数和变量均以DS18b20_开头.
//LED显示:4位共阳,动态显示.9012控制位选,P0口通过200欧电阻控制段选.比较亮,可考虑增大电阻.

#include<intrins.h>     
#include"AT89X52.H"
#include <stdio.h>
#define uint unsigned int

⌨️ 快捷键说明

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