ATmega16的DS18B20测温程序

合集下载

DS18B20测温流程图

DS18B20测温流程图

主程序流程图:
DS18B20程序流程图:
程序按数据手册的时序图编写子函数模块:
1、DS18B20复位函数:resetDS18B20(void)
2、写一位的函数:WriteBit (unsigned char wb)
3、读一位的函数:unsigned char ReadBit (void)
4、读一个字节的函数:unsigned char readByteDS18B20(void)
即将位读取的时序循环8次。

5、写一个字节的函数:void writeByteDS18B20(unsigned char Data)。

即将位写入的时序循环8次。

6、first和next函数流程图:
1、端口初始化子函数;
2、串口初始化;
3、串口发送一个字符函数:void USART_Putchar(unsigned char
send_char)
4、串口发送数组函数:void UsartTransmit(unsigned char *data,
unsigned char len)
5、串口发送字符串函数:void USART1_Putstr(char *s)
即通过字符串长度控制USART_Putchar函数的循环次数。

6、串口发送字符串子程序(带有换行符):
void USART1_Puts(char *s)
7、串口接收字符串函数:unsigned char getchar1(void)
8、串口接收中断子程序:void USART_RXT(void)流程图
1、 数据打包子函数:void Packet_Data(void)
2、。

DS18B20温度采集和显示程序

DS18B20温度采集和显示程序

这个是我自己制作的51单片机板上的DS18B20温度采集和显示程序,你如果有现成的51板稍微修改一下可以用,在我这里是可以用没问题的。

环境是KEIL。

我这个51板也完全符合你的要求。

#pragma db code#include<AT89X52.H>//#include "reg52.h"#include "INTRINS.H"// 此实验是使用18B20检测温度,然后在数码管上显示#define uchar unsigned char#define uint unsigned int#define BUSY1 (DQ1==0)sbit LED_0=P1^0;sbit LED_1=P1^1;sbit LED_2=P1^2;sbit LED_3=P1^3;sbit DQ1=P1^6;//void delay(uint x);void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4);void ds_reset_1(void);void wr_ds18_1(char dat);void time_delay(unsigned char time);int get_temp_1(void);void delay(unsigned int x);void read_ROM(void);int get_temp_d(void);/*=====0-9=====A-G=====*/uchar a[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0x86,0x8e,0x82}; unsigned char ResultSignal;int ResultTemperatureLH,ResultT emperatureLL,ResultTemperatureH; unsigned char ROM[8];unsigned char idata TMP;unsigned char idata TMP_d;unsigned char f;unsigned char rd_ds18_1();unsigned int TemH,TemL;void main(){unsigned int TemH,TemL,k=0;ds_reset_1();ds_reset_1(); //resetwr_ds18_1(0xcc); //skip rom_nop_();wr_ds18_1(0x7f);ds_reset_1();wr_ds18_1(0xcc);_nop_();wr_ds18_1(0x44);for(k=0;k<11000;k++)time_delay(255);ds_reset_1();while(1){wr_ds18_1(0xcc);wr_ds18_1(0xbe);TemH=get_temp_1();TemL=get_temp_d();TemH&=0x00ff;TemL&=0x00ff;display((TemH/10),(T emH%10),(TemL/10),(TemL%10));}}/***************延时程序,单位us,大于10us*************/ void time_delay(unsigned char time){time=time-10;time=time/6;while(time!=0)time--;}/*****************************************************//* reset ds18b20 */ /*****************************************************/void ds_reset_1(void){unsigned char idata count=0;DQ1=0;time_delay(240);time_delay(240);DQ1=1;return;}void check_pre_1(void){while(DQ1);while(~DQ1);time_delay(30);}void read_ROM(void){int n;check_pre_1();wr_ds18_1(0x33);for(n=0;n<8;n++){ROM[n]=rd_ds18_1();}}/*****************************************************//* Read a bit from 1820 位读取*/ /*****************************************************/bit tmrbit_1(void){idata char i=0;bit dat;DQ1=0;_nop_();DQ1=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();dat = DQ1;time_delay(50);return dat;}/*****************************************************//* read a bety from ds18b20 字节读取*/ /*****************************************************/unsigned char rd_ds18_1(){unsigned char idata i,j,dat=0;for(i=1;i<=8;i++){j=tmrbit_1();dat=(j<<(i-1))|dat;}return dat;}/*****************************************************//* write a bety from ds18b20 写字节*/ /****************************************************/void wr_ds18_1(char dat){signed char idata i=0;unsigned char idata j;bit testb;for(j=1;j<=8;j++){testb=dat & 0x01;dat = dat>>1;if(testb){DQ1=0;_nop_();_nop_();DQ1=1;time_delay(60);}else{DQ1=0;time_delay(50);DQ1=1;_nop_();_nop_();}}}int get_temp_1(void){unsigned char idata a=0,b=0; unsigned char idata i;EA=0;ds_reset_1();check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0x44);while(BUSY1);ds_reset_1();check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0xbe);a=rd_ds18_1();b=rd_ds18_1();i=b; /*若b为1则为负温*/ i=(i>>4);if(i==0){f=0;TMP=((a>>4)|(b<<4));a=(a&0x0f);if (a>8){TMP=(TMP+1);}}else{f=1;a=a>>4;b=b<<4;TMP=(a|b);TMP=~TMP;TMP=(TMP+1);}EA=1;return(TMP);}int get_temp_d(void){unsigned char idata a=0,b=0; unsigned char idata i,m;EA=0;ds_reset_1();//复位check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0x44);while(BUSY1);ds_reset_1();check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0xbe);a=rd_ds18_1();b=rd_ds18_1();i=b; /*若b为1则为负温*/ i=(i>>4);if(i==0){f=0;TMP=((a>>4)|(b<<4)); a=(a&0x0f);TMP_d=a;}else{f=1;a=~a;a=(a+1);b=~b;b=(b+1);m=a;a=a>>4;b=b<<4;TMP=(a|b);m=(m&0x0f);TMP_d=m;}EA=1;return(TMP_d);}void delay(unsigned int x) {unsigned int i;for(i=0;i<x;i++);}void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4) {P2=a[d1];LED_0=0;delay(100);LED_0=1;P2=a[d2];LED_1=0;delay(100);LED_1=1;P2=a[d3];LED_2=0;delay(100);LED_2=1;P2=a[d4];LED_3=0;delay(100);LED_3=1;}。

