51单片机Ds18b20温度传感器程序

* 实验名 : 18B20温度显示试验* 实验说明 : 数码管显示温度值,并且将温度值通过串口发送到电脑上。

* 连接方式 : 见连接图temp.h#ifndef __TEMP_H_#define __TEMP_H_#include<reg51.h>//---重定义关键词---//#ifndef uchar#define uchar unsigned char#endif#ifndef uint#define uint unsigned int#endif//--定义使用的IO口--//sbit DSPORT=P3^7;//--声明全局函数--//void Delay1ms(uint );uchar Ds18b20Init();void Ds18b20WriteByte(uchar com);uchar Ds18b20ReadByte();void Ds18b20ChangTemp();void Ds18b20ReadTempCom();int Ds18b20ReadTemp();#endiftemp.c#include"temp.h"/******************************************************************************** 函数名: Delay1ms* 函数功能: 延时函数* 输入: 无* 输出: 无*******************************************************************************/void Delay1ms(uint y){uint x;for( ; y>0; y--){for(x=110; x>0; x--);}}/******************************************************************************** 函数名: Ds18b20Init* 函数功能: 初始化* 输入: 无* 输出: 初始化成功返回1,失败返回0*******************************************************************************/ uchar Ds18b20Init(){uchar i;DSPORT = 0;//将总线拉低480us~960usi = 70;while(i--);//延时642usDSPORT = 1;//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低i = 0;while(DSPORT)//等待DS18B20拉低总线{Delay1ms(1);i++;if(i>5)//等待>5MS{return 0;//初始化失败}}return 1;//初始化成功}/******************************************************************************** 函数名: Ds18b20WriteByte* 函数功能: 向18B20写入一个字节* 输入: com* 输出: 无*******************************************************************************/void Ds18b20WriteByte(uchar dat){uint i, j;for(j=0; j<8; j++){DSPORT = 0;//每写入一位数据之前先把总线拉低1usi++;DSPORT = dat & 0x01; //然后写入一个数据,从最低位开始i=6;while(i--); //延时68us,持续时间最少60usDSPORT = 1;//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值dat >>= 1;}}/******************************************************************************** 函数名: Ds18b20ReadByte* 函数功能: 读取一个字节* 输入: com* 输出: 无*******************************************************************************/ uchar Ds18b20ReadByte(){uchar byte, bi;uint i, j;for(j=8; j>0; j--){DSPORT = 0;//先将总线拉低1usi++;DSPORT = 1;//然后释放总线i++;i++;//延时6us等待数据稳定bi = DSPORT;//读取数据,从最低位开始读取/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。

*/byte = (byte >> 1) | (bi << 7);i = 4;//读取完之后等待48us再接着读取下一个数while(i--);}return byte;}/******************************************************************************* * 函数名: Ds18b20ChangTemp* 函数功能: 让18b20开始转换温度* 输入: com* 输出: 无*******************************************************************************/ void Ds18b20ChangTemp(){Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc);//跳过ROM操作命令Ds18b20WriteByte(0x44);//温度转换命令//Delay1ms(100);//等待转换成功,而如果你是一直刷着的话,就不用这个延时了}/******************************************************************************* * 函数名: Ds18b20ReadTempCom* 函数功能: 发送读取温度命令* 输入: com* 输出: 无*******************************************************************************/ void Ds18b20ReadTempCom(){Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc);//跳过ROM操作命令Ds18b20WriteByte(0xbe);//发送读取温度命令}/******************************************************************************* * 函数名: Ds18b20ReadTemp* 函数功能: 读取温度* 输入: com* 输出: 无*******************************************************************************/ int Ds18b20ReadTemp(){int temp = 0;uchar tmh, tml;Ds18b20ChangTemp();//先写入转换命令Ds18b20ReadTempCom();//然后等待转换完后发送读取温度命令tml = Ds18b20ReadByte();//读取温度值共16位,先读低字节tmh = Ds18b20ReadByte();//再读高字节temp = tmh;temp <<= 8;temp |= tml;return temp;}main.c/******************************************************************************* * 普中科技* 实验名: 18B20温度显示试验* 实验说明: 数码管显示温度值,并且将温度值通过串口发送到电脑上。

* 连接方式: 见连接图* 注意:*******************************************************************************/ #include<reg51.h>#include"temp.h"//--定义使用的IO--//#define GPIO_DIG P0sbit LSA=P2^2;sbit LSB=P2^3;sbit LSC=P2^4;//--定义全局变量unsigned char code DIG_CODE[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码unsigned char DisplayData[8];//用来存放要显示的8位数的值//--声明全局函数--//void LcdDisplay(int);void DigDisplay();/******************************************************************************* * 函数名: main* 函数功能: 主函数* 输入: 无* 输出: 无*******************************************************************************/ void main(){while(1){LcdDisplay(Ds18b20ReadTemp());}}/******************************************************************************* * 函数名: LcdDisplay()* 函数功能: LCD显示读取到的温度* 输入: v* 输出: 无*******************************************************************************/ void LcdDisplay(int temp) //lcd显示{float tp;if(temp< 0)//当温度值为负数{DisplayData[0] = 0x40;//因为读取的温度是实际温度的补码,所以减1,再取反求出原码temp=temp-1;temp=~temp;tp=temp;temp=tp*0.0625*100+0.5;//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就//算由?.5,还是在小数点后面。

