DS18B20的四位数码管显示数字温度计程序
18b20测温数码管显示实验--精确到小数点后4位
18b20测温数码管显示实验--精确到小数点后4位//滑国虎于09.9.20完成////DS18B20的读写程序,数据脚P1.5 ////温度传感器18B20程序,采用器件默认的12位转化 ////最大转化时间750微秒,显示温度-55到+125度,显示精度 // //为0.1度,显示采用4位LED共阳显示测温值 ////P0口为段码输入,P27~P21为位选 ///***************************************************/#include "reg51.h"#include "intrins.h" //_nop_();延时函数用 #define Disdata P0 //段码输出口 #define discan P2 //扫描口 #define uchar unsigned char #define uint unsigned intsbit DQ=P1^5; //温度输入口 sbit DIN=P0^7; //LED小数点控制 uint h;uint temp;//uchar codedis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0x bf};//共阳LED段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮""-"uchar code scan_con[7]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd}; //列扫描控制字uchar data temp_data[2]={0x00,0x00}; //读出温度暂放 uchar data display[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //显示单元数据,共4个数据和一个运算暂用/*****************11us延时函数*************************///void delay(uint t) //11us{for (;t>0;t--);}///****************DS18B20复位函数************************/ow_reset(void){char presence=1;while(presence){while(presence){DQ=1;_nop_();_nop_();//从高拉倒低DQ=0;delay(50); //550 usDQ=1;delay(6); //66 uspresence=DQ; //presence=0 复位成功,继续下一步}delay(45); //延时500 uspresence=~DQ;}DQ=1; //拉高电平 }/****************DS18B20写命令函数************************/ //向1-WIRE 总线上写1个字节void write_byte(uchar val){uchar i;for(i=8;i>0;i--){DQ=1;_nop_();_nop_(); //从高拉倒低DQ=0;_nop_();_nop_();_nop_();_nop_(); //5 usDQ=val&0x01; //最低位移出delay(6); //66 usval=val/2; //右移1位}DQ=1;delay(1);}/****************DS18B20读1字节函数************************/ //从总线上取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_(); //4 usDQ=1;_nop_();_nop_();_nop_();_nop_(); //4 usif(DQ)value|=0x80;delay(6); //66 us}DQ=1;return(value);}/****************显示扫描函数***************************/ scan(){char k;for(k=0;k<7;k++) //4位LED扫描控制{Disdata=dis_7[display[k]]; //数据显示 P0if (k==2){DIN=0;} //小数点显示 P0.7discan=scan_con[k]; //位选 P2delay(150);discan=0xff;}}/****************读出温度函数************************/ //read_temp(){ow_reset(); //总线复位delay(200);write_byte(0xcc); //发命令write_byte(0x44); //发转换命令ow_reset();delay(1);write_byte(0xcc); //发命令write_byte(0xbe);temp_data[0]=read_byte(); //读温度值的低字节temp_data[1]=read_byte(); //读温度值的高字节temp=temp_data[1];temp=temp&0x0f; //去掉符号位temp=temp<<8; //temp为16位temp=temp|temp_data[0]; // 两字节合成一个整型变量。
DS18B20数码管显示程序
void LED7_Init()
{
DDRA|=(1<<3)|(1<<4);
DDRB=0xff;
DDRA=0x18;
DDRB=0xff;
}
void Number_Show(unsigned int num)
{
PORTB=Number[num/1000%10];
PORTA|=(1<<3); //PA3=1;
PORTA|=BIT(DQ); //释放总线
_delay_us(1); //稍微延迟
Data>>=1;
}
}
//DS1302读字节函数
unsigned char DS1302_Read()
{
unsigned char i,Temp=0;
for(i=0;i<8;i++)
PORTA&=~BIT(DQ); //输出低电平
_delay_us(500); //延迟500微妙
PORTA|=BIT(DQ); //示范总线
_delay_us(60); //延迟60微妙
DDRA&=~BIT(DQ); //DQ位输出状态
while(PINA&BIT(DQ)); //等待从机DS18B20应答(低电平有效)
PORTA&=~(1<<3); //PA3=0;
PORTB=0xf7;
PORTA|=(1<<4); //PA3=1;
PORTA&=~(1<<4)//DS1302复位函数
void DS1302_Reset()
ds18b20多路温度采集程序
本程序为ds18b20的多路温度采集程序,是我自己参考其他程序后改写而成,可显示4路正负温度值,并有上下限温度报警(声音、灯光报警)。
亲测,更改端口即可使用。
(主要器件:51单片机,ds18b20,lcd显示器)附有proteus仿真图,及序列号采集程序/****上限62度下限-20度****/#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit ds=P1^1;sbit rs=P1^4;sbit e=P1^6;sbit sp=P1^0;sbit d1=P1^2;sbit d2=P1^3;ucharlcdrom[4][8]={{0x28,0x30,0xc5,0xb8,0x00,0x00,0x00,0x8e} ,{0x28,0x31,0xc5,0xb8,0x00,0x00,0x00,0xb9},{0x28,0x32,0xc5,0xb8,0x00,0x00,0x00,0xe0},{0x28,0x33,0xc5,0xb8,0x00,0x00,0x00,0xd7}};unsigned char code table0[]={"TEMPERARTURE:U "}; unsigned char code table1[]={"0123456789ABCDEF"};int f[4];int tvalue;float ftvalue;uint warnl=320;uint warnh=992;/****lcd程序****/void delayms(uint ms)//延时{uint i,j;for(i=ms;i>0;i--)for(j=110;j>0;j--);}void wrcom(uchar com)//写指令{delayms(1);rs=0;P3=com;delayms(1);e=1;delayms(1);e=0;}void wrdat(uchar dat)//写数据{rs=1;e=0;P3=dat;delayms(5);e=1;delayms(5);e=0;}void lcdinit()//初始化lcd {delayms(15);wrcom(0x38);delayms(5);wrcom(0x0c);delayms(5);wrcom(0x06);delayms(5);wrcom(0x01);delayms(5); }void display(uchar *p)//显示{while(*p!='\0'){wrdat(*p);p++;delayms(1);}}displayinit()//初始化显示{lcdinit();wrcom(0x80);display(table0);}/****ds18b20程序****/ void dsrst()//ds18b20复位{uint i;ds=0;i=103;while(i>0)i--;ds=1;i=4;while(i>0)i--;}bit dsrd0()//读一位数据{uint i;bit dat;ds=0;i++;ds=1;i++;i++;dat=ds;i=8;while(i>0)i--;return(dat);}uchar dsrd()//读1个字节数据{uchar i,j,dat;dat=0;for(i=8;i>0;i--){j=dsrd0();dat=(j<<7)|(dat>>1);}return(dat);}void dswr(uchar dat)//写数据{uint i;uchar j;bit testb;for(j=8;j>0;j--){testb=dat&0x01;dat=dat>>1;if(testb){ds=0;i++;i++;ds=1;i=8;while(i>0)i--;}else{ds=0;i=8;while(i>0)i--;ds=1;i++;i++;}}}void tmstart()//初始化ds18b20{sp=1;d1=1;d2=1;dsrst();delayms(1);dswr(0xcc);dswr(0x44);}void read_dealtemp()//读取并处理温度{uchar i,j,t;uchar a,b;for(j=0;j<4;j++){dsrst();delayms(1);dswr(0x55);for(i=0;i<8;i++){dswr(lcdrom[j][i]);//发送64位序列号}dswr(0xbe);a=dsrd();b=dsrd();tvalue=b;tvalue<<=8;tvalue=tvalue|a;if(tvalue<0){d1=1;tvalue=~tvalue+1;wrcom(0xc0);wrdat(0x2d);if(tvalue>warnl){d2=0;sp=0;}else{d2=1;sp=1;}}else{d2=1;wrcom(0xc0);wrdat(' ');if(tvalue>warnh){d1=0;sp=0;}else{d1=1;sp=1;}}if(j==0){wrcom(0x8e); wrdat('2');}if(j==1){wrcom(0x8e);wrdat('3');}if(j==2){wrcom(0x8e);wrdat('4');}if(j==3){wrcom(0x8e);wrdat('5');}ftvalue=tvalue*0.0625;tvalue=ftvalue*10+0.5;ftvalue=ftvalue+0.05;f[j]=tvalue;//温度扩大十倍,精确到一位小数tvalue=f[j];t=tvalue/1000;wrcom(0x80+0x41);wrdat(table1[t]);//显示百位t=tvalue%1000/100;wrdat(table1[t]);//显示十位t=tvalue%100/10;wrdat(table1[t]);//显示个位wrdat(0x2e); //显示小数点儿t=tvalue%10/1;wrdat(table1[t]);//显示小数位delayms(5000);}}/****主函数****/void main(){d1=1;d2=1;sp=1;displayinit();//初始化显示while(1){tmstart();//初始化read_dealtemp();//读取温度}}/****序列号读取程序****/#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit DQ = P1^1; //温度传感器信号线sbit rs = P1^4; //LCD数据/命令选择端(H/L)位声明sbit lcden = P1^6; //LCD使能信号端位声明void delay(uint z); //延时函数void DS18B20_Reset(void); //DQ18B20复位,初始化函数bit DS18B20_Readbit(void); //读1位数据函数uchar DS18B20_ReadByte(void); //读1个字节数据函数void DS18B20_WriteByte(uchar dat); //向DQ18B20写一个字节数据函数void LCD_WriteCom(uchar com); //1602液晶命令写入函数void LCD_WriteData(uchar dat); //1602液晶数据写入函数void LCD_Init();//LCD初始化函数void Display18B20Rom(char Rom); //显示18B20序列号函数/**********************************************//* 主函数*//**********************************************/void main(){ uchar a,b,c,d,e,f,g,h;LCD_Init();DS18B20_Reset();delay(1);DS18B20_WriteByte(0x33);delay(1);a = DS18B20_ReadByte();b = DS18B20_ReadByte();c = DS18B20_ReadByte();d = DS18B20_ReadByte();e = DS18B20_ReadByte();f = DS18B20_ReadByte();g = DS18B20_ReadByte();h = DS18B20_ReadByte();LCD_WriteCom(0x80+0x40);Display18B20Rom(h);Display18B20Rom(g);Display18B20Rom(f);Display18B20Rom(e);Display18B20Rom(d);Display18B20Rom(c);Display18B20Rom(b);Display18B20Rom(a);while(1);}/***************************************************//* 延时函数:void delay() *//* 功能:延时函数*//***************************************************/void delay(uint z)//延时函数{uint x,y;for( x = z; x > 0; x-- )for( y = 110; y > 0; y-- );}/***************************************************//* DS18B20函数:void DS18B20_Reset() *//* 功能:复位18B20 *//***************************************************/void DS18B20_Reset(void)//DQ18B20复位,初始化函数{uint i;DQ = 0;i = 103;while( i > 0 ) i--;DQ = 1;i = 4;while( i > 0 ) i--;}/***************************************************//* DS18B20函数:void DS18B20_Readbit() *//* 功能:读1个字节数据函数*//***************************************************/bit DS18B20_Readbit(void) //读1位数据函数{uint i;bit dat;DQ = 0;i++; //i++起延时作用DQ = 1;i++;i++;dat = DQ;i = 8;while( i > 0 )i--;return( dat );}/***************************************************//* DS18B20函数:void DS18B20_ReadByte() *//* 功能:读1个字节数据函数*//***************************************************/uchar DS18B20_ReadByte(void) //读1个字节数据函数{uchar i,j,dat;dat = 0;for( i = 1; i <= 8; i++ ){j = DS18B20_Readbit();dat = ( j << 7 ) | ( dat >> 1 );}return(dat);}/***************************************************//* DS18B20函数:void DS18B20_WriteByte() *//* 功能:向DQ18B20写一个字节数据函数*//***************************************************/void DS18B20_WriteByte(uchar dat) //向DQ18B20写一个字节数据函数{uint i;uchar j;bit testb;for( j=1; j<=8; j++){testb = dat&0x01;dat= dat>>1;if(testb) //写1{DQ = 0;i++;i++;DQ = 1;i = 8;while(i>0)i--; }else{DQ = 0; //写0 i = 8;while(i>0)i--; DQ = 1;i++;i++;}}}/* LCD函数:void LCD_WriteCom() *//* 功能:向LCD写入命令*//***********************************************/void LCD_WriteCom(uchar com){rs = 0;P3= com;delay(5);lcden = 0;delay(5);lcden = 1;delay(5);lcden = 0;}/***********************************************//* LCD函数:void LCD_WriteData(uchar dat) *//* 功能:向LCD写入数据*/void LCD_WriteData(uchar dat){rs = 1; //选择LCD为写入数据状态lcden = 0;P3= dat; //将待写入数据放到总线上delay(5);lcden = 1; //给LCD使能端一个脉冲delay(5); //信号将之前放到总线上lcden = 0; //的数据写入LCDdelay(5);}/***********************************************//* LCD函数:void LCD_Init() *//* 功能:初始化LCD,设定LCD的初始状态*/void LCD_Init(){LCD_WriteCom(0x38); //LCD显示模式设定delay(15);LCD_WriteCom(0x08); //关闭LCD显示delay(3);LCD_WriteCom(0x01); //LCD显示清屏delay(3);LCD_WriteCom(0x06); //设定光标地址指针为自动加1delay(3);LCD_WriteCom(0x0c); //打开LCD显示,但不显示光标}/**********************************************//* *//* 显示18B20序列号*//* *//**********************************************/void Display18B20Rom(char Rom){uchar h,l;l = Rom & 0x0f; //取低4位h = Rom & 0xf0; //取高4位h >>= 4;if( ( h >= 0x00 )&&( h <= 0x09 ) )LCD_WriteData(h+0x30);//取ASCII码elseLCD_WriteData(h+0x37);//取ASCII码if( ( l >= 0x00 )&&( l <= 0x09 ) )LCD_WriteData(l+0x30);//取ASCII码elseLCD_WriteData(l+0x37);//取ASCII码}。
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测温程序(数码显示)*;************************************************************************** ;*接线方法: *;* 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测温程序,四位数码管显示两位小数
#include<reg51.H>#include<absacc.H>#include <intrins.h>#include<stdio.h>#define uchar unsigned char#define uint unsigned intuchar code TAB[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar code TAB1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; sbit DQ=P3^3;void delay(uint i){while(i--);}void DelayMS(uint ms){uchar i;while(ms--) for(i=0;i<120;i++);}void display(int k)//数码管显示{P2=0x08;P0=TAB[k%10];DelayMS(5);P2=0x04;P0=TAB[k/10%10];DelayMS(5);P2=0x02;P0=TAB1[k/100%10];DelayMS(5);P2=0x01;P0=TAB[k/1000];DelayMS(5);}init_DS(void){uchar x=0;DQ=1;delay(8);DQ=0;delay(85);DQ=1;delay(14);x=DQ;delay(20);}Read(void){uchar i=0;uchar dat=0;for(i=8;i>0;i--){//DQ=1;//delay(1);DQ=0;dat>>=1;DQ=1;if(DQ)dat|=0x80;//读出数据放入高位,最后右移到低位delay(4);}return(dat);}write(uchar dat){uchar i=0;for(i=8;i>0;i--){DQ=0;DQ=dat&0x01;//从地位开始写入delay(5);DQ=1;dat>>=1;}delay(4);}Readtem(void){ uchar a=0;uchar b=0;uchar t=0,t1;init_DS();write(0xcc);//跳过读序列号操作write(0x44);//启动温度转换delay(125);init_DS();write(0xcc);write(0xbe);// 读温度寄存器a=Read();//读取温度低位LSBb=Read();//读取温度低位HSBt1=(a&0x0f)*0.0625;//取小数部分t=((b<<4)|(a>>4));//取整数部分if(t>128){t=~t+1;}t=t+t1;return(t);}void main(){float tp;while(1){tp=Readtem();tp=tp*100;//把二位数乘以100变成四位数display(tp);}}。
多个DS18B20温度测量程序
#include<reg51.h>#include<intrins.h> //nop函数#include<stdlib.h>#include<math.h>#define uchar unsigned char#define uint unsigned intsbit DS18B20_DQ=P2^7;sbit feng=P2^0;sbit deng=P1^0;#define LCD_data P0 //ch375数据端口uchar count1,count2,count;sbit LCD_RS=P3^5;sbit LCD_RW=P3^6; //ch375的rw也是此口sbit LCD_EN=P3^4;#include<key_fo.h>uchar ds18b20_serial[4][8]={0x28,0x51,0x8c,0x9e,0x03,0x00,0x00,0xfd, //第1个18B20的ID0x28,0x71,0x91,0x9e,0x03,0x00,0x00,0xdb, //第2个18B20的ID0x28,0x43,0xa6,0x9a,0x03,0x00,0x00,0x83, //第3个18B20的ID0x28,0xe3,0x8a,0x9e,0x03,0x00,0x00,0x08 //第4个18B20的ID};#include<12864.h>uchar temp_num1;uchar temp_num2;uint temper=0,yushe1=325,yushe2=325,yushe3=325,yushe4=325,piancha;/****************************************************函数:void Ds18b20_Delay(uint timer)功能:STC单片机严格的us级延时函数*****************************************************/void Ds18b20_Delay(uint timer) //us{while(timer--){_nop_();_nop_();_nop_();}}/***************************************************函数:void rest()功能:DS18B20芯片复位函数说明:复位时,MCU将数据线置为低电平,并且保持480uS-960uS,然后置为高电平,延时一段时间后,然后由MCU接受DS18B20的响应信号。
DS18B20温度显示程序
DS18B20传感器温度数码管显示#include<reg51.h>#include<1820twj.h> //传感器DS18B20#include<intrins.h> //字符操作库sbit g1=P2^7;sbit g2=P2^6;sbit g3=P2^5;sbit g4=P2^4;sbit lv=P2^2;sbit jin=P3^3; //进sbit jia=P3^4; //加sbit jian=P3^5; //减uint shiwen;uint zuigao=30; //最高30度uint zuidi=20; //最低20度//*键盘调节/uchar flag=0; //记录第一个按键次数flag=0正常1最高2最低uchar flag2=0; //记录第四个按键次数flag2=0正常1调节小时2调节分钟uchar tableshu[]={0x28,0xeb,0x32,0xa2,0xe1,0xa4,0x24,0xea,0x20,0xe0,0xff ,0xf7 }; uchar tableshudi[]={0x08,0xcb,0x12,0x82,0xc1,0x84,0x04,0xca,0x00,0xc0,0xff };void main(){uchar TL; //储存暂存器的温度低位uchar TH; //储存暂存器的温度高位uint TN; //储存温度的整数部分uchar TD; //储存温度的小数部分uchar ba,sh,ge,di,ba1,sh1,ge1,di1;bit flag1; //判断显示正负0负1正delay1(5); //延时5ms给硬件一点反应时间while(1) //不断检测并显示温度{ init();//读温度准备if(flag1==1) dis(ba,sh,ge,di);else dis(11,sh,ge,di);TL=ReadOneChar(); //先读的是温度值低位TH=ReadOneChar(); //接着读的是温度值高位if((TH&0xf8)!=0x00)//判断高五位得到温度是负{ flag1=0; TL=~TL; //取反TH=~TH; //取反TL=TL+1; //低位加1TN=(TH*256+TL)*0.625; //实际温度值10倍=(TH*256+TL)*0.625,if(TN%160==0) TN=TN+160;sh=TN/100%10; ge=TN/10%10; di=TN%10;dis(ba,sh,ge,di); //显示温度}else//判断高五位得到温度是正{ flag1=1;TN=(TH*256+TL)*0.625; //实际温度值10倍=(TH*256+TL)*0.625, //这样前几位是温度的整数部分,最后一位是温度的小数部分ba=TN/1000; sh=TN/100%10; ge=TN/10%10; di=TN%10;dis(ba,sh,ge,di); //显示温度的整数部分}shiwen=TN; biaozhun(); tfz();if(flag1==1)dis(ba,sh,ge,di);else dis(11,sh,ge,di);kongzhi()//温度调整驱动程序}void kongzhi(){if((shiwen<zuigao)&&(shiwen>zuidi))lv=0; //控制P2口输出电平elselv=1;}void dis(uchar ba,uchar sh,uchar ge,uchar di){ g1=0;P0=tableshu[ba];delay1(5);g1=1;P0=tableshu[10];g2=0;P0=tableshu[sh];delay1(5);g2=1;P0=tableshu[10];g3=0;P0=tableshudi[ge];delay1(5);g3=1;P0=tableshudi[10];g4=0;P0=tableshu[di];delay1(5);g4=1;P0=tableshu[10];}void disdi(uchar ba,uchar sh,uchar ge,uchar di){ g1=0;P0=tableshudi[ba];delay1(5); g1=1;P0=tableshu[10]; g2=0;P0=tableshudi[sh];delay1(5); g2=1;P0=tableshu[10]; g3=0;P0=tableshudi[ge];delay1(5); g3=1;P0=tableshudi[10]; g4=0;P0=tableshudi[di];delay1(5); g4=1;P0=tableshu[10];}void biaozhun(){ if(jin==0){ delay1(5);if(jin==0){ while(!jin);flag++; if(flag==3) flag=0;} } } /*调幅值*/void tfz(){ uchar ba,sh,ge,di; if(flag==1){ while(1){ ba=zuigao/1000; sh=zuigao/100%10; ge=zuigao/10%10; di=zuigao%10; dis(ba,sh,ge,di); if(jia==0) delay1(5);if(jia==0) { zuigao=zuigao+10;while(!jia); dis(ba,sh,ge,di); }if(jian==0){ zuigao=zuigao-10;while(!jian);dis(11,sh,ge,di); }biaozhun();if(flag!=1) break; } }if(flag==2){ while(1){ ba=zuidi/1000; sh=zuidi/100%10; ge=zuidi/10%10; di=zuidi%10;dis(ba,sh,ge,di);if(jia==0) delay1(5);if(jia==0){ zuidi=zuidi+10; while(!jia); }if(jian==0) { zuidi=zuidi-10; while(!jian); }biaozhun();if(flag!=2)break;}}}。
单片机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温度测控程序
#include<reg52.h>sbit s2=P0^0;sbit led=P1^3;unsigned char wendushangxian=0;sbit DQ=P1^6;sbit wei1=P3^0;sbit wei2=P3^1;sbit wei3=P3^2;sbit wei4=P3^3;sbit key_Max_jia=P0^0;sbit key_Max_jian=P0^1;sbit key_Min_jia=P0^2;sbit key_Min_jian=P0^3;sbit dianji_jian=P1^2;sbit dianji_jia=P1^7;sbit Led_tempreture_Max=P1^3;sbit Led_tempreture_Min=P1^4;sbit Led_normal=P1^5;unsigned char num[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf}; int tempreture_Max=40;int tempreture_Min=-10;void delay_mylself(int temp){unsigned int i,j;for(i=0;i<temp;i++)for(j=0;j<1140;j++);}void delay(unsigned int i) //如果i是unsigend char类型,则会出现错误结果{while(i--);}void DS18B20_Init(void)//初始化{unsigned char flag=0;DQ = 1; //DQ复位delay(1);DQ = 0; //单片机将DQ拉低delay(80); //精确延时大于480us小于960usDQ = 1; //拉高总线delay(6);while(DQ);while(!DQ);//flag=DQ; //稍做延时后如果flag=0则初始化成功flag=1则初始化失败//delay(30);}unsigned char Read(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 Write(unsigned char dat)//写字节{unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;delay(5);DQ = 1;dat>>=1;}}void init(){wei1=0;wei2=0;wei3=0;wei4=0;}void Display(unsigned int temp){unsigned char one,two,three,four;int wendu=0;if(temp<=0xf000){ temp>>=4; //右移4位,相当于乘0.0625,将温度化为十进制//temp*=10; //扩大10倍,显示一位小数one=temp/1000; //千位two=temp%1000/100; //百位three=temp%1000%100/10; //十位four=temp%1000%100%10; //个位wendu=temp;}else{temp=~temp;temp+=1;temp>>=4;one=10; //负数two=temp%1000/100; //百位three=temp%1000%100/10; //十位four=temp%1000%100%10; //个位wendu=-temp;}if(wendu>tempreture_Max){Led_tempreture_Max=0;Led_tempreture_Min=1;Led_normal=1;dianji_jian=1;dianji_jia=0;}else if(wendu<tempreture_Min){Led_tempreture_Max=1;Led_tempreture_Min=0;Led_normal=1;dianji_jia=1;dianji_jian=0;}else{Led_tempreture_Max=1;Led_tempreture_Min=1;Led_normal=0;dianji_jian=0;dianji_jia=0;}//第1位wei1=1;wei2=0;wei3=0;wei4=0;P2=num[one];delay_mylself(1);//第2位wei1=0;wei2=1;wei3=0;wei4=0;P2=num[two];delay_mylself(1);//第3位wei1=0;wei2=0;wei3=1;wei4=0;P2=num[three];delay_mylself(1);//第4位wei1=0;wei2=0;wei3=0;wei4=1;P2=num[four];delay_mylself(10);}void common_display(int temp){unsigned char one,two,three,four;one=temp/1000; //千位two=temp%1000/100; //百位three=temp%1000%100/10; //十位four=temp%1000%100%10; //个位if(temp<0){temp=-temp;two=temp%1000/100; //百位three=temp%1000%100/10; //十位four=temp%1000%100%10; //个位//第1位wei1=1;wei2=0;wei3=0;wei4=0;P2=num[10];delay_mylself(50);}else{//第1位wei1=1;wei2=0;wei3=0;wei4=0;P2=num[one];delay_mylself(50);}//第2位wei1=0;wei2=1;wei3=0;wei4=0;P2=num[two];delay_mylself(50);//第3位wei1=0;wei2=0;wei3=1;wei4=0;P2=num[three];delay_mylself(50);//第4位wei1=0;wei2=0;wei3=0;wei4=1;P2=num[four];delay_mylself(60);}void key(){unsigned char flag=0;if(key_Max_jia==0){flag=1;tempreture_Max+=1;if(tempreture_Max>125){tempreture_Max=125;}while(!key_Max_jia); //按键松手检测}else if(key_Max_jian==0){flag=2;tempreture_Max-=1;if(tempreture_Max<tempreture_Min){tempreture_Max=tempreture_Min;}while(!key_Max_jian); //按键松手检测}else if(key_Min_jia==0){flag=3;tempreture_Min+=1;if(tempreture_Min>tempreture_Max){tempreture_Min=tempreture_Max;}while(!key_Min_jia); //按键松手检测}else if(key_Min_jian==0){flag=4;tempreture_Min-=1;if(tempreture_Min<-55){tempreture_Min=-55;}while(!key_Min_jian); //按键松手检测}if(flag==1||flag==2){common_display(tempreture_Max);delay_mylself(200);flag=0;}else if(flag==4||flag==3){common_display(tempreture_Min);delay_mylself(200);flag=0;}}void main(){unsigned int temp;unsigned char tl=0,th=0;while(1){DS18B20_Init();Write(0xCC); // 跳过读序号列号的操作Write(0x44); // 启动温度转换delay(100);DS18B20_Init();Write(0xCC); //跳过读序号列号的操作Write(0xBE); //读取温度寄存器等delay(100);tl=Read(); //读取温度值低位th=Read(); //读取温度值高位temp=th<<8;temp|=tl;Display(temp);key();}}。
基于ds18b20的温度计设计代码
基于DS18B20的温度计设计代码一、介绍DS18B20温度计DS18B20是一种数字温度传感器,由美国达拉斯半导体公司生产。
它采用单总线通信协议,并可以通过单总线接口进行多级串联。
DS18B20具有精度高、稳定性好、响应速度快等特点,因此在各种温度测量应用中被广泛使用。
二、DS18B20温度计设计代码在使用DS18B20温度传感器时,我们通常需要编写相应的代码来读取传感器的数据并进行温度计算。
以下是基于Arduino评台的DS18B20温度计设计代码:```c#include <OneWire.h>#include <DallasTemperature.h>#define ONE_WIRE_BUS 2 // 设置DS18B20数据线连接的Arduino 引脚OneWire oneWire(ONE_WIRE_BUS);DallasTemperature sensors(&oneWire);void setup() {Serial.begin(9600);sensors.begin();}void loop() {sensors.requestTemperatures(); // 发送获取温度命令float temperatureC = sensors.getTempCByIndex(0); // 获取温度值(摄氏度)float temperatureF = sensors.toFahrenheit(temperatureC); // 转换为华氏度Serial.print("Temperature: ");Serial.print(temperatureC);Serial.print("°C / ");Serial.print(temperatureF);Serial.println("°F");delay(1000); // 延时1s}```以上代码使用了OneWire库和DallasTemperature库来实现对DS18B20的温度测量。
DS18B20数字温度计的主程序
主程序ORG 0000HLJMP STARTSTART: MOV DISBUF4,#00H ;开始,初始化MOV DISBUF5, #00HMAIN: ;主程序LCAAL KEY ;调按键预置数子程序CLR RS1CLR RS0LCALL RESET ;调复位子程序MOV A,#0CCH ;跳过ROM匹配------0CCLCALL WRITE ;调DS18B20子程序MOV A,#44H ;发出温度转换命令LCALL WRITE ;调DS18B20子程序LCALL RESET ;调复位子程序MOV A,#0CCH ;跳过ROM匹配LCALL WRITE ;调DS18B20子程序MOV A,#0BEH ;发出读取温度值命令LCALL WRITE ;调DS18B20子程序LCALL READ ;调DS18B20子程序MOV A, 3DHMOV 29H,ALCALL READMOV A, 3DHMOV 28H,AMOV R0, #34HMOV A, 28HRLC AMOV 47H,CJNB 47H, BTOD1 ;28H中的最高位是不是为1(温度<0);小于0的温度值不处置,大于0顺序执行BTOD1: MOV A, 28HRRC AMOV 40H,CRRC AMOV 41H,CRRC AMOV 42H,CRRC AMOV 43H,CMOV A, 29HMOV 27H, AMOV C,40H ;将28H中的最低位移入C,40H41H42H43H ;为28H中的位地址RRC A ;将28H中的低4位移到A的高4位MOV C, 41HRRC AMOV C, 42HRRC AMOV C, 43HRRC AMOV 29H,A ;将28H中的低4位放入29H中MOV A, 29H ;将29H中的十六进制数转换成10进制MOV B, #100DIV ABMOV @R0, A ;百位存于34HMOV @R0, #11H ;百位不显示DEC R0MOV A, #10XCH A, BDIV ABMOV @R0, A ;十位存于33HDEC R0MOV @R0, B ;个位存于32HDEC R0ANL 27H, #0FH ;小数点后一名进制转换MOV A, 27HMOV B, #06HMUL ABMOV B, #10DIV ABMOV @R0, A ;小数点后一名存于31HMOV DISBUF0,33H ;十位MOV DISBUF1,32H ;个位MOV DISBUF2,31H ;小数位MOV DISBUF3, #0H ;置0MOV DISBUF6, #0HMOV DISBUF7, #0HLCALL CMP ;调比较报警子程序LCALL DISPLAY ;调显示子程序LJMP MAIN ;转到MAINDS18B20复位子程序RESET: NOPL0: CLR ;拉低数据线MOV R2,#200 ;发出600us的复位脉冲L1: NOPDJNZ R2, L1SETB ;主机释放数据线MOV R2,#30 ;DS18B20等待60usL4: DJNZ R2, L4CLR CORL C, ;DS18B20数据变低(存在脉冲)吗?JC L3 ;DS18B20未预备好,从头初始化MOV R6, #80L5: ORL C,JC L3 ;DS18B20数据变高,初始化成功DJNZ R6,L5 ;数据线低电平可持续3us*80=240us SJMP L0 ;初始化失败,从头初始化L3: MOV R2, #250L2: DJNZ R2,L2 ;DS18B20应答500usRET读DS18B20子程序READ: MOV R6,#8 ;循环8次,读一个字节RE1: CLRMOV R4, #6NOPNOPSETBRE2: DJNZ R4,RE2 ;等待8USMOV C, ;读DS18B20的数据RRC A ;读取的数据移入AMOV R5, #30DJNZ R6,RE1 ;读完一个字节的数据MOV 3DH,A ;数据存入3DH中SETB ;把数据线拉高RET写DS18B20子程序;写DS18B20的子程序, 从DS18B20中写出一个字节的数据WRITE: MOV R3,#8 ;循环8次,写一个字节WR1: SETB ;拉高数据线MOV R4, #8RRC A ;写入位从A中移到CYCLRWR2: DJNZ R4,WR2 ;等待16USMOV ,C ;命令字按位依次送给DS18B20MOV R4, #20WR3: DJNZ R4,WR3 ;保证写进程持续40USDJNZ R3,WR1 ;未写完一个字节转WR1继续SETB ;写完一个字节,数据线置高RET比较报警子程序CMP: MOV A,DISBUF0 ;实际测量温度值放在DISBUF8中SWAP AMOV DISBUF8, AMOV A, DISBUF1ORL A, DISBUF8MOV DISBUF8, AMOV A,DISBUF4 ;预置温度值放在DISBUF9中SWAP AMOV DISBUF9, AMOV A, DISBUF5ORL A, DISBUF9MOV DISBUF9, ACLR CMOV A, DISBUF8SUBB A, DISBUF9JNC KK ;没有借位,即实际温度值大于;预置温度值转KKCLR ;有借位,即实际温度值小于预置温度值;置0,不发报警信号RETKK: SETB ;置1,即发出报警标志发光二极管亮RET按键子程序KEY: JNB , YZBWJNB , YZSWLJMP KEYRET YZBW: LCALL DELAY1JB , KEYRETJNB , $INC DISBUF5MOV A, DISBUF4CJNE A, #10,KEYRETMOV DISBUF4, #0LJMP KEYRETYZSW: LCALL DELAY1JB , KEYRETJNB , $INC DISBUF5MOV A, DISBUF5CJNE A, #10,KEYRETMOV DISBUF5, #0 KEYRET: RET显示子程序DISPLAY: MOV A, DISBUF0MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00000001BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF1MOV DPTR, #SEGMOVC A, @A+DPTRORL A, #80HMOV P1, AMOV P2, #00000010BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF2MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00000100BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF3MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00001000BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF4MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00010000BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF5MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00100000BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF6MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00000000BLCALL DELAY1MOV P2, #00000000BMOV A, DISBUF7MOV DPTR, #SEGMOVC A, @A+DPTRMOV P1, AMOV P2, #00000000BLCALL DELAY1MOV P2, #00000000BRET; (00) (01) (02) (03) (04)SEG: DB 03FH, 06H, 05BH, 04FH, 066H ; (05) (06) (07) (08) (09)DB 06DH, 07DH, 007H, 07FH, 06FH ;延时子程序DELAY1: MOV R1, #0A0HDEL11: NOPDJNZ R1, DEL11RETEND;工作内存概念:DISBUF0 EQU 10H DISBUF1 EQU 11H DISBUF2 EQU DISBUF1+1 DISBUF3 EQU DISBUF2+1 DISBUF4 EQU DISBUF3+1 DISBUF5 EQU DISBUF4+1 DISBUF6 EQU DISBUF5+1 DISBUF7 EQU DISBUF6+1 DISBUF8 EQU DISBUF7+1 DISBUF9 EQU DISBUF8+1。
STC12C2052AD驱动DS18B20四位共阳极数码管显温程序
/***********************************************函数名:DS18B20温度读取程序编写人:寒江学钓时间:2021.7.8接口:调用:数码管显示函数,共阳极数码管参数:返回值:结果:备注:DS18B20温度探测/********************************************/#include<STC12C2052AD.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int#define X_PWM 9 //LED的亮度设置#define X_DELAY 12 //每点显示时长#define X_P1M0SET 0x00 //I\0口工作方式选择(从左到右,从高到低)#define X_P1M1SET 0x00sbit dq = P3 ^ 5;sbit X_LED_H1 = P3 ^ 0;sbit X_LED_H2 = P3 ^ 1;sbit X_LED_H3 = P3 ^ 2;sbit X_LED_H4 = P3 ^ 3;sbit X_LED_L1 = P1 ^ 0;sbit X_LED_L2 = P1 ^ 1;sbit X_LED_L3 = P1 ^ 2;sbit X_LED_L4 = P1 ^ 3;sbit X_LED_L5 = P1 ^ 4;sbit X_LED_L6 = P1 ^ 5;sbit X_LED_L7 = P1 ^ 6;sbit X_LED_L8 = P1 ^ 7;bit flag;//初始化标志bit negative;//负温度标志uint temp;uchar code disdata[] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, //无小数点数码管断码表0-9 0x40,0x09,0x72 //特殊标记符号};/******数码管函数***********************/void delay(uint a);//点扫描延时程序声明void dis_off(void);//关所有显示void displayHH1(uchar b); //横向显示程序void displayHH2(uchar b); //横向显示程序void displayHH3(uchar b); //横向显示程序void displayHH4(uchar b); //横向显示程序void displaydata(uchar L, uchar b); //数码管显示void display(uint T);//总显示程序void init(void); //上电初始/***************************************//*******DS18B20函数********************/void delay_1us();//1 us 延时@12.000MHzvoid delay_aus(uint a);//a us延时@12.000MHzvoid delay_a10us(uchar a);//a*10 us延时@12.000MHz void DS18B20_init(void);//初始化bit ds_read_bit(); //位读取uchar ds_read_byte(); //读字节void ds_write_byte(uchar dat); //写字节uint read_temperature(); //读温度void temperature_conversion();//温度转换先行/************************************************/int main(){uint L;temp = 0;flag = 0;init();while (1){temperature_conversion();//温度转换L = read_temperature();//读温度display(L);delay_aus(500);}}/*************延时区*************************/ void delay(uint a) //点扫描延时子程序{uchar i;while (--a != 0){for (i = 0; i < X_DELAY; i++);}}void Delay_1us()//@12.000MHz{_nop_();_nop_();}void delay_us(uint a){uint i, j;for (i = 0; i < a; i++){for (j = 0; j < 1; j++);}}void delay_10us(uint a){uint i, j;for (i = 0; i < a; i++){_nop_();for (j = 0; j < 19; j++){_nop_();}}}/**********************************************//*****************初始化**********************/void DS18B20_init(void){uint i;i = 0;dq = 1;delay_us(10);dq = 0;delay_10us(50);dq = 1;delay_us(16);for (i = 0; i < 1000; i++)//在反馈时间内判断DP=0时有响应{if (dq == 0){flag = 1;break;//跳出循环}elseflag = 0;}delay_10us(48);//凑延时}/*******************************************//*****************位读取********************/ bit ds_read_bit(){bit dat;dq = 0;delay_1us();dq = 1;delay_1us();delay_1us();dat = dq;delay_us(80);return dat;}/*******************************************//****************** 读字节******************/ uchar ds_read_byte() //数据传输地位在先{uchar i, j, k;for (i = 0; i < 8; i++){j = ds_read_bit();k = (j << 7) | (k >> 1);}return k;delay_us(2);}/****************************************//****************写字节******************/void ds_write_byte(uchar dat){uchar i;for (i = 0; i < 8; i++){dq = 0;delay_1us();dq = dat & 0x01;delay_us(60);dq = 1;dat = dat >> 1;}delay_us(60);}/*****************************************//***************读温度*******************/uint read_temperature(){uchar a, b,c;DS18B20_init();ds_write_byte(0xcc);//跳过ROMds_write_byte(0xbe);//读温度a = ds_read_byte();//读取温度低八位b = ds_read_byte();//读取温度高八位temp = b;temp = temp << 8;temp = temp | a;c = b & 0xf8;if (c==0xf8){negative = 1;//负温度标记temp = ~temp;//补吗取反temp += 1;//反码加1,获得负温度值temp = temp & 0xfff;}else{negative = 0;//正温度标记temp = temp & 0x7ff;//过滤负温度标识位temp = temp * 0.625 + 0.5;//取正温度到0.1显示精度}return temp;}/******************************************//***************温度转换先行***************/ void temperature_conversion(){DS18B20_init();ds_write_byte(0xcc);ds_write_byte(0x44);//温度转换}/*****************************************/ /******数码管函数************************/void dis_off(void)//数码管全关程序{P1 = ~X_P1M1SET;X_LED_H1 = 0;X_LED_H2 = 0;X_LED_H3 = 0;X_LED_H4 = 0;delay(10 - X_PWM);}void displayHH1(uchar b)//第一列横向显示程序{uchar i;i = b & 0x01;if (i == 0x01){X_LED_H1 = 1;X_LED_L1 = 0;}delay(X_PWM);dis_off();i = b & 0x02;if (i == 0x02){X_LED_H1 = 1;X_LED_L2 = 0; }delay(X_PWM); dis_off();i = b & 0x04;if (i == 0x04){X_LED_H1 = 1;X_LED_L3 = 0; }delay(X_PWM); dis_off();i = b & 0x08;if (i == 0x08){X_LED_H1 = 1;X_LED_L4 = 0; }delay(X_PWM); dis_off();i = b & 0x10;if (i == 0x10){X_LED_H1 = 1;X_LED_L5 = 0; }delay(X_PWM); dis_off();i = b & 0x20;if (i == 0x20){X_LED_H1 = 1;X_LED_L6 = 0; }delay(X_PWM); dis_off();i = b & 0x40;if (i == 0x40){X_LED_H1 = 1;X_LED_L7 = 0;}delay(X_PWM);dis_off();i = b & 0x80;if (i == 0x80){X_LED_H1 = 1;X_LED_L8 = 0;}delay(X_PWM);dis_off();}void displayHH2(uchar b)//第二列横向显示程序{uchar i;i = b & 0x01;if (i == 0x01){X_LED_H2 = 1;X_LED_L1 = 0;}delay(X_PWM);dis_off();i = b & 0x02;if (i == 0x02){X_LED_H2 = 1;X_LED_L2 = 0;}delay(X_PWM);dis_off();i = b & 0x04;if (i == 0x04){X_LED_H2 = 1;X_LED_L3 = 0;}delay(X_PWM); dis_off();i = b & 0x08;if (i == 0x08){X_LED_H2 = 1;X_LED_L4 = 0; }delay(X_PWM); dis_off();i = b & 0x10;if (i == 0x10){X_LED_H2 = 1;X_LED_L5 = 0; }delay(X_PWM); dis_off();i = b & 0x20;if (i == 0x20){X_LED_H2 = 1;X_LED_L6 = 0; }delay(X_PWM); dis_off();i = b & 0x40;if (i == 0x40){X_LED_H2 = 1;X_LED_L7 = 0; }delay(X_PWM); dis_off();i = b & 0x80;if (i == 0x80){X_LED_H2 = 1;X_LED_L8 = 0;}delay(X_PWM);dis_off();}void displayHH3(uchar b)//第三列横向显示程序{uchar i;i = b & 0x01;if (i == 0x01){X_LED_H3 = 1;X_LED_L1 = 0;}delay(X_PWM);dis_off();i = b & 0x02;if (i == 0x02){X_LED_H3 = 1;X_LED_L2 = 0;}delay(X_PWM);dis_off();i = b & 0x04;if (i == 0x04){X_LED_H3 = 1;X_LED_L3 = 0;}delay(X_PWM);dis_off();i = b & 0x08;if (i == 0x08){X_LED_H3 = 1;X_LED_L4 = 0;}delay(X_PWM);dis_off();i = b & 0x10;if (i == 0x10){X_LED_H3 = 1;X_LED_L5 = 0;}delay(X_PWM);dis_off();i = b & 0x20;if (i == 0x20){X_LED_H3 = 1;X_LED_L6 = 0;}delay(X_PWM);dis_off();i = b & 0x40;if (i == 0x40){X_LED_H3 = 1;X_LED_L7 = 0;}delay(X_PWM);dis_off();i = b & 0x80;if (i == 0x80){X_LED_H3 = 1;X_LED_L8 = 0;}delay(X_PWM);dis_off();}void displayHH4(uchar b)//第四列横向显示程序{uchar i;i = b & 0x01;if (i == 0x01){X_LED_H4 = 1;}delay(X_PWM); dis_off();i = b & 0x02;if (i == 0x02){X_LED_H4 = 1;X_LED_L2 = 0; }delay(X_PWM); dis_off();i = b & 0x04;if (i == 0x04){X_LED_H4 = 1;X_LED_L3 = 0; }delay(X_PWM); dis_off();i = b & 0x08;if (i == 0x08){X_LED_H4 = 1;X_LED_L4 = 0; }delay(X_PWM); dis_off();i = b & 0x10;if (i == 0x10){X_LED_H4 = 1;X_LED_L5 = 0; }delay(X_PWM); dis_off();i = b & 0x20;if (i == 0x20){X_LED_L6 = 0;}delay(X_PWM);dis_off();i = b & 0x40;if (i == 0x40){X_LED_H4 = 1;X_LED_L7 = 0;}delay(X_PWM);dis_off();i = b & 0x80;if (i == 0x80){X_LED_H4 = 1;X_LED_L8 = 0;}delay(X_PWM);dis_off();}void displaydata(uchar L, uchar b)//显示程序{switch (L)//显示的列位置{case 1:displayHH1(b);//将显示数据送入break;case 2:displayHH2(b);break;case 3:displayHH3(b);break;case 4:displayHH4(b);break;}}void init(void)//初始化{P1M0 = X_P1M0SET;//P1M0:P1M1=0:0准双向一般输出P1M1 = X_P1M1SET;P3M0 = 0x00;//P3M0:P3M1=0:1 强推挽输出电流可达20mAP3M1 = 0x0f;dis_off();}void display(uint T){if (flag ==1){if (negative == 1){displaydata(1, disdata[T / 100]);displaydata(2, disdata[T % 100 / 10] + 0x80);//+0x80是为了点亮“:”号,作为小数点用displaydata(3, disdata[T % 100 % 10]);displaydata(4, disdata[10]);//特殊符号显示位‘-’代表负温度}else{displaydata(1, disdata[T / 100]);displaydata(2, disdata[T % 100 / 10] + 0x80);//+0x80是为了点亮“:”号,作为小数点用displaydata(3, disdata[T % 100 % 10]);displaydata(4, disdata[11]);//特殊符号显示位‘二’代表正温度}}elsedisplaydata(4, disdata[12]);//特殊符号显示位‘r’代表初始化失败}。
DS18B20温度传感器测温通过数码管显示(上传)
DS18B20温度传感器测温通过数码管显示(详尽版)/*-----------------------------------------------名称:DS18B20温度传感器数码管显示编写:JR日期:2017.12修改:无内容:利用DS18B20温度传感器测量温度-40~+100℃,通过数码管显示单片机开发板使用“金容电子(https:///item.htm?id=544540401703)”开发的JR51单片机开发板。
------------------------------------------------*/#include<reg52.h>#include<stdio.h>#include<intrins.h>#include"delayus.h"#define uchar unsigned char#define uint unsigned intsbit DQ=P2^2; //温度传感器信号线sbit dula=P2^6; //数码管段选线sbit wela=P2^7; //数码管位选线sbit beep=P2^3; //数码管位选线uint temper;uchar a1,a2,a3,a4,a5,n;uint aaa,num;uint warn_l=3000; //低温-40℃报警,测试温度乘以100uint warn_h=10000; //高温100℃报警,测试温度乘以100float ttt;void disp(uchar num0,uchar num1,uchar num2,uchar num3,uchar num4,uchar num5);const uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00};//不带小数点0-9编码const uchar table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //带小数点0-9编码uchar data temp_data[2]={0x00,0x00}; //读出温度暂放void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}/*******************************************************************18B20复位初始化函数1、将数据线拉高到12、延时2us(该时间要求不是很严格,但是要尽可能短一点)3、将数据线拉低到04、延时750us(该时间范围可以在480~960us)5、将数据线拉高到16、延时等待(70us),如果初始化成功则在15~60us内产生一个由18B20返回的低电平0,据该状态可以确定它的存在。
DS18B20温度传感器和数码管显示例程
//DS18B20温度传感器和数码管显示//编程时间:连线表: CPU=stc89C52 SysClock=12MHz// LEDLE= 控制位高电平有效 LEDSEG=P2 KEYBOARD=P3 LEDWEI=,LED高到底//**********************************************************//DS18B20//**********************************************************//连线表: CPU=stc89C52 SysClock=12MHz *//单总线: TMDAT=////**********************************************************#include <>#define uchar unsigned char#define uint unsigned intuchar discount=0;//显示扫描位计数uchar last=0;//最终温度值uchar itcount=0x13;//定时器延时计数uchar seg[4];//数码管显示暂存uchar tem[2];//读取温度暂存uchar flag=0;//温度正负标志位/********************LED引脚定义********************/sfr LEDSEG=0x80;//P2sfr LEDWEI=0xA0;//P3/********************DS18B20引脚定义********************/sbit TMDAT=P1^0; //温度传感器数据位/********************DS18B20函数定义*******************/void dmsec(uint count);//延时(count)毫秒void tmreset(void); //产生复位信号void tmpre(void); //检测器件应答信号bit tmrbit(void); //从总线读一个bituchar tmrbyte(void); //从总线读一个字节void mwbyte(uchar dat);//向总线写一个字节void tmstart(void); //启动一次温度转换uchar tmrtemp(void); //读取温度数据/********************LED函数定义*******************/uchar * uchartodectoseg(uchar unm);//字符转换为十进制然后转换为数码管段表void disp(uchar *seg);//显示函数void delay_ms(uint t); //延时函数/************************************************/uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0xc6};/*************数码表*******0 1 2 3 4 5 6 7 8 9 无显示 C**************/ /************************************************/uchar * uchartodectoseg(uchar unm){uchar x00,xx,x0,x,n;x00=unm/100;//取百位xx=unm%100;//取余x0=xx/10;//取十位x=xx%10;//取余即取个位n=0;seg[n]=table[x00];n++;seg[n]=table[x0];n++;seg[n]=table[x];n++;seg[n]=table[11];//最后一位显示摄氏度符号Cif(flag==1)seg[0]=0x40;//显示负号‘-’if(seg[0]==table[0])seg[0]=table[10]; //如果百位为零则不显示if((seg[0]==table[0])&(seg[1]==table[0]))seg[1]=table[10];//如果百位为零且十位为零则十位不显示return seg;}/***************************************************/ /******DELAY***************************/void delay_ms(uint t){uint m,n;for(m=0;m<t;m++){for(n=0;n<950;n++);}}/******************************************//*********************显示LEDSEG*****************************/void disp(uchar *seg){uchar wei[]={0x08,0x04,0x02,0x01};//位扫描码//LEDSEG=seg[10];LEDWEI =wei[discount];LEDSEG = seg[discount];delay_ms(1);discount++;if(discount==4){ delay_ms(1);discount=0;//LEDSEG=seg[10];LEDWEI=wei[discount];LEDSEG=seg[discount];}//检测是否扫描完,扫描完的话则重新置初值}/*********************************************************//*****************DS18B20函数体定义****************/void dmsec(uint count) {uint i;while(count--){for(i=0;i<125;i++){} }}void tmreset(void){uint i;TMDAT=0;i=103;while(i>0) i--;TMDAT=1;i=4;while(i>0) i--;}void tmpre(void){uint i;while(TMDAT);while(~TMDAT);i=4;while(i>0) i--;}bit tmrbit(void){uint i;bit dat;TMDAT=0;i++;TMDAT=1;i++;i++;dat=TMDAT;i=8;while(i>0) i--;return(dat);}uchar tmrbyte(void){uchar i,j,dat;dat=0;for(i=1;i<=8;i++){ j=tmrbit();dat=(j<<7)|(dat>>1); }return(dat);}void tmwbyte(uchar dat) {uint i;uchar j;bit testb;for(j=1;j<=8;j++){ testb=dat & 0x01; dat=dat>>1;if(testb){ TMDAT=0;i++; i++;TMDAT=1;i=8;while(i>0) i--; }else{ TMDAT=0;i=8;while(i>0) i--; TMDAT=1;i++; i++;}}}void tmstart(void){tmreset();tmpre();dmsec(1);tmwbyte(0xcc);tmwbyte(0x44);}uchar tmrtemp(void){uchar y1,y2,y3;tmreset();tmpre();dmsec(1);tmwbyte(0xcc);tmwbyte(0xbe);tem[0]=tmrbyte();tem[1]=tmrbyte();if(tem[1]>127){tem[1]=(255-tem[1]);tem[0]=(255-tem[0]);flag=1;} //负温度求补码y1=tem[0]>>4;y2=tem[1]<<4;y3=y1|y2;return(y3);}/*********************************************************/void main(){TMOD=0X01;TL0=0XB0;TH0=0X3C;EA=1;ET0=1;TR0=1;dmsec(1);tmstart();while(1){uchartodectoseg(last);disp(seg);}}void time0() interrupt 1{TL0=0XB0;TH0=0X3C;//定时50msitcount--;if(itcount==0){last=tmrtemp();dmsec(1);tmstart();itcount=0x13;}}。
数字温度传感器DS18B20(含程序)
数字温度传感器DS18B20摘要DS-18B20 数字温度传感器具有耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。
应用范围广泛,适用于冷冻库,粮仓,储罐,电讯机房,电力机房,电缆线槽等测温和控制领域,轴瓦,缸体,纺机,空调,等狭小空间工业设备测温和控制和汽车空调、冰箱、冷柜、以及中低温干燥箱等。
一、引脚图DS18B20引脚定义:(1)DQ为数字信号输入/输出端;(2)GND为电源地;(3)VDD为外接供电电源输入端(在寄生电源接线方式时接地)二、DS18B20的主要特性1.1、电压范围:3.0~5.5V,在寄生电源方式下可由数据线供电1.2、DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯1.3、多个DS18B20可以并联在唯一的三线上,实现组网多点测温1.4、DS18B20在使用中不需要任何外围元件1.5、温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃1.6、可编程的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃,可实现高精度测温1.7、在9位分辨率时最多在93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字,速度更快1.8、测量结果直接输出数字温度信号,以"一线总线"串行传送给CPU,同时可传送CRC校验码,具有极强的抗干扰纠错能力1.9、负压特性:电源极性接反时,芯片不会因发热而烧毁,但不能正常工作。
三、DS18B20的外形和内部结构DS18B20内部结构主要由四部分组成:64位光刻ROM 、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。
DS18B20内部结构图四、DS18B20工作原理DS18B20的温度转换时的延时时间由2s 减为750ms。
DS18B20测温原理如图3所示。
DS18B20温度测试程序(51单片机数码管显示)+电路图
DS18B20温度测试程序(51单片机数码管显示)+电路图•下面是电路图采用4位数码管显示程序一共有2个文件:/****************************************************************************** *****************************************ds18b20.h 头文件******************************************************************************* ****************************************/#ifndef _DS18B20_H_#define _DS18B20_H_#include <reg51.h>#define led P1#define ledw P2extern unsigned char f;extern void ds18b20_reset();extern void dela(unsigned char i);extern void ds18b20_write(unsigned char dat);extern unsigned char ds18b20_read();extern unsigned char ds18b20_temp();extern unsigned char ledtab[];#endif/****************************************************************************** **************************************ds18b20.c 文件******************************************************************************* *************************************/#include"ds18b20.h"#define uchar unsigned char#define uint unsigned int#define led P1#define ledw P2uchar ledtab[]={0xc0,0xf9,0xa4, 0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};sbit dq=P3^7 ;uchar delay,f;//uchar f;void dela(uchar i) //5us t=5+i*2{while(--i);}void ds18b20_reset(){while(1){dq=1;dq=0;delay=250; //540us延时,当delay=1时延时为2us ,T=2*xwhile(--delay);dq=1;delay=25;while(--delay);while(dq==0){delay=220;while(--delay);if(dq==1)break;}delay=150;while(--delay);break;}}void ds18b20_write(uchar dat) {uchar i=0;for(i=0;i<8;i++){dq=1;dq=0;delay=3;while(--delay);dq=dat&0x01;delay=35;while(--delay);dq=1;dat=dat>>1;}}uchar ds18b20_read(){uchar i=0,m=0;for(i=0;i<8;i++){//m>>=1dq=1;dq=0;delay=4;while(--delay);dq=1;delay=4;while(--delay);if(dq==1)m|=0x01<<i;//m=m|0x80;delay=25;while(--delay);dq=1;delay=1;while(--delay);}return m;}uchar ds18b20_temp(){uchar temp=0,temph=0,templ=0,k=0; ds18b20_reset();ds18b20_write(0xcc);ds18b20_write(0x44);ds18b20_reset();ds18b20_write(0xcc);ds18b20_write(0xbe);templ=ds18b20_read();temph=ds18b20_read();if((temph&0xf80)!=0){f=1;templ=~templ;temph=~temph;k=templ+1;templ=k;if(templ>0xff){temph++;}}elsef=0;templ=templ>>4;temph=temph<<4;temp=templ|temph;return temp;}/****************************************************************************** ************************************main.c 主文件******************************************************************************* ************************************/#include<reg51.h>#include"ds18b20.h"#define uchar unsigned charvoid main(){uchar a=0,b=0,c=0,temp=0;while(1){temp=ds18b20_temp();a=temp/100;b=temp0/10;c=temp;if(f==1){led=0xbf;ledw=1;dela(5000);ledw=0;dela(600);}led=ledtab[c]; ledw=8;dela(5000); ledw=0;dela(600) ;led=ledtab[b]; ledw=4;dela(5000); ledw=0;dela(600) ;led=ledtab[a]; ledw=2;dela(5000);ledw=0;dela(600) ; }}。
DS18B20--MSP430--4位数码管显示温度
DS18B20 MSP430 4位数码管显示温度//实验材料:MSP430F149开发板,DS18B20一个,杜邦线15条,3元普通4位共阴极数码管一个//由于本人没有排阻,没有采用灌电流方式给4位共阴极数码管供电,MSP430的I/O口直接接4位共阴极数码管的12个脚//接线说明:DS18B20数据口接P17,电源接3.3V直流;P40~P47接数码管a、b、c、d、e、f、g、dp // P50~P53接位1、位2、位3,位4,数码管接线图请百度//Made By Zhong Sir From Wuhan University#include <msp430x14x.h>//延时函数#define CPU_F ((double)8000000) //外部高频晶振8MHZ//#define CPU_F ((double)32768) //外部低频晶振32.768KHZ#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))//自定义数据结构#define uchar unsigned char#define uint unsigned int#define ulong unsigned long//DS18B20控制脚,单脚控制#define DQ_IN P1DIR &= ~BIT7 // DS18B20接单片机P17口#define DQ_OUT P1DIR |= BIT7 //设置输出#define DQ_CLR P1OUT &= ~BIT7 //置低电平#define DQ_SET P1OUT |= BIT7 //置高电平#define DQ_R P1IN & BIT7 //读电平int temp_value;int temp; //定义的变量,显示数据处理int A1,A2,A3;//***********************************************************************// 系统时钟初始化,外部8M晶振//***********************************************************************void Clock_Init(){uchar i;BCSCTL1&=~XT2OFF; //打开XT2振荡器BCSCTL2|=SELM1+SELS; //MCLK为8MHZ,SMCLK为8MHZdo{IFG1&=~OFIFG; //清楚振荡器错误标志for(i=0;i<100;i++)_NOP();}while((IFG1&OFIFG)!=0); //如果标志位1,则继续循环等待IFG1&=~OFIFG;}//***********************************************************************// MSP430内部看门狗初始化void WDT_Init(){WDTCTL = WDTPW + WDTHOLD; //关闭看门狗}//************************************************************************* // 初始化IO口子程序//************************************************************************* void Port_Init(){P5DIR = 0xFF; //设置IO口方向为输出P4DIR = 0xFF; //P2口初始设置为FF}//************************************************************************* // DS18B20初始化//************************************************************************* unsigned char DS18B20_Reset(void) //初始化和复位{unsigned char i;DQ_OUT;DQ_CLR;delay_us(500); //延时500uS(480-960)DQ_SET;delay_us(80); //延时80uSi = DQ_R;delay_us(500); //延时500uS(保持>480uS)if (i){return 0x00;}else{return 0x01;}}//************************************************************************* // DS18B20读一个字节函数//************************************************************************* unsigned char ds1820_read_byte(void){unsigned char i;unsigned char value = 0;for (i = 8; i != 0; i--){DQ_OUT;DQ_CLR;delay_us(4); //*延时4uSDQ_SET;DQ_IN;delay_us(10); //*延时10uSif (DQ_R){value|=0x80;}delay_us(60); //*延时60uS}return(value);}//************************************************************************* // 向18B20写一个字节函数//************************************************************************* /*DS18B20字节写入函数*/void ds1820_write_byte(unsigned char value){unsigned char i;for (i = 8; i != 0; i--){DQ_OUT;DQ_CLR;delay_us(4); //延时4uSif (value & 0x01){DQ_SET;}delay_us(80); //延时80uSDQ_SET; //位结束value >>= 1;}}//************************************************************************* // 发送温度转换命令//************************************************************************* /*启动ds1820转换*/void ds1820_start(void){DS18B20_Reset();ds1820_write_byte(0xCC); //勿略地址ds1820_write_byte(0x44); //启动转换// DS8B20读取温度信息//************************************************************************* unsigned int ds1820_read_temp(void){unsigned int i;unsigned char buf[9];DS18B20_Reset();ds1820_write_byte(0xCC); //勿略地址ds1820_write_byte(0xBE); //读取温度for (i = 0; i < 9; i++){buf[i] = ds1820_read_byte();}i = buf[1];i <<= 8;i |= buf[0];temp_value=i;temp_value=(uint)(temp_value*0.625);//不是乘以0.0625的原因是为了把小数点后一位数据也转化为可以显示的数据return i;// 温度数据处理函数//*************************************************************************void data_do(int temp_d){int A2t;A1=temp_d/100; //分出百,十,和个位A2t=temp_d%100;A2=A2t/10;A3=A2t%10;}//***********************************************************************// 主程序//***********************************************************************void main(void){const unsigned char seg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; const unsigned char zww[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09}; uchar j;WDT_Init(); //看门狗初始化Clock_Init(); //时钟初始化Port_Init(); //端口初始化,用于控制IO口输入或输出DS18B20_Reset(); //复位D18B20while(1){ds1820_start(); //启动一次转换ds1820_read_temp(); //读取温度数值data_do(temp_value); //处理数据,得到要显示的值if(A1==zww[0]) A1=seg[0]; // 以下将DS18B20反馈的数值换成数码管的字符编码以显示else if(A1==zww[1]) A1=seg[1];else if(A1==zww[2]) A1=seg[2];else if(A1==zww[3]) A1=seg[3];else if(A1==zww[4]) A1=seg[4];else if(A1==zww[5]) A1=seg[5];else if(A1==zww[6]) A1=seg[6];else if(A1==zww[7]) A1=seg[7];else if(A1==zww[8]) A1=seg[8];else if(A1==zww[9]) A1=seg[9];else A1=A1;if(A2==zww[0]) A2=seg[0];else if(A2==zww[1]) A2=seg[1];else if(A2==zww[2]) A2=seg[2];else if(A2==zww[3]) A2=seg[3];else if(A2==zww[4]) A2=seg[4];else if(A2==zww[5]) A2=seg[5];. else if(A2==zww[6]) A2=seg[6];else if(A2==zww[7]) A2=seg[7];else if(A2==zww[8]) A2=seg[8];else if(A2==zww[9]) A2=seg[9];else A2=A2;if(A3==zww[0]) A3=seg[0];else if(A3==zww[1]) A3=seg[1];else if(A3==zww[2]) A3=seg[2];else if(A3==zww[3]) A3=seg[3];else if(A3==zww[4]) A3=seg[4];else if(A3==zww[5]) A3=seg[5];else if(A3==zww[6]) A3=seg[6];else if(A3==zww[7]) A3=seg[7];else if(A3==zww[8]) A3=seg[8];else if(A3==zww[9]) A3=seg[9];else A3=A3;for(j=0;j<8;j++){P4OUT=A1;P5OUT=0X0E;delay_ms(0.4);P4OUT=A2+BIT7;P5OUT=0x0D;.delay_ms(0.4);P4OUT=A3;P5OUT=0x0B;delay_ms(0.4);P4OUT=0x58;P5OUT=0x07;delay_ms(0.4);P4OUT=0x00; //缺少该句,数码管会有微弱重影,有该句无重影}}}可编辑。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include "intrins.h" //_nop_();延时函数用
#define Disdata P0 //段码输出口
#define discan P2 //扫描口
write_byte(0xBE); // 发读命令
temp_data[0]=read_byte(); //温度低8位
temp_data[1]=read_byte(); //温度高8位
ow_reset();
write_byte(0xCC); // Skip ROM
write_byte(0x44); // 发转换命令
val=val/2; //右移一位
}
DQ = 1;
delay(1);
}
//
/*********18B20读1个字节函数********/
//从总线上读取一个字节
uchar read_byte(void)
{
uchar i;
uchar value = 0;
for (i=8;i>0;i--)
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P3^3; //温度输入口
sbit DIN=P0^7; //LED小数点控制
{
Disdata=0xff;
Disdata=dis_7[display[k]];
if(k==1){DIN=0;}
discan=scan_con[k];delay(90);
discan=0xff;
}
}
// Βιβλιοθήκη // /***********18B20复位函数**********/
discan=0xff;
for(h=0;h<4;h++){display[h]=8;}//开机显示8888
ow_reset(); // 开机先转换一次
write_byte(0xCC); // Skip ROM
write_byte(0x44); // 发转换命令
for(h=0;h<500;h++)
{scan();} //开机显示"8888"2秒
while(1)
{
read_temp(); //读出18B20温度数据
work_temp(); //处理温度数据
scan(); //显示温度值2秒
}
}
//
//*********************结束**************************//
display[2]=display[4]/10%10;
display[1]=display[4]%10;
if(!display[3])
{
display[3]=0x0a;
flag3=0;
if(!display[2])
{
display[2]=0x0a;
uchar code scan_con[4]={0xbf,0x7f,0xef,0xfe}; //列扫描控制字
uchar data temp_data[2]={0x00,0x00}; //读出温度暂放
uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //显示单元数据,共4个数据和一个运算暂用
ow_reset(void)
{
char presence=1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_();
DQ=0; //
delay(50); // 550us
DQ=1; //
delay(6); // 66us
uint h;
uchar flag;
//**************温度小数部分用查表法***********//
uchar code ditab[16]=
{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ = 0; //
_nop_();_nop_();_nop_();_nop_(); //4us
DQ = 1;_nop_();_nop_();_nop_();_nop_(); //4us
if(DQ)value|=0x80;
display[0]=ditab[display[4]];
doth=display[0]/10;
dotl=display[0]%10;
display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x07)<<4);
display[3]=display[4]/100;
flag2=0;
}
}//最高位为0时都不显示
if(n)
{
display[3]=0x0b;//负温度时最高位显示"-"
flag3=0;
}
}
//
//
/**************主函数****************/
main()
{
Disdata=0xff; //初始化端口
delay(6); //66us
}
DQ=1;
return(value);
}
//
/***********读出温度函数**********/
//
read_temp()
{
ow_reset(); //总线复位
write_byte(0xCC); // 发Skip ROM命令
presence=DQ; // presence=0继续下一步
}
delay(45); //延时500us
presence = ~DQ;
}
DQ=1;
}
//
//
/**********18B20写命令函数*********/
//向 1-WIRE 总线上写一个字节
void write_byte(uchar val)
//
uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
//共阳LED段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"
{
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); //66us
{
temp_data[1]=~(temp_data[1]);
temp_data[0]=~(temp_data[0])+1;
n=1;
flag=1;
}//负温度求补码
if(temp_data[0]>255)
{
temp_data[1]++;
}
display[4]=temp_data[0]&0x0f;
}
//
/***********温度数据处理函数**********/
void work_temp()
{
uchar n=0;
uchar doth,dotl;
uchar flag3=1,flag2=1; //数字显示修正标记
if((temp_data[1]&0xf8)!=0x00)
//
//
//
/***********11微秒延时函数**********/
//
void delay(uint t)
{
for(;t>0;t--);
}
//
/***********显示扫描函数**********/
scan()
{
char k;
for(k=0;k<4;k++) //四位LED扫描控制