DS18B20测温程序

DS18B20测温程序

DS18B20测温程序(数码显示)*;************************************************************************** ;*接线方法: *;* 1、用一8P的数据线,一头插在J1,另一头插在J5,接通数码管的段选*;* 2、用一8P的数据线,一头插在J4,另一头插在J6,接通数码管的位选*;* 3、将DS18B20插在主机上的测温部份 *;* 4、用一根单根的数据线,一头插在DS18B20所在数据插针,另一头插到P2.7 * ;**************************************************************************TEMPER_L EQU 36H ;从DS18B20中读回高位,低位暂存区TEMPER_H EQU 35H ;TEMPER_NUM EQU 60H;温度值存储TEMPER_GE EQU 61HTEMPER_SHI EQU 62HTEMPER_SAVE EQU 63HFLAG1 BIT 00HFLAG2 BIT 01HRS BIT p3.0;液晶控制接口RW BIT p3.1E BIT p3.2DQ BIT P2.7;单总线口ORG 0000HA JMP MAINORG 0030HMAIN: MOV SP,#70HLCALL GET_TEMPERLCALL TEMPER_COVLCALL DISPLAYLJMP MAINNOP;**************************************************;读出转换后的温度值;**************************************************GET_TEMPER:SETB DQ ; 定时入口BCD: LCALL INIT_1820JB FLAG1,S22LJMP BCD ;若DS18B20不存在则返回S22: LCALL DELAY1MO V A,#0CCH ; 跳过ROM匹配------0CC命令LCALL WRITE_1820MOV A,#44H ; 发出温度转换命令LCALL WRITE_1820LCALL DELAYCBA CALL INIT_1820JB FLAG1,ABCLJMP CBAABC CALL DELA Y1MOV A,#0CCH ; 跳过ROM匹配LCALL WRITE_1820MOV A,#0BEH ; 发出读温度命令LCALL WRITE_1820LCALL READ_18200 ;READ_1820RET;************************************************************** ;读DS18B20的程序,从DS18B20中读出一个字节的数据;************************************************************** READ_1820:MOV R2,#8RE1:CLR CSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE1RET;******************************************************;写DS18B20的程序;******************************************************WRITE_1820:MOV R2,#8CLR CWR1:MOV R3,#6DJNZ R3,$RRC AMOV DQ,CMOV R3,#23DJNZ R3,$SETB DQNOPDJNZ R2,WR1SETB DQRET;****************************************************;读DS18B20的程序,从DS18B20中读出两个字节的温度数据;****************************************************READ_18200:MOV R4,#2 ; 将温度高位和低位从DS18B20中读出MOV R1,#36H ; 低位存入36H(TEMPER_L),高位存入35H(TEMPER_H) RE00:MOV R2,#8RE01:CLR CSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE01MOV @R1,ADEC R1DJNZ R4,RE00RET;;****************************************************;将从DS18B20中读出的温度数据进行转换;;****************************************************TEMPER_COV:MOV A,#0F0HANL A,TEMPER_L ; 舍去温度低位中小数点后的四位温度数值SWAP AMOV TEMPER_NUM,A ;得到低四位MOV A,TEMPER_LJNB ACC.3,TEMPER_COV1 ; 四舍五入去温度值INC TEMPER_NUMTEMPER_COV1:MOV A,TEMPER_HANL A,#07HSWAP AORL A,TEMPER_NUM ;得到高四位,再与低四位相或得到值MOV TEMPER_NUM,A ; 保存变换后的温度数据LCALL BIN_BCDRET;;**************************************************** ;将16进制的温度数据转换成压缩BCD码;;**************************************************** BIN_BCD:MOV A,TEMPER_NUMMOV B,#10DIV ABMOV TEMPER_SHI,AMOV TEMPER_GE,BMOV A,TEMPER_SAVECJNE A,TEMPER_GE,ZWFHRET:MOV TEMPER_SAVE,TEMPER_GERETZW:CALL LCDDISPAJMP FHRET;**************************************************** ;DS18B20初始化程序;;**************************************************** INIT_1820:SETB DQNOPCLR DQMOV R0,#250TSR1:DJNZ R0,TSR1 ; 延时520usSETB DQMOV R0,#25H ;96US-25HTSR2:DJNZ R0,TSR2JNB DQ,TSR3;如D0为低则复位成功,DS18B20存在LJMP TSR4 ; 延时TSR3:SETB FLAG1 ; 置标志位,表示DS1820存在LJMP TSR5TSR4:CLR FLAG1 ; 清标志位,表示DS1820不存在LJMP TSR7TSR5:MOV R0,#06BH ;200USTSR6:DJNZ R0,TSR6 ; 延时TSR7:SETB DQ ;拉高总线RET;************************************************* ;数码显示程序;************************************************* Display:MOV DPTR,#disptabMOV A,TEMPER_GEMOVC A,@A+DPTRMOV P1,ACLR P2.2CALL DELAYCALL DELAYSETB P2.2MOV DPTR,#disptabMOV A,TEMPER_SHIMOVC A,@A+DPTRMOV P1,ACLR P2.3CALL DELAYCALL DELAYSETB P2.3RET;************************************************* ;液晶显示程序;*************************************************mov p0,#01h;清屏call enrwmov p0,#38h;设为8位,5*7字型两行 call enrwmov p0,#0Chcall enrwmov p0,#06hcall enrwmov p0,#80hcall enrwmov dptr,#yjtabcall rwrammov p0,#0C0hcall enrwmov dptr,#yjtab1call rwramW_TEM:mov p0,#0CChcall enrwMO V DPTR,#ASCIIMO V A,TEMPER_SHIMO VC A,@A+DPTRMO V P0,Asetb rsclr rwclr ecall delaysetb eMO V DPTR,#ASCIIMO V A,TEMPER_GEMO VC A,@A+DPTRMO V P0,Asetb rsclr rwclr ecall delaysetb eRE Tenrw:clr rsclr rwclr esetb eretrwram:mov r1,#00ha1: mov a,r1movc a,@a+dptrcall rwram2inc r1cjne a,#00h,a1retrwram2:mov p0,asetb rsclr rwclr ecall delaysetb eret;*************************************************;延时子程序;*************************************************DELAY:MOV R6,#250;延时500usDJNZ R6,$RETDELAY1:MOV R7,#20HDJNZ R7,$RETdisptab:db 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H;字形代码表 ;0 1 2 3 4 5 6 7 8 9yjtab: db 'HTTP// ',00hyjtab1:db 'CHENZHOU_TE:**`C',00hASCII: DB 30H,31H,32H,33H,34H,35H,36H,37H,38H,39Hend。