合集下载

DS18B20温度检测程序

DS18B20温度检测程序

(1)先将数据线置高电平“1”。

(2)延时(该时间要求的不是很严格,但是尽可能的短一点)(3)数据线拉到低电平“0”。

(4)延时750微秒(该时间的时间范围可以从480到960微秒)。

(5)数据线拉到高电平“1”。

(6)延时等待(如果初始化成功则在15到60毫秒时间之内产生一个由DS18B20所返回的低电平“0”。

据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时控制)。

(7)若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要480微秒。

(8)将数据线再次拉高到高电平“1”后结束。

(1)数据线先置低电平“0”。

(2)延时确定的时间为15微秒。

(3)按从低位到高位的顺序发送字节(一次只发送一位)。

(4)延时时间为45微秒。

(5)将数据线拉到高电平。

(6)重复上(1)到(6)的操作直到所有的字节全部发送完为止。

(7)最后将数据线拉高。

DS18B20的写操作时序图如图DS18B20的读操作(1)将数据线拉高“1”。

(2)延时2微秒。

(3)将数据线拉低“0”。

(4)延时15微秒。

(5)将数据线拉高“1”。

(6)延时15微秒。

(7)读数据线的状态得到1个状态位,并进行数据处理。

(8)延时30微秒。

DS18B20的读操作时序图如图所示。