DS18B20程序包含温度设置、报警、华氏温度和摄氏温度转换

DS18B20程序包含温度设置、报警、华氏温度和摄氏温度转换
for(j=1;j<=123;j++);
}
void reset()//对ds18b20进行复位
{ unsignedinti;
DQ = 1; //DQ复位
_nop_(); //稍做延时,此为延时1ms函数
DQ = 0; //单片机将DQ拉低
i=70;while(i>0)i--; //根据协议要满足大于480us
unsignedchar j;
bitb;
for(j=0;j<8;j++)
{
b=dat& 0x01;
dat>>=1;
if(b) //写"1",将DQ拉低15us后,在15us~60us内将DQ拉高,即完成写1
{
DQ=0;
i++;i++; //此处延时16us。满足延时15us以后
DQ=1;//将DQ拉高
if(c==0)//每按下一次k0,则进行温度设定选项和温度显示值的功能的转换
{kf=!kf;
delayms(250);
while(!kf)
displayset();
}
};break;
case0x0d:
{
c=1+4*d;
if(c==1&&kf==0)
{
down++;//按下k1,报警温度上限值加1
delayms(200);
{
t=t+(0.01);
final=t*100;
hf=(32+t*1.8)*100;//华氏温度转换
}
else
{
final=t*100;

温度传感器DS18B20检测程序说明

温度传感器DS18B20检测程序说明

DS18B20美国达拉斯公司生产的单总线协议的数字温度检测芯片,数据的写入与读取都在一根总线上进行操作,在总线上可以连接多个DS18B20,因为每个DS18B20都有唯一的光刻ROM序列号,所以可以进行ROM匹配,搜索指令进行选择相应的从机序列号。

编写DS18B20的检测程序主要包括:初始化函数(复位脉冲+存在脉冲),写数据函数,读取数据的函数。

对DS18B20的操作包括:初始化函数,ROM指令,RAM指令这三个部分。

接下来我先说一下这三个部分所对应的时序图的理解吧。

初始化:由于上拉电阻的存在,总线默认状态是高电平,接着主机将总线拉低,维持480us 到960us的时间,再接着就是释放总线,维持时间为15us到60us,接着就由从机发出一个低电平信号,将总线拉低,表示该DS18B20是正常地,或者说是存在的,其维持时间为60us 到240us。

上面一图是写入数据的时序图。

写时序:默认状态为高电平,先将总线拉低,至少维持1us 的延时时间,接着就往总线上进行写数据操作,接着DS18B20就开始采样数据了,整个过程时间为60us到120us。

下面一图是读取数据的时序图。

读时序:默认状态为高电平,先将总线拉低,接着在15us 之前,主机进行数据采样,其维持时间也为60us到120us。

下面是我在理解了DS18B20的原理之后所写的程序,调试成功了,且能实时读取外界温度的功能,这里是不读取小数部分的温度,只读取温度的正数值。

#include<reg52.h>#define uint unsigned int#define uchar unsigned charuchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};sbit DQ=P2^2;sbit duan=P2^6;sbit wei=P2^7;//是在11.0592M赫兹的频率下void delay_ms(uint t){uint i;for(;t>0;t--)for(i=110;i>0;i--);} //约为tms的延时程序void delay(uint x){while(x--);}void init_ds18b20(){uchar n;DQ=1;delay(2); //约为38usDQ=0;delay(80); //约为800usDQ=1;delay(4); //约为58usn=DQ;delay(10); //约为110us}void write_byte(uchar dat){uchar i;for(i=0;i<8;i++){DQ=0; //无论是写0或写1都要有至少1us的低电平DQ=dat&0x01;//总线直接等于写入的数据(低位在前,高位在后)delay(4); //约为58usDQ=1; //释放总线,为下一步的数据变换做准备dat>>=1;//数据进行移位操作}delay(4);}uchar read_byte(){uchar i,value;for(i=0;i<8;i++){DQ=0;value>>=1; //移位7次DQ=1; //先要释放总线,那样才能采样到有效数据if(DQ) //判断8次{value|=0x80;}delay(6); //约为78us}return value;}uchar read_temperature(){uchar a,b;init_ds18b20(); //每次操作指令前,都必须进行初始化设置write_byte(0xcc);//跳过ROM指令write_byte(0x44);//进行温度转换处理delay(300);//进行一定地延时约为3ms左右init_ds18b20();write_byte(0xcc);//跳过ROM操作write_byte(0xbe);//读取温度a=read_byte();//温度低字节b=read_byte();//温度高字节b<<=4;//b左移四位,低四位为0000b=b+(a&0xf0)>>4;//将a的低四位屏蔽,不取小数点,进行右移四位,合并成一个字节的数据return b;}void display(uchar aa,uchar bb) {duan=1;P0=table[aa];duan=0;P0=0xff;wei=1;P0=0xfe;wei=0;delay_ms(5);duan=1;P0=table[bb];duan=0;P0=0xff;wei=1;P0=0xfd;wei=0;delay_ms(5);}void main(){uchar num,shi,ge;while(1){num=read_temperature();shi=num/10; //分离出十位ge=num%10; //分离出个位display(shi,ge);}}。

DS18B20温度检测

DS18B20温度检测

目录1引言 (1)2系统描述 (2)2.1系统功能 (2)2.2系统设计指标 (2)3系统的主要元件 (3)3.1单片机 (3)3.2温度传感元件 (4)3.3LCD显示屏 (6)4硬件电路 (7)4.1系统整体原理图 (7)4.2单片机晶振电路 (7)4.3温度传感器连接电路 (8)4.4LCD电路 (9)4.5报警和外部中断电路 (10)5结论 (11)温度监测系统硬件设计摘要:利用DS18B20为代表的新型单总线数字式温度传感器实现温度的监测,可以简化硬件电路,也可以实现单线的多点分布式温度监测,而不会浪费单片机接口,提供了单片机接口的利用率。

同时提高了系统能够的抗干扰性,使系统更灵活、方便。

本系统主要实现温度的检测、显示以及高低温的报警。

也可以通过单总线挂载多个DS18B20实现多点温度的分布式监测。

关键词: DS18B20,单总线,温度,单片机1引言在科技广泛发展的今天,计算机的发展已经越来越快,它的应用已经越来越广泛。

而单片机的发展和应用是其中的重要一方面。

单片机在工业生产(机电、化工、轻纺、自控等等)和民用家电各方面有广泛的应用。

其中,单片机在工业生产中的应用尤其广泛。

单片机具有集成度高,处理能力强,可靠性高,系统结构简单,价格低廉的优点,因此被广泛应用。

在工业生产中,电流、电压、温度、压力、流量、流速和开关量都是常用的主要测量参数。

例如:在冶金工业、化工工业、电力工程、机械制造和食品加工等许多领域中,人们都需要对各类加热炉、热处理炉、反映炉和锅炉,尤其是热学试验(如:物体的比热容、汽化热、热功当量、压强温度系数等教学实验)中的温度进行测量,并经常会对其进行控制。

传统的方式是采用热电偶或热电阻,但是由于模拟温度传感器输出为模拟信号,必须经过A/D 转换环节获得数字信号后才能够被单片机等微处理器接收处理,使得硬件电路结构复杂,制作成本较高。

近年来,美国DALLAS公司生产的DS18B20为代表的新型单总线数字式温度传感器以其突出优点广泛使用于仓储管理、工农业生产制造、气象观测、科学研究以及日常生活中。

DS18B20工作过程及时序

DS18B20工作过程及时序

DS18B20工作过程及时序DS18B20内部的低温度系数振荡器是一个振荡频率随温度变化很小的振荡器,为计数器1提供一频率稳定的计数脉冲。

高温度系数振荡器是一个振荡频率对温度很敏感的振荡器,为计数器2提供一个频率随温度变化的计数脉冲。

初始时,温度寄存器被预置成-55℃,每当计数器1从预置数开始减计数到0时,温度寄存器中寄存的温度值就增加1℃,这个过程重复进行,直到计数器2计数到0时便停止。

初始时,计数器1预置的是与-55℃DS18B20工作过程及时序DS18B20内部的低温度系数振荡器是一个振荡频率随温度变化很小的振荡器,为计数器1提供一频率稳定的计数脉冲。

高温度系数振荡器是一个振荡频率对温度很敏感的振荡器,为计数器2提供一个频率随温度变化的计数脉冲。

初始时,温度寄存器被预置成-55℃,每当计数器1从预置数开始减计数到0时,温度寄存器中寄存的温度值就增加1℃,这个过程重复进行,直到计数器2计数到0时便停止。

初始时,计数器1预置的是与-55℃相对应的一个预置值。

以后计数器1每一个循环的预置数都由斜率累加器提供。

为了补偿振荡器温度特性的非线性性,斜率累加器提供的预置数也随温度相应变化。

计数器1的预置数也就是在给定温度处使温度寄存器寄存值增加1℃计数器所需要的计数个数。

DS18B20内部的比较器以四舍五入的量化方式确定温度寄存器的最低有效位。

在计数器2停止计数后,比较器将计数器1中的计数剩余值转换为温度值后与0.25℃进行比较,若低于0.25℃,温度寄存器的最低位就置0;若高于0.25℃,最低位就置1;若高于0.75℃时,温度寄存器的最低位就进位然后置0。

这样,经过比较后所得的温度寄存器的值就是最终读取的温度值了,其最后位代表0.5℃,四舍五入最大量化误差为±,即0.25℃。

温度寄存器中的温度值以9位数据格式表示,最高位为符号位,其余8位以二进制补码形式表示温度值。

测温结束时,这9位数据转存到暂存存储器的前两个字节中,符号位占用第一字节,8位温度数据占据第二字节。

ds18b20温度检测程序(C语言)

ds18b20温度检测程序(C语言)

//18B20单线温度检测的应用样例程序#include<REG52.H>#include<math.h>#include<INTRINS.H>#include<stdio.h>#define uchar unsigned char#define uint unsigned int;/*****************************************************************************/ sbit seg1=P2^0;sbit seg2=P2^1;sbit seg3=P2^2;sbit DQ=P1^7;//ds18b20 端口sfr dataled=0x80;//显示数据端口/**********************************************************************/uchar temp;uchar flag_get,count,num,minute,second;uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//7段数码管段码表共阳uchar str[3];/***********************************************************************/void delay1(uchar MS);unsigned char ReadTemperature(void);void Init_DS18B20(void);unsigned char ReadOneChar(void);void WriteOneChar(unsigned char dat);void delay(unsigned int i);void INITchuangkou(void);//void Initdingshiqi1(void);/************************************************************************/main(){TMOD|=0x21;//定时器设置TH0=0xef;TL0=0xf0;EA=1;TR0=1;//Initdingshiqi1();INITchuangkou();P2=0x00;count=0;while(1){str[2]=0x39;//显示C符号str[0]=tab[temp/10]; //十位温度str[1]=tab[temp%10]; //个位温度if(flag_get==1) //定时读取当前温度{temp=ReadTemperature();printf("%d",temp);flag_get=0;}}}void tim(void) interrupt 1 using 1//中断,用于数码管扫描和温度检测间隔{TH0=0xef;//定时器重装值TL0=0xf0;num++;if (num==50){num=0;flag_get=1;//标志位有效second++;if(second>=60){second=0;minute++;}}count++;if(count==1){P2=0;dataled=str[0];}//数码管扫描if(count==2){P2=1;dataled=str[1];}if(count==3){ P2=2;dataled=str[2];count=0;}}/******************************************************************************void delay(unsigned int i)//延时函数{while(i--);}/****************************************************************************** *********///18b20初始化函数void Init_DS18B20(void){unsigned char x=0;DQ = 1; //DQ复位delay(8); //稍做延时DQ = 0; //单片机将DQ拉低delay(80); //精确延时大于480usDQ = 1; //拉高总线delay(10);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay(5);}//读一个字节unsigned char ReadOneChar(void){unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){DQ = 0; // 给脉冲信号dat>>=1;DQ = 1; // 给脉冲信号if(DQ)dat|=0x80;delay(5);}return(dat);}//写一个字节void WriteOneChar(unsigned char dat){unsigned char i=0;for (i=8; i>0; i--){DQ = dat&0x01;delay(5);DQ = 1;dat>>=1;}delay(5);}//读取温度unsigned char ReadTemperature(void){unsigned char a=0;unsigned char b=0;unsigned char t=0;//float tt=0;Init_DS18B20();WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换delay(200);Init_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度a=ReadOneChar();b=ReadOneChar();b<<=4;b+=(a&0xf0)>>4;t=b;//tt=t*0.0625;//t= tt*10+0.5; //放大10倍输出并四舍五入return(t);}void INITchuangkou(void){SCON=0X50;TH1=0XFD;TR1=1;TI=1;}/*void Initdingshiqi1(void);{TMOD=0X11;TH1=0XFD;TL1=0XFD; TR1=1;}*/。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//DS18B20初始化程序 uchar ds18b20_reset() {
unsigned char errTime=0;//用于循环计数
DQ_OUT;//先设置成输出 DQ_CLR;//总线拉低
Delay_Us(500);//保持500us(最小为480us,最大为960us) DQ_IN;//1 _NOP(); while(DQ_R)//探测 IO 引上是上升沿 {
uchar i; for(i=0;i<8;i++)//1个字节有8位,1位1位的传输
{ DQ_OUT;//先设置成输出 DQ_CLR;//总线拉低 Delay_Us(10);//按照写1时序,在15us 中完成所以延时10us if(value&0x01)//判断此时写入的值是1还是0 { DQ_SET;//如果是1,总线拉高,使得18B20能采样 } else DQ_CLR; Delay_Us(100);//如果是0(低电平)就不用管,继续延时(15+15+30=60us,100us 足够) DQ_SET;//释放总线 value=value>>1;//每次传输完后移位 } } uint ds18b20_read_byte(void)//18B20读一个字节的程序 { uint i,value;
for(i=0;i<8;i++) {
value=value>>1;//移位,最后一次读正好是最高位 DQ_OUT;//先设置成输出 DQ_CLR;//总线拉低 Delay_Us(10);//>1us,<15us 控制器读1时序 DQ_SET;//总线释放准备采样 DQ_IN;//采样,设置成输入 if(DQ_R)//如果读到的值是1 { value|=0x80;//从低位开始读取 } Delay_Us(50);//>45us } return value; } //读取温度值先读取暂存器的值在进行温度转换否则会意外出错 unsigned int readTempDS18B20(void) {
void write_dat(uchar dat) {
PORTD|=BIT(4); PORTD&=~BIT(5); PORTB=dat; PORTD|=BIT(6); delay(1); PORTD&=~BIT(6); } void LCD_init() {
DDRB=0XFF; DDRD|=BIT(4)|BIT(5)|BIT(6); PORTD&=~BIT(6);
ds18b20_reset();//18B20初始化 ds18b20_write_byte(0xcc);//对 ROM 进行操作,因为只接了1个器件所以写跳过指令 ds18b20_write_byte(0x44);//启动温度转换 Delay_ms(1);//给硬件一点时间让其进行转换 return(temp); }
/************************************************************** **函数功能:10us 级延时 **输入参数:x10us:延时 x10us 数 **返回值:无 **在本函数外定义变量:无 **调用的函数:无 **************************************************************/ void Delay10us(int x10us);
基于 ATMEGA16的 DS18B20测温程序
main 函数:
/* 程序功能:18B20测温结果在1602液晶上显示 说明:PA5为输入端口 18B20参数:测温范围:-55~+125℃,在-10~+85℃精确度为±5 通信方式:单总线
*/ #include <iom16v.h> #include <macros.h> #include "delay.h" #include "display.h" #include "18B20.h" #define uchar unsigned char #define uint unsigned int
uint temperture; void main() {
LCD_init();//1602液晶初始化 while(1) { temperture=readTempDS18B20(); display();//调用显示函数 } } 18B20.c:
#include <iom16v.h> #include <macros.h> #include"18B20.h" #define uchar unsigned char
--------------------------------------------------------
display.c: #include <iom16v.h> #include <macros.h> #include"display.h" #define uchar unsigned char #define uint unsigned int
#define display_h extern void write_com(uchar com); extern void write_dat(uchar dat); extern void LCD_init(); extern void display(); extern uchar table[]; #endif delay.h:
Delay_Us(6);//5.15us errTime++; if(errTime>20) return(0x00); //如果等待大于约 5.15us*20就返回0x00,报告复位失败(实际上只要等 待15-60us)
} errTime=0; while(!(DQ_R))//注意(DQ_R)与 DQ_R 不同 {
/************************************************************** **函数功能:延时1ms **输入参数:无 **返回值:无
**在本函数外定义变量:无 **调用的函数:NOP() **************************************************************/ void Delay_1ms(void);
delay(5); write_com(0X80+15); delay(5); write_dat(table1[temperture%10]); delay(5);
write_com(0X80+0X40); delay(5);
for(i=0;i<12;i++) {
write_dat(table2[i]); delay(5);
Delay_Us(6);//5.15us errTime++; if(errTime>50) return(0x00); //如果等待大于约 5.15us*50就返回0x00,报告复位失败(实际上只要等 待60-240us) } return(0xff); }
void ds18b20_write_byte(uchar value)//18B20写一个字节的程序 {
uchar table1[]="0123456789"; uchar table2[]="design:zhubo"; uchar table3[]="temperature:"; uchar table4[]=".";
extern int temperture; void delay(unsigned int ms) {
/************************************************************** **函数功能:ms 级延时 **输入参数:xms:延时 ms 数 **返回值:无 **在本函数外定义变量:无 **调用的函数:Delay_1ms() **************************************************************/ void Delay_ms(unsigned int xms);
} }
-------------------------------------------------------接口函数: 18B20.h: #define uchar unsigned char #define uint unsigned int
extern uchar ds18b20_reset(); extern void ds18b20_write_byte(uchar value); extern uint ds18b20_read_byte(void); extern uint readTempDS18B20(void); display.h: #define uchar unsigned char #define uint unsigned int #ifndef display_h
unsigned char tempL,tempH; unsigned int temp; //开始读取温度
ds18b20_reset();//18B20复位 ds18b20_write_byte(0xcc);//跳过 ROM ds18b20_write_byte(0xbe);//命令读取暂存器 tempL=ds18b20_read_byte();//从暂存器中读取数据 tempH=ds18b20_read_byte();//从暂存器中读取数据 temp=(tempH<<8)|tempL;//总值为高位*256+低位 temp=temp*0.625;//为了保留1位小数,最小单位为0.0625
相关文档
最新文档