DS18B20的Protues仿真图源程序代码:#include "reg51.h"#include "intrins.h" // 此头文件中有空操作语句NOP 几个微秒的延时可以用NOP 语句,但本人没用NOP,直接用了I++来延时#define uchar unsigned char#define uint unsigned intuchar code table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};sbit ds18b20_io=P2^0; //单片机与DS18B20的连接口sbit lcdrs=P2^6; //1602与单片机的接口sbit lcden=P2^7;unsigned char flag,tflag,i;unsigned int temper0,temper1,tvalue;float temperature;void delay() //6us 在KEIL中仿真出来的时间,这是调用DELAY所用的时间{i++;i++;}void Delay_50us(unsigned char t) //50us延时程序{unsigned char j;for(;t>0;t--)for(j=20;j>0;j--);}void delay1(uint z) //这个延时主要用在1602中,1602的读写时序没有//DS18B20那么严格{uint x,y;for(x=0;x<z;x++){ for(y=0;y<121;y++){;};};}uchar ds18b20_rst(){unsigned char j;ds18b20_io=1;i++; //1usds18b20_io=0;for(j=0;j<60;j++) //543us{delay();}ds18b20_io=1;for( j=0;j<7;j++) //65us{delay();}if(!ds18b20_io) //如果读到低电平,即复位成功{flag=1;}else flag=0; //如果没有读到低电平,则复位失败Delay_50us(9); //450usds18b20_io=1;return flag;}void ds18b20_writebyte(unsigned char byte){unsigned char j;for(j=0;j<8;j++){ds18b20_io=1;i++;ds18b20_io=0;delay(); //15usdelay();i++;i++;i++;ds18b20_io=byte&0x01;delay(); delay();delay();delay(); //48usdelay(); delay();delay();byte>>=1;ds18b20_io=1;delay();}ds18b20_io=1;}unsigned char ds18b20_readbyte() {unsigned char k,jj,i;jj=0;for(k=0;k<8;k++){ds18b20_io=1;i++; i++;ds18b20_io=0;delay(); //15usdelay(); i++;i++;i++;ds18b20_io=1;delay(); //15usdelay(); i++; i++;i++;if(ds18b20_io) //17us jj=(jj>>1)|0x80;elsejj>>=1;delay();delay(); delay(); //18us }return jj;}void write_com(uchar com){lcdrs=0;P1=com;delay1(5);lcden=1;delay1(5);lcden=0;}void write_data(uchar date){lcdrs=1;P1=date;delay1(5);lcden=1;delay1(5);lcden=0;}void init(){lcden=0;write_com(0x38);write_com(0x0C);write_com(0x06);write_com(0x01);}float read_temp()/*读取温度值并转换*/{if(ds18b20_rst()==1);{ds18b20_writebyte(0xcc);//*跳过读序列号*/ ds18b20_writebyte(0x44);//*启动温度转换*/ Delay_50us(30);}if(ds18b20_rst()==1);{ds18b20_writebyte(0xcc);//*跳过读序列号*/ds18b20_writebyte(0xbe);//*读取温度*/temper0 =ds18b20_readbyte();temper1 =ds18b20_readbyte();Delay_50us(20);}if(temper1&0xf8) //判断是正温度还是负温度{ //如果是高5位是0 为正温度,反则为负温度tflag=1;tvalue=(temper1<<8)|temper0;tvalue=((~tvalue)+1);temperature=tvalue*(0.0625);}else{tflag=0;tvalue=(temper1<<8)|temper0;temperature=tvalue*0.0625; //不用把tvalue进行转换,直接乘0.0625//的精度}return(temperature);}void write_xian(float date){uint bai,shi,ge,xiaozheng,xqian,xbai,xshi,xge;float k,m; //把浮点的DATA转换为整数,得到浮点娄的整数部分bai=(int)(date)/100; //把得到的整数部分拆开分别存在BAI SHI GE 中shi=((int)(date)%100)/10;ge=(int)(date)%10;if (bai!=0) //如果百不为0 则把整数部分全部显示{write_data(0x30+bai);write_data(0x30+shi);write_data(0x30+ge);}else if (shi!=0) //如果十不为0 则把十位和个位显示{write_data(0x30+shi);write_data(0x30+ge);}else write_data(0x30+ge);//如果百和十位都为0 ,则只显示个位数write_data(0x2e);k=date-(int)date; //取浮点娄的小数部分m=k*10000; //把得到的小数变为整数并显示xiaozheng=(int)m;xqian=(xiaozheng)/1000;xbai=((xiaozheng)%1000)/100;xshi=((xiaozheng)%100)/10;xge=(xiaozheng)%10;write_data(0x30+xqian);write_data(0x30+xbai);write_data(0x30+xshi);write_data(0x30+xge);}void main(){temperature=0.0;flag=0;tflag=0;tvalue=0;init();while(1){read_temp();if(tflag==0){write_xian(temperature); write_data(' '); write_data(' '); }if(tflag==1){write_data('-');write_xian(temperature); write_data(' '); write_data(' '); }write_com(0x80);}}。

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温度传感器程序
System_Init(); while(1)
{ LCD_ShowNumber(1,10,DS18B20_Read()); LCD_ShowNumber(0,10,DS18B20_Check());
} } #endif
/****************************************************************************** * File name:DS18B20.c Author:zzm Data:2011.12.13 Description:DS18B20 测温传感器的控制 Version:Thermostat V1.0 History: Others:测量范围为 -55 ℃ ~+ 125 ℃ ******************************************************************************* / #include"System_cfg.h"
void DS18B20_Ready(void) {
DS18B20_Init();
/*跳过读序号列号的操作*/ DS18B20_WriteByte(0xCC);
/*启动温度转换*/ DS18B20_WriteByte(0x44);
/*等待转换完成*/ while (!DQ);
DS18B20_Init(); DS18B20_WriteByte(0xCC);
/*对负温度的特殊处理*/ if((TH&0xf8)!=0x00)
{ flag=1; TL=~TL; TH=~TH; TL=TL+1;
/*如果低 8 位大于 255,向高 8 位进 1*/ if(TL>255)

ds18b20温度计程序

ds18b20温度计程序

ORG 0000HAJMP MAINORG 0030HMAIN: MOV R5,#0FFHMAIN1:MOV P0,#00H ;系统自检。

自高位向低位带小数点显示8扫描256次CLR P2.4LCALL DELAYSETB P2.4CLR P2.5LCALL DELAYSETB P2.5CLR P2.6LCALL DELAYSETB P2.6CLR P2.7LCALL DELAYSETB P2.7DJNZ R5,MAIN1SETB P2.4 ;关显示SETB P2.5SETB P2.6SETB P2.7SJMP MAIN2DELAY:MOV R7 ,#05H //;延时LP8: MOV R6,#19HLP7:DJNZ R6,LP7DJNZ R7,LP8RET; DS18B20初始化汇编程序;*****************************************//MAIN2:LCALL DISP //;主程序SETB P3.2 // ;18B20DQ置1拉高LCALL INIT // ;调初始化MOV A,#0CCH //;跳过ROM匹配------0CCLCALL WRITE // ;调写DS18B20的程序MOV A,#44H // ;发出温度转换命令LCALL WRITE // ;调写DS18B20的程序MOV R6,#34H //;延时136微秒转换时间,写一个字约需70微秒。

DJNZ R6,$LCALL DISPLCALL INITMOV A,#0CCHLCALL WRITEMOV A,#0BEH // ;发出读温度命令LCALL WRITELCALL READCLR CLCALL CONVTEMPLCALL DISPBCDLCALL DISPSJMP MAIN2WRITE:MOV R0,#8 // ;写子程序CLR CWR1: CLR P3.2MOV 20H,#3 // ;延时17微秒DJNZ 20H,$RRC AMOV P3.2,CMOV 21H,#10 // ;发送后延时45微秒DJNZ 21H,$SETB P3.2NOPDJNZ R0,WR1 // ;8位未发送完转SETB P3.2RETREAD: MOV R6,#2 // ;读子程序CLR PSW.5 // ;清清标志F0RE0:MOV R2,#8RE1:CLR CSETB P3.2 // ;拉高DQNOP // ;延时2微秒CLR P3.2 // ;拉低DQSETB P3.2MOV 22H,#3RE2:DJNZ 22H,RE2MOV C,P3.2MOV 23H,#10RE3:DJNZ 23H,RE3RRC ADJNZ R2,RE1 //;8位未读完继续读CPL PSW.5JNB PSW.5,RE4 // ;高8位保存至28HMOV 29H,A // ;低8位及小数保存至29HRE4:MOV 28H,ADJNZ R6,RE0 //;高8位未读继续RETINIT:SETB P3.2 // ;初始化开始DQ置1(整个时隙和理论值不是很准确)NOP //;延时L0:CLR P3.2 // ;DQ拉低MOV 24H,#100 // ;延时400微秒DJNZ 24H,$SETB P3.2 // ;DQ拉高MOV 25H,#10 // ;置40微秒延时常数L01:JNB P3.2,L2 // ;有18B20响应转L2DJNZ 25H,L01 // ;无18B20响应等待40微秒SJMP L0 // ;无18B20重新初始化L2:MOV R7,#60 // ,延时240微秒L3:DJNZ R7,L3SETB P3.2 //;DQ拉高、退出RETCONVTEMP:MOV A,28H //;温度转换ANL A,#80H //;温度正负判别JZ TEMPC1 //;温度为正转CLR C // ;温度为负调整MOV A,29HCPL AADD A,#01HMOV 29H,AMOV A,28HCPL AADDC A,#00HMOV 28H,AMOV 26H,#0BH // ;温度为负26H内送#0BHSJMP TEMPC11TEMPC1:MOV 26H,#0AH //;温度为正26H内送#0AHTEMPC11:MOV A,26HSWAP AMOV 26H,A // ;26H高4位为温度符号MOV A,29H // ;取温度小数部分ANL A,#0FH ;去整数个位MOV DPTR,#DOTTABMOVC A,@A+DPTRMOV 27H,A // ;查表得小数值,并保存至27H单元MOV A,29H // ;温度整数部分拼装后暂时存入AANL A,#0F0H // ;留下整数个位SWAP AMOV 29H,AMOV A,28HANL A,#0FHSWAP AHEX2BCD1:MOV B,#64H // ;温度整数部分除100得整数百位,并存入R7中DIV ABMOV R7,A // ;R7中为百位,B中为十位和个位MOV A,#0AH // ;温度整数部分除10得整数十位和个位XCH A,B // ;除数与被除数交换DIV ABSWAP AORL A,BTEMPC10:MOV 29H,A // ;温度十位和个位存入29H单元中,十位在高4位,个位在低4位ANL A,#0F0H // ;取温度十位SWAP AORL A,26H //;十位加温度符号存入26H单元;高4位为符号MOV 26H,AMOV A,29HANL A,#0FH // ;取温度个位SWAP AORL A,27HMOV 27H,A // ;27H单元中高4位为个位,低4位为小数MOV A,R7JZ TEMPC12 // ;百位为0退出ANL A,#0FH // ;百位不为0即温度为正和十位重新拼装后存入26H,高4位为百位SWAP A // ;MOV R7,AMOV A,26HANL A,#0FH ; // ;去除26H单元的符号ORL A,R7 //;百位和十位拼装,放入26H单元高4位为百位MOV 26H,A // ;低4位为十位TEMPC12:RETDOTTAB:DB 00H,01H,01H,02H,03HDB 03H,04H,04H,05H,06HDB 06H,07H,08H,08H,09H,09HDISPBCD:MOV A,27H // ;BCD码转换ANL A,#0FHMOV 70H,A // ;取小数,并保存在70H中SWAP AANL A,#0FHMOV 71H,A // ;取整数个位,并保存在71H中MOV A,26HANL A,#0FHMOV 72H,A //;取整数十位,并保存在72H中MOV A,26HSWAP AANL A,#0FHMOV 73H,A // ;取整数百位,并保存在73H中MOV A,72H //;取整数十位ANL A,#0F0HCJNE A,#00H,DISPBCD2SJMP DISPBCD2DISPBCD0:MOV A,26H // ;取整数百位ANL A,#0F0HCJNE A,#00H,DISPBCD2 //;百位不等于0退出MOV A,26HSW AP AANL A,#0FH //;十位保留符号MOV 73H,#0AHMOV 72H,ADISPBCD2:RETDISP:MOV R1,#70H // ;显示子程序MOV R5,#11101111B // ;送Y4位码PLAY:MOV P0,#0FFH // ;关段码MOV A,R5 // ;取Yn位码MOV P2,A // ;送位码MOV A,@R1 //;取段码MOV DPTR,#TABMOVC A,@A+DPTRMOV P0,A // ;送段码MOV A,R5JB ACC.5,LOOP1 // ;位码未指向Y2(整数个位)转CLR P0.7 ;;开小数点LOOP1:LCALL DL1MS //;调显示延时INC R1 // ;指向下一位显示段码MOV A,R5 ;取显示位码JNB ACC.7,ENDOUTRL A // ;向下一位位码MOV R5,AAJMP PLAYENDOUT:MOV P0,#0FFHMOV P3,#0FFHRETTAB: DB 0C0H,0F9H,0A4H,0B0HDB 99H,92H,82H,0F8HDB 80H,90H,0FFH,0BFHDL1MS:MOV R6,#14H // ;延时1mS DL1: MOV R7,#19HDL2: DJNZ R7,DL2DJNZ R6,DL1RETEND。

单片机DS18B20温度计(有程序)

单片机DS18B20温度计(有程序)

;单片机DS18B20温度计C语言程序; 有程序#include<reg51.h>#include<intrins.h>#include <math.H> //要用到取绝对值函数abs()//通过DS18B20测试当前环境温度, 并通过数码管显示当前温度值, 目前显示范围: -55~ +125度sbit wela = P2^7; //数码管位选sbit dula = P2^6; //数码管段选sbit ds = P2^2;int tempValue;//0-F数码管的编码(共阳极)unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//0-9数码管的编码(共阳极), 带小数点unsigned char code tableWidthDot[]={0x40, 0x79, 0x24, 0x30,0x19, 0x12, 0x02,0x78, 0x00, 0x10};//延时函数, 对于11.0592MHz时钟, 例i=10,则大概延时10ms.void delay(unsigned int i){unsigned int j;while(i--){for(j = 0; j < 125; j++);}}//初始化DS18B20//让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动 void dsInit(){//对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间大于?us unsigned int i;ds = 0;i = 100; //拉低约800us, 符合协议要求的480us以上while(i>0) i--;ds = 1; //产生一个上升沿, 进入等待应答状态i = 4;while(i>0) i--;}void dsWait(){unsigned int i;while(ds);while(~ds); //检测到应答脉冲i = 4;while(i > 0) i--;}//向DS18B20读取一位数据//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,//之后DS18B20则会输出持续一段时间的一位数据bit readBit(){unsigned int i;bit b;ds = 0;i++; //延时约8us, 符合协议要求至少保持1usds = 1;i++; i++; //延时约16us, 符合协议要求的至少延时15us以上b = ds;i = 8;while(i>0) i--; //延时约64us, 符合读时隙不低于60us要求return b;}//读取一字节数据, 通过调用readBit()来实现unsigned char readByte(){unsigned int i;unsigned char j, dat;dat = 0;for(i=0; i<8; i++){j = readBit();//最先读出的是最低位数据dat = (j << 7) | (dat >> 1);}return dat;}//向DS18B20写入一字节数据void writeByte(unsigned char dat){unsigned int i;unsigned char j;bit b;for(j = 0; j < 8; j++){b = dat & 0x01;dat >>= 1;//写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1if(b){ds = 0;i++; i++; //拉低约16us, 符号要求15~60us内ds = 1;i = 8; while(i>0) i--; //延时约64us, 符合写时隙不低于60us要求}else //写"0", 将DQ拉低60us~120usds = 0;i = 8; while(i>0) i--; //拉低约64us, 符号要求ds = 1;i++; i++; //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us 了}}//向DS18B20发送温度转换命令void sendChangeCmd(){dsInit(); //初始化DS18B20, 无论什么命令, 首先都要发起初始化dsWait(); //等待DS18B20应答delay(1); //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号writeByte(0xcc); //写入跳过序列号命令字Skip RomwriteByte(0x44); //写入温度转换命令字Convert T}//向DS18B20发送读取数据命令void sendReadCmd(){dsInit();dsWait();delay(1);writeByte(0xcc); //写入跳过序列号命令字Skip RomwriteByte(0xbe); //写入读取数据令字Read Scratchpad}//获取当前温度值int getTmpValue(){unsigned int tmpvalue;int value; //存放温度数值float t;unsigned char low, high;sendReadCmd();//连续读取两个字节数据low = readByte();high = readByte();//将高低两个字节合成一个整形变量//计算机中对于负数是利用补码来表示的//若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的valuetmpvalue = high;tmpvalue <<= 8;tmpvalue |= low;value = tmpvalue;//使用DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度t = value * 0.0625;//将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入//如t=11.0625, 进行计数后, 得到value = 1106, 即11.06 度//如t=-11.0625, 进行计数后, 得到value = -1106, 即-11.06 度value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5return value;}unsigned char const timeCount = 3; //动态扫描的时间间隔//显示当前温度值, 精确到小数点后一位//若先位选再段选, 由于IO口默认输出高电平, 所以当先位选会使数码管出现乱码void display(int v){unsigned char count;unsigned char datas[] = {0, 0, 0, 0, 0};unsigned int tmp = abs(v);datas[0] = tmp / 10000;datas[1] = tmp % 10000 / 1000;datas[2] = tmp % 1000 / 100;datas[3] = tmp % 100 / 10;datas[4] = tmp % 10;if(v < 0){//关位选, 去除对上一位的影响P0 = 0xff;wela = 0;//段选P0 = 0x40; //显示"-"号dula = 1; //打开锁存, 给它一个下降沿量dula = 0;//位选P0 = 0xfe;wela = 1; //打开锁存, 给它一个下降沿量wela = 0;delay(timeCount);}for(count = 0; count != 5; count++){//关位选, 去除对上一位的影响P0 = 0xff;wela = 1; //打开锁存, 给它一个下降沿量wela = 0;//段选if(count != 2){P0 = table[datas[count]]; //显示数字}else{P0 = tableWidthDot[datas[count]]; //显示带小数点数字}dula = 0;//位选P0 = _crol_(0xfd, count); //选择第(count + 1) 个数码管wela = 1; //打开锁存, 给它一个下降沿量wela = 0;delay(timeCount);}}void main(){unsigned char i;while(1){//启动温度转换sendChangeCmd();//显示5次for(i = 0; i < 40; i++){display(tempValue);}tempValue = getTmpValue();}以下是我编的程序,可用#include <reg52.h>#include <intrins.h>//-----------------------------------------------------------sbit DQ=P1^5;//-----------------------------------------------------------unsigned char number[10]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F};//数字0~9unsigned char wei[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //数码管位循环unsigned char Flag;unsigned char Templ,Temph;unsigned int temp;//-----------------------------------------------------------//函数声明//-----------------------------------------------------------void delay(unsigned char i); //延时程序//----------------------------------void Int18b20(void); //18b20初始化void Write18b20(unsigned char dat); //向18b20写一字节unsigned char Read18b20(void); //从18b20读一字节void Start18b20(void); //开始转换温度void Get18b20(void); //读出温度void chinT(void); //数据转换//----------------------------------void display(void); //显示程序//-----------------------------------------------------------//函数功能:延时//-----------------------------------------------------------/*************精确延时函数*****************/void delay(unsigned char i){while(--i);}/*此延时函数针对的是12Mhz的晶振delay(0); //延时518us 误差:518-2*256=6delay(1); //延时7us (原帖写"5us"是错的)delay(10); //延时25us 误差:25-20=5delay(20); //延时45us 误差:45-40=5delay(100); //延时205us 误差:205-200=5delay(200); //延时405us 误差:405-400=5*///-----------------------------------------------------------//DS18b20的相关程序//-----------------------------------------------------------//初始化//-----------------------------------------------------------void Int18b20(void){DQ=1;_nop_();_nop_();DQ=0; //拉低delay(100); //延时205usdelay(200); //延时405us //等待400~960微秒,最短为480us DQ=1;delay(1); //延时7usdelay(20); //延时45us //等待15~60微秒(等待回复)if(DQ==1) //判断初始化的情况是否成功{Flag=0; //复位失败}else{Flag=1;while(!DQ); //等待回复完成}delay(200); //延时405us //等待完成初始化}//-----------------------------------------------------------//写一字节//-----------------------------------------------------------void Write18b20(unsigned char dat){unsigned char i;for(i=0;i<8;i++){DQ=1;_nop_();DQ=0;delay(1); //延时7us //拉低后延时小于15usif(dat&0x01){DQ=1;}else{DQ=0;}dat=dat>>1;delay(20); //延时45usdelay(10); //延时25us //延时大于60usDQ=1;delay(1); //延时7us //延时大于1us}}//-----------------------------------------------------------//读一字节//-----------------------------------------------------------unsigned char Read18b20(void){unsigned char i,dat=0;for(i=0;i<8;i++){DQ=1;_nop_();DQ=0;delay(1); //延时7usdat=dat>>1;DQ=1;delay(1); //延时7us //确保在15us后60us前读数据if(DQ){dat|=0x80;}delay(20); //延时45us //确保读时续大于60us}return dat;}//-----------------------------------------------------------//开始转换温度//-----------------------------------------------------------void Start18b20(void){Int18b20();Write18b20(0xcc); //跳过ROM指令Write18b20(0x44); //温度转换指令}//-----------------------------------------------------------//读出温度//-----------------------------------------------------------void Get18b20(void){Int18b20();Write18b20(0xcc); //跳过ROM指令Write18b20(0xbe); //读暂存器指令Templ=Read18b20();Temph=Read18b20();}//-----------------------------------------------------------//数据转换//-----------------------------------------------------------void chinT(void){float Tt;temp=Temph; //先把高八位有效数据赋于temptemp=(temp<<8); //将数据从temp低八位移到高八位temp=temp|Templ; //将两字节合成一个整型变量Tt=temp*0.0625; //得到真实十进制温度值(因为DS18B20可以精确到0.0625度) temp=Tt*10+0.5; //放大十倍(将小数点后一位变成个位,个位变成十位,十位变成百位,并四舍五入)}//-----------------------------------------------------------//显示程序//-----------------------------------------------------------void display(void){unsigned int i;unsigned char A1,A2,A3;A1=temp/100; //百位(温度的十位)A2=temp%100/10; //十位(温度的个位)A3=temp%10; //个位(温度的小数点后一位)for(i=0;i<20;i++){P0=0x00;P2=0x00;P0=number[A1];P2=wei[0];delay(220);P0=0x00;P2=0x00;P0=number[A2];P2=wei[1];delay(220);P0=0x00;P2=0x00;P0=number[A3];P2=wei[2];delay(220);P0=0x00;P2=0x00;P0=0x80;P2=wei[1];delay(220);}}//-----------------------------------------------------------//----------------------------------------------------------- void main(void){while(1){Int18b20();if(Flag){Start18b20(); //开始转换温度Get18b20(); //得到温度chinT(); //数据转换display(); //显示}else P3=0x01;}}。

ds18b20程序设计傻瓜式讲解

ds18b20程序设计傻瓜式讲解

ds18b20程序设计傻瓜式讲解
DS18B20 是一款数字温度传感器,可以直接读出被测温度,并采用 9 位数字量串行输出。

下面是一个简单的 DS18B20 程序设计讲解:
1. 初始化
在 DS18B20 通信过程中,首先需要初始化数据线,即将其置为高电平。

在初始化时,需要持续至少 480 微秒的高电平。

2. 跳过 ROM
在 DS18B20 中,每个传感器都有一个唯一的 ROM 序列号,可以通过跳过ROM 操作来避免对 ROM 进行操作。

具体操作是先发出一个低电平,然后持续至少 60 微秒的高电平。

3. 发送命令
在跳过 ROM 后,需要向传感器发送命令。

常用的命令有温度转换命令和读取温度命令。

温度转换命令是 0x44,读取温度命令是 0xBE。

4. 读取数据
在发送命令后,需要等待传感器响应。

传感器响应的标志是数据线上的低电平。

在低电平持续约 60-240 微秒后,数据线将变为高电平,此时可以开始读取数据。

每次读取一位数据后,需要将数据线置为低电平,等待传感器响应。

5. 数据解析
DS18B20 的数据由 9 位数字量组成,其中最高位是符号位。

如果最高位为0,则表示温度为正数;如果最高位为 1,则表示温度为负数。

其余 8 位为温度值,可以通过一定的计算公式将其转换为实际温度值。

以上就是 DS18B20 的程序设计流程。

需要注意的是,在实际应用中,还需要考虑数据传输的校验、错误处理等问题。

基于51单片机和DS18B20的数字温度计设计说明

基于51单片机和DS18B20的数字温度计设计说明
1.硬件设计:
-51单片机:选择合适的型号,如STC89C52或AT89C52等。

-DS18B20温度传感器:该传感器是一种数字温度传感器,具有单总线接口和高精度测量能力。

-接口电路:将51单片机和DS18B20传感器连接起来,要注意电平转换和信号线的阻抗匹配。

2.软件设计:
-初始化:在主函数中,首先对单片机进行初始化设置,包括时钟设置、串口配置等。

-DS18B20通信协议:使用单总线协议与DS18B20传感器进行通信,包括发送复位信号、读写数据等操作。

-温度测量:通过向DS18B20发送读取温度的命令,从传感器中读取温度值并保存。

-数据传输:将温度值转换为可显示的格式,如摄氏度或华氏度,并通过串口输出或LED显示。

3.程序流程:
-初始化单片机,设置时钟和串口参数。

-进入主循环,循环执行以下操作:
-发送复位信号,启动温度转换。

-等待转换完成,发送读取温度命令。

-读取温度值,并进行数据处理转换。

-输出温度值。

4.其他功能:
-可以添加LCD显示模块,将温度值显示在液晶屏上。

-可以添加按键输入模块,通过按键切换温度单位或进行其他操作。

需要注意的是,该设计只是一个简单的示例,实际应用中可能需要根据具体需求进行扩展和修改。

同时,在程序设计过程中,也要注意低功耗和数据稳定性等方面的考虑。

DS18b20温度测量程序。单片机C51控制

//DS18B20的读写程序,数据脚P3.3 ////温度传感器18B20汇编程序,采用器件默认的12位转化 ////最大转化时间750微秒,显示温度-55到+125度,显示精度 ////为0.1度,显示采用4位LED共阳显示测温值 ////P0口为段码输入,P24~P27为位选 ///***************************************************/#include "reg51.h"#include "intrins.h" //_nop_();延时函数用#define Disdata P1 //段码输出口#define discan P0 //扫描口#define uchar unsigned char#define uint unsigned intsbit DQ=P3^2; //温度输入口uint h;//**************温度小数部分用查表法***********//uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09 };//uchar dd[10]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};//共阳LED段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"uchar scan_con[4]={0x00,0x01,0x02,0x03}; //列扫描控制字uchar temp_data[2]={0x00,0x00}; //读出温度暂放uchar display[4]={0x00,0x00,0x00,0x00,}; //显示单元数据,共4个数据和一个运算暂用///////***********11微秒延时函数**********///void delay(uint t){for(;t>0;t--);}///***********显示扫描函数**********/scan(){uchar k;for(k=0;k<3;k++){P0=0xff;dd[k]=dd[display[k]];dd[k]=dd[k]*16;dd[k]=dd[k]|scan_con[k];P0=dd[k];delay(90);P0=0xff;}}/////***********18B20复位函数**********/ ow_reset(void){char presence=1;while(presence){while(presence){DQ=1;_nop_();_nop_();DQ=0; //delay(50); // 550usDQ=1; //delay(6); // 66uspresence=DQ; // presence=0继续下一步 }delay(45); //延时500uspresence = ~DQ;}DQ=1;}/////**********18B20写命令函数*********/ //向 1-WIRE 总线上写一个字节void write_byte(uchar val){uchar i;for (i=8; i>0; i--) //DQ=1;_nop_();_nop_();DQ = 0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us DQ = val&0x01; //最低位移出delay(6); //66usval=val/2; //右移一位}DQ = 1;delay(1);}///*********18B20读1个字节函数********///从总线上读取一个字节uchar read_byte(void){uchar i;uchar value = 0;for (i=8;i>0;i--){DQ=1;_nop_();_nop_();value>>=1;DQ = 0; //_nop_();_nop_();_nop_();_nop_(); //4usDQ = 1;_nop_();_nop_();_nop_();_nop_(); //4usif(DQ)value|=0x80;delay(6); //66us}DQ=1;return(value);}///***********读出温度函数**********///read_temp(){ow_reset(); //总线复位write_byte(0xCC); // 发Skip ROM命令write_byte(0xBE); // 发读命令temp_data[0]=read_byte(); //温度低8位temp_data[1]=read_byte(); //温度高8位ow_reset();write_byte(0xCC); // Skip ROMwrite_byte(0x44); // 发转换命令}/***********温度数据处理函数**********/void work_temp(){display[3]=temp_data[0]&0x0f;display[0]=ditab[display[3]]; //小数部分display[3]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x07)<<4); display[2]=display[3]/10%10;display[1]=display[3]%10;}/////**************主函数****************/main(){Disdata=0xff; //初始化端口discan=0xff;ow_reset(); // 开机先转换一次write_byte(0xCC); // Skip ROMwrite_byte(0x44); // 发转换命令for(h=0;h<500;h++){scan();} //开机显示"0000"2秒while(1){read_temp(); //读出18B20温度数据work_temp(); //处理温度数据scan(); //显示温度值2秒}}////*********************结束**************************//。

18b20温度传感器51程序

#include <reg52.h>#include "intrins.h"#define uint unsigned int#define uchar unsigned char#define ulong unsigned longsbit WD_DQ=P3^7; //温度传感器sbit YJ_CS= P1^2; //液晶sbit YJ_SID= P1^1;sbit YJ_SCLK=P1^0;uchar wendu[]={0,0,0,0};/***************************************************************** * 温度测量模块子程序*******************************************************************/ void delay_18b20(unsigned int t){while(t--);}void YJ_delay(uint x){uint y,z;for(y=x;y>0;y--)for(z=110;z>0;z--);}uchar init_18b20(){uchar i=0;WD_DQ=1;WD_DQ=0;delay_18b20(79); //延时480us-960usWD_DQ=1;delay_18b20(4); //延时15us-60usi=WD_DQ;while(!WD_DQ);return(i);}uchar read_18b20_byte( void ){uchar times,ram;ram=0;for(times=8;times>0;times--){ram>>=1; //将采样到的数据依次向低位移WD_DQ=0; //将总线拉低,然后释放。

整个过程不大于15us_nop_();_nop_(); //delay 2usWD_DQ=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();if(WD_DQ) //采样总线上的数据{ram|=0x80;}delay_18b20(4); //延时,使整个读操作时序大于60us.}return ram;}void write_18b20_byte(uchar command){uchar i;for(i=8;i>0;i--){if((command&0x01)){//写1操作WD_DQ=0;_nop_();_nop_();WD_DQ=1; //将DQ拉低,延时2us后释放,以上操作必须在15us内完成delay_18b20(4); //延时,使整个操作大于60us。

单片机例程DS18b20温度传感器程序

LCDE=0;
return(lcd_start&0x80);
}
wr_com(uchar comm) //写控制字命令
{
while(busy_check());
RS=0;
RW=0;
LCDE=1;
data=comm;
LCDE=0;
}
wr_com(0x80);
for(j=0;j<16;j++)
{
wr_dat(tab2[0][j]);
}
wr_com(0xc0);
for(k=0;k<16;k++)
{
wr_dat(tab2[1][k]);
}
}
void main()
{ uchar temp;
delay3 (1); // 延时
tmpwrite (0xcc); // 跳过序列号命令
tmpwrite (0x44); // 发转换命令 44H,
}
uchar tmp (void) // 读取温度
{
unsigned int a,b,t;
i = 8; while (i>0) i--;
DQ = 1;
i++; i++;
}
}
}
void tmpchange(void) // ds1820 开始转换
{
tmreset (); // 复位
//tmpre (); // 等待存在脉冲
delay1(10);
init();
while(1)
{
tmpchange(); // 开始温度转
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档